Milacay
Milacay

Reputation: 1497

Jquery - Edit Table Row Directly

I am a novice with Jquery, so please don't be so hard on me. What I try do is edit the row data directly from the table cell. This is a working process in which I am stuck and needed help.

Imagine that I have a tableID "tabledata", I want to click on a cell (col/row) and that cell value will change to a textbox (editable). After the user edit the value, it will save using Ajax. If user decides that not change the value while in editing mode, user can click somewhere out on the screen to abort, which the cell value go back to original value (no textbox anymore).

I am still working on pieces, but the problem I am facing right now is that, when user click on the cell, it changes to editable mode (textbox), and then user clicks on the textbox to edit, the textbox goes away because of the "mouseup function" putting back the original value.

How can I prevent this? Any better way to do this with examples would be really appreciated.

Here is my Jquery codes:

$(function() {

    var array = []
    array[0] = '';  // Current Row
    array[1] = '';  // Current Col

    var oldValue
    var updateID; // Updating ID

     $("#tabledata td").click(function(e) {   
        // I NEED TO FIND THE CLOSEST TD 
        var column_num = parseInt( $(this).index() ) ;
        var row_num = parseInt( $(this).parent().index() ); 
        //alert("updateID: " + updateID + " |\n Row_num = " + row_num + "  |\n Column_num = " + column_num + ' |\n NewValue: ' + oldValue);         

        oldValue = ($(this).html());
        updateID = $("#tabledata tr:eq(" + row_num + ") td:eq(0)").text();

        $("#tabledata tr:eq(" + row_num + ") td:eq(" + column_num + ")").html("<input type='text' name='cstage' value='Test123'>");
        array[0] = row_num;
        array[1] = column_num;
        //getCellPosition()

        e.preventDefault(); // <-- consume event
        e.stopImmediatePropagation();
        return false;

    });

    putOldValueBack = function()
    {
        //alert("Change back value for " + array[1] + ' - ' + array[2] + " - " + oldValue); 
        $("#tabledata tr:eq(" + array[0] + ") td:eq(" + array[1] + ")").html(oldValue); 
    }

});


$(document).click(function (e)
{
    putOldValueBack()

});

HTML codes for the table:

<table id="tabledata">
    <tr>
        <th>RecID</th>
        <th>Col1</th>
        <th>Col2</th>
    </tr>
    <tr>
        <td>RecID</td>
        <td>Val1.1</td>
        <td>Val1.2
    </tr>
    <tr>
        <td>RecID</td>
        <td>Val2.1</td>
        <td>Val2.2
    </tr>
    <tr>
        <td>RecID</td>
        <td>Val3.1</td>
        <td>Val3.2
    </tr>
</table>

Upvotes: 1

Views: 24657

Answers (1)

MightyPork
MightyPork

Reputation: 18861

I suspect this could solve it, but can't really say for sure. You must consume the event (and preferably dont use mouseup, but just click - it should work well.

Note that I removed the unchanged bits of code.

$("#tabledata td").click(function(e) { // <-- event as argument

    // some stuff

    e.preventDefault(); // <-- consume event
    e.stopImmediatePropagation();
    return false;
});

$(document).click(function (e) { // <-- now using click
    putOldValueBack()
});

Here's a simple cell editor impl: http://jsfiddle.net/9KEGd/

$(function () {
    $("#tabledata td").click(function (e) {
        e.preventDefault(); // <-- consume event
        e.stopImmediatePropagation();

        $this = $(this);

        if ($this.data('editing')) return;  

        var val = $this.text();

        $this.empty()
        $this.data('editing', true);        

        $('<input type="text" class="editfield">').val(val).appendTo($this);
    });

    putOldValueBack = function () {
        $("#tabledata .editfield").each(function(){
            $this = $(this);
            var val = $this.val();
            var $td = $this.closest('td');
            $td.empty().html(val);
            $td.data('editing', false);

        });
    }

    $(document).click(function (e) {
        putOldValueBack();
    });
});

Here's an editor with cancelling (hit enter to save, Esc to cancel, CLick outside to cancel)

http://jsfiddle.net/9KEGd/2/

$(function () {

    function revert() {
        $("#tabledata .editfield").each(function () {
            var $td = $(this).closest('td');
            $td.empty();
            $td.text($td.data('oldText'));
            $td.data('editing', false);

            // canceled            
            console.log('Edit canceled.');
        });
    }

    function save($input) {
        var val = $input.val();
        var $td = $input.closest('td');
        $td.empty();
        $td.text(val);
        $td.data('editing', false);

        // send json or whatever
        console.log('Value changed');
    }


    $('#tabledata td').on('keyup', 'input.editfield', function (e) {
        if (e.which == 13) {
            // save
            $input = $(e.target);
            save($input);
        } else if (e.which == 27) {
            // revert
            revert();
        }
    });

    $("#tabledata td").click(function (e) {

        // consuem event
        e.preventDefault();
        e.stopImmediatePropagation();

        $td = $(this);

        // if already editing, do nothing.
        if ($td.data('editing')) return;
        // mark as editing
        $td.data('editing', true);

        // get old text
        var txt = $td.text();

        // store old text
        $td.data('oldText', txt);

        // make input
        var $input = $('<input type="text" class="editfield">');
        $input.val(txt);

        // clean td and add the input
        $td.empty();
        $td.append($input);
    });


    $(document).click(function (e) {
        revert();
    });
});

Upvotes: 6

Related Questions