Inline Row Editing

Inline Row Editing

jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
edited November 2011 in General
So I have come a long way since I started this implementation and need some assistance as I have been struggling to get it all working properly.

I have a table of 10 columns one of which is the edit link column. During the edit process one column (Promo Code) is not editable so I had to work on the JS for editRow so that it would work. Saving the rows works fine. However the issue at hand comes when you have to have restoreRow called or when you add a new record.

I created a new function called addRow and have used this because when "Adding" a record you must edit ALL columns INCLUDING promo code.

Below is an explanation of the issues I am struggling with and also the full code for the data table.


ISSUE: When I click the add new promo link it reloads the table and no new row is inserted at the start of the table. Also when I click the edit link for one row and then go click it for another row things go crazy and I start to see errors like the following in my console. Here is exactly what happens through the process. I click Edit link and a row becomes Editable. I click yet another Edit link and the first row goes back to being non-editable. The second row becomes Editable but then quickly goes back to being non-Editable. When I click any other Edit link I get the following error.

[code]
aData is null
https://www.domain.com/admin-assets/js/gsn.mktool.promotions.js
Line 93
[/code]

Line 93 is part of restoreRow and is below.

[code]
oTable.fnUpdate( aData[i], nRow, i, false );
[/code]

So with the problem explained here goes the code for the data table I will start with the HTML

[code]
Add New Promotion




Edit
Type
Name
Code
Start Date
End Date
Close Date
Amount
Total Awards
Total Max




Loading data from server




[/code]

and here is the FULL JS file which includes everything the datatable will need to do.
I was going to put the code here however when I tried to post it told me the body was 4000+ characters too long.

http://www.josephcrawford.com/code/gsn.mktool.promotions.js

Clicking on the add new promo link only makes the following request in my console

[code]
https://www.domain.com/admin/mktoolpromotionsajax/?sEcho=3&iColumns=10&sColumns=&iDisplayStart=0&iDisplayLength=10&mDataProp_0=0&mDataProp_1=1&mDataProp_2=2&mDataProp_3=3&mDataProp_4=4&mDataProp_5=5&mDataProp_6=6&mDataProp_7=7&mDataProp_8=8&mDataProp_9=9&iSortingCols=1&iSortCol_0=1&sSortDir_0=desc&bSortable_0=true&bSortable_1=true&bSortable_2=true&bSortable_3=true&bSortable_4=true&bSortable_5=true&bSortable_6=true&bSortable_7=true&bSortable_8=true&bSortable_9=true
[/code]

Any assistance in getting this to work would be appreciated it's the last and final step to get to the finished tool :)

Replies

  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    bump?
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    After some Thorough debugging I have found that when you click the edit link for the second row and it gets to line 188 of the gsn.mktool.promotions.js file it enters the editRow function but the call on line 87 is returning null

    [code]
    var aData = oTable.fnGetData(nRow);
    [/code]

    Any thoughts why this would happen?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    This would happen if nRow is not a row that the table knows about (i.e. it hasn't been found in the internal DataTables cache). What is nRow at that point? If its a TR element that is in the table and has been rendered by DataTables then that is certainly a bug and I'd love a test case of how your table is setup. However, I would suspect that nRow is either not a TR element or its not a TR element that DataTables knows about.

    Allan
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    edited November 2011
    Allan,

    When I load my table and I click Edit on the first row nRow gets set to tr#619.odd in my Watch Panel. When I click Edit on the second row it says tr#417.even

    Is there a way I could console.log the columns for the tr to see what tr#417 contains?

    One thing to keep in mind is the fact that I am using Server Side data.

    Thanks,
    Joseph Crawford
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    console.dir( $('td', nRow) );

    :-)

    I don't think that server-side processing will have any issue with this, as long as the row is still in the DataTables cache. You can have a look at the cache using:

    console.dir ( oTable.fnSettings().aoData );

    The TR elements are called 'nTr' in the aoData array objects.

    Allan
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    edited November 2011
    Allan,

    I was not quite sure how to copy the output so I took a screen shot of FireBug

    I put the command as the first command in restoreRow(), just before the fnGetData call.

    http://www.josephcrawford.com/pics/dt-cache.png

    as you can see both records exist in the cache

    I am going to try the same but for the editRow method, will report back soon.
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    Allan,

    Yep something happens to my data somehow somewhere between restoreRow and editRow because in this second attempt to dump out the cache but this time in the editRow method as the first command I get the following results.

    http://www.josephcrawford.com/pics/dt-cache1.png

    Notice the second record in the cache is all NULL. Thoughts?
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    it appears to me that something is happening between line 187 and 189. restoreRow should not effect the cache right? And doing nEditing = nRow should not do anything either so I am quite at a loss here :(
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    I'm wondering if the fact that you are using server-side processing is having an effect here because the row will not be in the cache if you do a draw between caching the element in your variable and then doing a lookup on fnGetData - is that the case or not? It might be that the code will need to be updated to take that into account.

    Allan
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    I am not sure how the internals of DT works but I am not doing any manual caching. Basically what is happening is this.

    The page loads and makes the initial ajax request to get data
    I click Edit for the first row in the table and the form fields appear
    I then click Edit on the 2nd row in the table and it restores the first row however
    it then sets nEditable = nRow and calls editRow on that new row. This is where
    it data is coming back null.

    There is only one server request being made. As for drawing the table restoreRow updates the columns and then calls fnDraw so if fnDraw clears the cache that is the problem.
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    Allan,

    Thanks it took me a bit to grasp what you were saying lol. I removed the draw event and everything seems to be working perfect.
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    edited November 2011
    Allan,

    Upon clicking my Add New Promo link this code is triggered

    [code]
    $('#newPromo').click( function (e) {
    e.preventDefault();

    var aiNew = oTable.fnAddData( [
    'Edit',
    '', '', '', '', '', '', '', '', ''
    ] );
    var nRow = oTable.fnGetNodes( aiNew[0] );
    addRow( oTable, nRow );
    nEditing = nRow;
    } );
    [/code]

    However nRow is null in my debugger. aiNew in my debugger shows as the following

    [code]
    aiNew [ 10 ]
    0 10
    [/code]

    Thoughts on why this would return null?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    The first thing to note is that fnAddData is not suitable for use with server-side processing unless you are really careful. By default it will do a redraw (as it will above) thus causing a fetch from the server and any nodes you have stored are now lost. If you want to manipulate what is in the table you need to do it either on the server-side or through the DOM (and if the latter, know that any change in the table to make it redraw will result in your losing your changes, unless you reapply them).

    So in this case, you don't want to add a row like that, since it will do a redraw. You probably want to use appendChild() or something like that from the DOM to add the new row, and then when submitted to the server the redraw will add the new data in.

    Allan
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    edited November 2011
    Thanks I will give this a shot. Sorry I was just basing everything off of your example :)

    I should note that I did explicitly tell fnAddData not to redraw the table and it still was not working. I will attempt to use the DOM to get the job done. Thanks.
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    edited November 2011
    Allan,

    One more question about manipulating with the DOM. If I add a row using jquery for something like the following

    [code]
    $('#newPromo').click( function (e) {
    e.preventDefault();
    $('#promos tr:last').remove();
    $('#promos > tbody > tr').eq(0).before('Edit');
    var nRow = oTable.fnGetNodes( 0 );
    addRow( oTable, nRow );
    nEditing = nRow;
    } );
    [/code]

    So I have gotten everything to work or so I thought. I am able to add a new row to the table, remove the last row so that the row counts remain the same in the table. However when nRow is set by getting the 0 node from the table it is actually the original first row in the table and NOT the new row I just added. Could you assist with what might be going on with that?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    fnGetNodes is only going to work for nodes that DataTables knows about (i.e. it gets the node from data index 0 in its cache), but since you've injected it straight into the DOM here, DataTables doesn't know anything about it!

    So in this case, just stick to using jQuery / DOM methods: nRow = $('#promos > tbody > tr:eq(0)')

    Allan
  • jcrawfordjcrawford Posts: 172Questions: 0Answers: 0
    Allan,

    unfortunately going the DOM route is going to make it so that I have to rewrite all methods for save, restore, edit, etc.

    I have to do this because using jquery and the dom when edit/save/restore rows are called it has no idea of the data because fnGetData.

    Thanks for the information I am going to be working on a rewrite for this that will not use the DT API. Unless it can be done using server side processing.

    The one thing I am having a bit of trouble understanding is how I will restore the row since the data will not be stored in the DT internal data. Upon clicking Edit row I think I need to create an array of the real data, that way restore row has the "real" data to restore.
This discussion has been closed.