Changing td to textbox when clicked and changing textbox back to td when user is done

Dr. Banana picture Dr. Banana · Jul 26, 2015 · Viewed 15k times · Source

I'm looking for a way the user can change a td from table by clicking on it. My current setup is when a user clicks on a td, it should replace the clicked td by a textbox which contains the text from the clicked td. Then when the user clicks outside of it, or presses enter. It should change the textbox back to td.

This is the Table I have:

<table class="table" id="tableCompleted">
    <thead>
        <tr>
            <th>Name</th>
            <th>A</th>
            <th>B</th>
            <th>C</th>
            <th>D</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>John</td>
            <td>Yes</td>
            <td>Yes</td>
            <td>No</td>
            <td>No</td>
        </tr>
        <tr>
            <td>Jesse</td>
            <td>Yes</td>
            <td>Yes</td>
            <td>Yes</td>
            <td>Yes</td>
        </tr>
        <tr>
            <td>David</td>
            <td>No</td>
            <td>Yes</td>
            <td>No</td>
            <td>No</td>
        </tr>
    </tbody>
</table>

This is the script I have written, the problem I have is that, when a users clicks on a td it replaces all the td's and I havent figured out how to change it back when it loses focus. I tried using a button but that made it even worse. Also the text from the td doesn't get placed inside the textbox.

The script I used for it:

$('td').click(function () {
    $('td').replaceWith(function () {
        return '<input type="text" id="modify" "value="' + $('#Text').val() + '" />';
    });
})

I Currently have 3 problems with it, Im not sure how to only change the td that is clicked, because all the td don't have a unique id or class. And I'm not sure how to change it back when the user is done changing it. Also It doesn't place the content of the td inside the textbox.

Answer

undefined picture undefined · Jul 27, 2015

For referring to the clicked element you can use the this keyword:

$('td').on('click', function() {
    $(this)...
});

Also you shouldn't replace the td with an input, because a trelement can't have an input child. Instead of it remove the textContent of the td and append an input to it. Here is one way of implementing this:

$('td').on('click', function() {
    var $this = $(this);
    var $input = $('<input>', {
        value: $this.text(),
        type: 'text',
        blur: function() {
           $this.text(this.value);
        },
        keyup: function(e) {
           if (e.which === 13) $input.blur();
        }
    }).appendTo( $this.empty() ).focus();
});

Here is a demo using the above snippet.

You have also a more sensible option: contentEditable property.

$('td').prop('contentEditable', true);

Using the above property browser handles the editing. You can either manually add a contentEditable to the target cells in your markup or use JavaScript for modifying the attribute.