views:

652

answers:

2

Hi

I have data

<tr id="row_1">
  <td id="td_1_1">Text 1</td>
  <td id="td_2_1">Text 2</td>
  <td><a href="#" onclick="editRow(1)">Edit row</a></td> 
</tr>

then in javascript

function editRow(row_id) {
   //some ajax to retrieve html in the format
   //<td><input type="text" name="td_1" value="Text 1"></td>
   //<td><input type="text" name="td_2" value="Text 2"></td>
   //<td><input type="submit" name="submit" value="submit"></td>
}

in editRow function I do some ajax and retrieve TDs and replace [$(row_id).html(html)] the row's TDs. All this works fine. But I need to have one cancel button, clicking which brings the original TDs back (that is .. no input boxes). Any ideas, how to achieve this functionality? Do I need to copy the before edit row html to a variable, and then later on cancel replace input boxes html? Thank you for your help.

EDIT

Also, if user clicks somewhere else on the page, it should consider it as cancel and bring the original data back. How to bind this action?

+1  A: 

First of all - look into Javascript frameworks. The kind of functionality you are talking about is advanced enough that if you really want your code to work in all browsers correctly you shouldn't do this on your own. It would also let you keep your HTML free of ugly inline Javascript and such, which is considered bad practice.That being said, here's a thought:

Have you considered having two rows per item, one of the row in "edit mode" and one of the row in "normal mode"? You could style the "edit mode" rows to be hidden by default, and when someone clicks on the edit link you can hide that row and bring the edit one into view. This would really be easier than doing an AJAX call to get the edit form.

EDIT

Here's some code to get you started:

function editRow(row_id, callback) {
   // you would get this dynamically through ajax, thus why we need the callback
   var html = '<tr id="edit_' + row_id + '" class="edit"><td><input type="text" name="td_1" value="Text 1"></td><td><input type="text" name="td_2" value="Text 2"></td><td><input type="submit" name="submit" value="submit"></td></tr>';
   callback(html);
}

$('a.edit', '#data').click(function() {
    var $tr = $(this).closest('tr');
    var id = $tr.attr('id').split('_').pop();
    var edit_row = '#edit_' + id;
    if($(edit_row).length == 1) { // edit row already exists
        $tr.hide();
        $(edit_row).show();
    } else { // doesn't exist, fetch it
        editRow(id, function(html) {
            $tr.hide();
            $tr.after(html);
        });
    }
    return false;
});

$(window).click(function(e) {
    $('tr.edit:visible').each(function() {
        var $tr = $(e.target).closest('tr');
        var id = $(this).attr('id').split('_').pop();
        console.log(e.target, $tr, this);
        if($tr.attr('id') != this.id) {
            $(this).hide();
            $('#row_' + id).show();
        }
    });
});

I should probably note that there are a lot of jQuery plugins that do a lot of this for you, and depending on the needs of your application you might be better off just fetching the row every time, not fetching them at all, etc. This is just a rough idea of what you might have to do to achieve what you want, and the rest is up to you. :)

Paolo Bergantino
Hmm .. @Paolo .. its not a bad idea.. but it would just double the number of rows on page.. hence the page size increases as well. Not an issue but I'll wait for another solutions before I impelement this. Regarding frameworks, I am not very experienced in javascript .. and given the custom requirements I thought of my basic flow of things as above. Thanks.
Wbdvlpr
I know it'd increase the page size, I could swear I added a note about that. Anyhow, most of my applications have paging in them so no more than 50ish rows are in a page anyways, and 100 rows is really not a big deal. If you want I can whip something up to keep it how you have it, but I'd use jQuery as otherwise it's too much of a pain in the ass. :)
Paolo Bergantino
@Paolo.. yes I did read your note about html. Anyhow I use Jquery as well. If you can throw some light how to do it using Jquery that will be very helpful. Thanks.
Wbdvlpr
Another thought is that instead of overriding the original row when you load the edit row, you can simply hide the original row, add a new one directly after/before it, and then show the original back when the editing is finished.
Paolo Bergantino
yes, I was thinking something like this after your answer about hiding rows. Instead of loading and replacing TDs I just hide and load a new Row. If there is any "better" way please do help me know.
Wbdvlpr
I think that's a pretty good solution to be honest. It should be trivial to do with jQuery.
Paolo Bergantino
OK. Thanks mate.
Wbdvlpr
A: 

I think to get the initial functionality using jQuery you can look at the jEditable plugin. This is a very functional plugin that allows you to click on some text and create an editable area and cancel etc. I assume that once the user clicks OK or Save that you do not need to revert to the original, its only mid edit that this is an issue. jEditable takes care of this.

Vincent Ramdhanie