1

I have a table in my page as below;

<table id="tbl" cellpadding="0" cellspacing="0" style="width: 100%">
  <tr>
    <td class="field1s">field1x</td>
    <td class="field2s">field2x</td>
    <td class="field3s">field3x</td>
    <td class="field4s">field4x</td>
    <td class="xx">#</td>
  </tr>
</table>

The table contains so many rows. When I click last cell (xx), I want all other texts in the row change to <input type="text" /> having corresponding classes respectively, with their corresponding texts inside. And when user again click xx, the row may be updated with changed text.

I caught data and made some work already.

Here is the fiddle

2
  • Why a diffferent classname per cell? better have different IDs and the same class Commented Jun 2, 2012 at 13:25
  • OMG... I wonder Y -1 for my question!!! Commented Jun 2, 2012 at 16:10

5 Answers 5

5

I'd suggest the following:

$('#tbl').on('click','.xx',function() {
    $(this).siblings().each(
        function(){
            // if the td elements contain any input tag
            if ($(this).find('input').length){
                // sets the text content of the tag equal to the value of the input
                $(this).text($(this).find('input').val());
            }
            else {
                // removes the text, appends an input and sets the value to the text-value
                var t = $(this).text();
                $(this).html($('<input />',{'value' : t}).val(t));
            }
        });
});

JS Fiddle demo.


Edited in response to comments from @mplungjan (below):

.text(something) must surely be faster and simpler to read than .text("").append(something) in any case. And you are not adding text but html so even more reason to use just html().

He's right, of course. Therefore:

$('#tbl').on('click','.xx',function() {
    $(this).siblings().each(
        function(){
            if ($(this).find('input').length){
                $(this).text($(this).find('input').val());
            }
            else {
                var t = $(this).text();
                $(this).html($('<input />',{'value' : t}).val(t));
            }
        });
});

JS Fiddle demo.

References:

Sign up to request clarification or add additional context in comments.

11 Comments

simple. if i want to do an ajax request, if any of the text is changed, where should i do that?
Why not $(this).html( $('<input />',{'value' : t}));
Thank you kindly! @mplungjan, answer edited per your suggestions. Thanks. =)
Absolutely no need for the .val() at all. It is setting the value twice. DEMO
yea it is @mplungjan +1 for comment
|
1

Here's working jsfiddle with comments explaining stuff:

http://jsfiddle.net/767y4/6/

$('#tbl').on('click','.xx',function() {
    // active, means we were in input mode - revert input to td
    if ($(this).hasClass('active')) {
        // go through each input in the table
        $('#tbl input').each(function() {
           // get input text
           var colData = $(this).val();
           // get input class
           var colClass = $(this).attr('class');
           // create td element
           var col = $('<td></td>');
           // fill it with data
           col.addClass(colClass).text(colData);
           // now. replace
           $(this).replaceWith(col);
        });
    } else {
        // go through each column in the table
        $('#tbl td:not(.xx)').each(function() {
           // get column text
           var colData = $(this).text();
           // get column class
           var colClass = $(this).attr('class');
           // create input element
           var input = $('<input />');
           // fill it with data
           input.addClass(colClass).val(colData);
           // now. replace
           $(this).replaceWith(input);
        });

    }



    // give link class active to detect if we are in input mode
    $(this).toggleClass('active');
});

2 Comments

its changing to input, but not updating
@blasteralfred, ah, missed that part. Give me a sec to update it.
1

Here is my version - I felt I should post it since I keep having comments on all given suggestions

DEMO

$('#tbl .xx').toggle(
  function() {
    $(this).siblings().each(function(){
      var t = $(this).text();
      $(this).html($('<input />',{'value' : t}));
    });
  },
  function() {
    $(this).siblings().each(function(){
      var inp = $(this).find('input');
      if (inp.length){
        $(this).text(inp.val());
      }
    });
  }    
);

if you give the fields the same class, you can do

$(".field").each(

instead of

$(this).siblings().each(

Comments

0

According to your fiddle, you did almost everything ok, you just need to use

$col1.html('<input type="text" />');

and you're done, the content of the cells is changed to input fields.

Comments

0

Updated:

$('#tbl').on('click','.xx',function() {
    $('td').not(':last').each(function(){
      var val = $(this).text()      
      $(this).text('').append("<input type='text' value=" + val + ">")
    })
});

$('td:last').click(function() {
    $(this).toggleClass('xx');
})       

$('td:last').on("click", function(){

$('input').each(function(){
     var tex = $(this).val();
     $(this).replaceWith(tex);
})

})  

http://jsfiddle.net/767y4/10/

3 Comments

the row is not updating. The fields remain as <input>
What is the point of using on("click') then .click(...) and then on("click") on the same element instead of doing all in one click? Also siblings will choose all the other TDs so no need to test for the last all the time
@mplungjan yes, it needs if statement, i wrote this too fast, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.