Ajax Reload

Ajax Reload

PeterPeter Posts: 8Questions: 0Answers: 0
edited July 2009 in General
Hi Allan,

i have 2 issues with datatables.
i'm loading data-table with ajax. after completion of table initialisation i can trigger this event with:
"fnInitComplete": function()
and it works fine!

but how can i do the same thing after reload? my users can reload the table via ajax:
oTable.fnReloadAjax(url);
how can i trigger the event that the table was reloaded successfully?

A second question:

I would like to use one of the table rows for google adsense.
The goal is that e.g. the 10th row is made of 1 column only (colspan?) and is slightly higher and filled with the google adsense code.
I have no clue whatsoever how i could possibly do that. Any idea?

Thanks for any help, and anyway for this amazing plug-in.

Regards
Peter

Replies

  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    Hi Peter,

    1. To detect the successful loading after calling fnReloadAjax() there are two options:
    1.1 - Modify the plug-in code to call whatever function you want after the fnDraw() (I might add this to the plug-in anyway - nice idea)
    1.2 - Use fnDrawCallback() to signal when a draw occurs (the first is probably easier :-) )

    2. Interesting one... I presume you don't want this row to actually be 'in the table' as such (i.e. filtering, sort etc will have no effect on it) but you do what the row to be present in the table (if that makes sense...). If so then I would suggest using fnDrawCallback ( http://datatables.net/usage#fnDrawCallback ) in combination with fnOpen() and fnClose() ( http://datatables.net/api#fnOpen ) - see a demo of these functions here: http://datatables.net/1.5-beta/examples/api/row_details.html

    What you can do then is to use fnDrawCallback to open the last row in the table on each draw (a simple selector will give you that row) and 'open' it with the adsense code.

    Another option, which also uses fnDrawCallback(), but not fnOpen/fnClose, is to append your special row on each draw. This might actually be a better option as you wouldn't need to worry about closing rows again... Plus the browser would only need to construct the DOM for the row once.

    Hope this helps!

    Allan
  • PeterPeter Posts: 8Questions: 0Answers: 0
    Thanks Allan,

    1) i managed to add the code to the plug-in. It works. What kind of tool do you use to minify the code? Because i added the code to the uncompressed version of your plugin, which is a bit large... So i would like to compress the code again...

    2) The example is pretty much what i need, i just don't get how to add exactly 1 (one) row at a special position. For example between the 'normal data rows' 6 and 7.

    Thanks a lot.
    Peter
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    Hi Peter,

    1. Is there a compressed version of fnReloadAjax() around? I thought there was just the raw source on the plug-ins page. Regardless, I use the YUI compressor: http://developer.yahoo.com/yui/compressor/ which should do the trick for you. I think there are online versions of this compressor as well which can be used if it's just "one shot".

    2. Are you happy with inserting the row now? If pure jQuery/DOM you can just use $('#example tbody tr:eq(5)') (for example) for with the fnOpen method, just pass the required from using a selector like that above.

    Regards,
    Allan
  • PeterPeter Posts: 8Questions: 0Answers: 0
    Hi Allan,

    2)
    i don't understand in which context i have to put
    $('#table_results tbody tr:eq(5)')
    is it a function? is there an event to catch? where can i put the html of the row?

    Do you maybe have a little example code?

    Thanks a lot
    Peter
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    Hi Peter,

    Okay, let's assume you have a node that you want o insert into the table (with the google code in it). This might have been created with something like:

    [code]
    var nTr = document.createElement('tr');
    var nTd = document.createElement('td');
    nTd.colspan = "5"; // or whatever
    nTd.innerHTML = "google code";
    nTr.appendChild( nTd );
    [/code]
    Then you can insert this node into the table (at the end) using:

    [code]
    $('#example tbody')[0].appendChild( nTr );
    [/code]
    Or if you want it part way through the table using insertAfter() and the selector above (with the eq(x)).

    Regardsm
    Allan
  • PeterPeter Posts: 8Questions: 0Answers: 0
    Hi Allan,

    i put the code into http://www.inmolia.com/js/search.js (at the end)

    Now, it shows the new row, but only if the table is empty, as soon as there is data loaded (via ajax), the new line disappears again.

    You can see this effect when you load my project site:
    http://www.inmolia.com
    First you can see the "google code" in the table, but then data is loaded to the table via ajax and the "google code" row is gone.

    I checked all pages of the pagination, but the row is nowwhere. Anyway it is not quite clear to me how to tell datatables to define the new row at e.g. position 5 of all rows.

    I'm desperate. Hope you have an idea.
    Cheers
    Peter
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    Hi Peter,

    You want the TR row insertion to run on every draw, so you need to put that code into fnDrawCallback() ( http://datatables.net/usage#fnDrawCallback ). Try that and hopefully you will get somewhere.

    Allan
  • PeterPeter Posts: 8Questions: 0Answers: 0
    Hi Allen,

    finally i was able to create the new row:
    [code]
    "fnDrawCallback": function () {
    var nTrs = $('#table_results tbody tr');
    var nRow = document.createElement( 'tr' );
    var nCell = document.createElement( 'td' );
    nCell.colSpan = 9;
    nCell.innerHTML = "google code";
    nRow.appendChild( nCell );
    nTrs[0].parentNode.insertBefore( nRow, nTrs[0] );
    }
    [/code]

    it creates the the new row as the first row of the table.

    to change that to e.g. row number 5, i changed the nTrs definition to:
    [code]
    var nTrs = $('#table_results tbody tr:eq(5)');
    [/code]

    but then firebug throws me an error: "nTrs[0] is undefined"

    also you mentioned insertAfter(). If use that instead of insertBefore, it throws an error too, "unknown function"

    I tried all kind of other stuff to make the new row go to somewhere in between the other rows, but i'm running out of ideas now. it just doesn't seem to work. Is it working at all, with ajax driven tables? i was wondering if datatables even knows that there is e.g. a 5th row at all in a ajax table.

    My project site: http://www.inmolia.com

    i hope you have a final tip for me.
    thanks so much.

    Peter
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    Hi Peter,

    Sounds like you are getting there...

    If you want to insert the TR at the end of your table, try something like:

    [code]
    $('#table_results tbody')[0].appendChild( nRow );
    [/code]
    Which is quick and easy, and also fool proof against the number of results on a page changing.

    If you want to get a bit more complex, you can do something like:

    [code]
    var jqRows = $('#table_results tbody tr');
    var iRows = jqRows.length;
    var iCenter = Math.floor( iRows / 2 );
    var nInsertPoint = jqRows[ iCenter ];
    $(nRow).insertAfter( nInsertPoint );
    [/code]
    Warning - not actually tested - but it should work... It could be made a lot more compact as well, but the breakdown should hopefully show how it works.

    Allan
  • PeterPeter Posts: 8Questions: 0Answers: 0
    Hi Allan,

    thank you so much. you are a genius. finally it works. it was a bit tricky with the google adsense code, it wasn't accepted as javascript, i had to put it into an iframe (with keywords as parameter), but now it works perfectly: http://www.inmolia.com
    one question: the fnDrawCallback is also triggered when the pagination or sorting is used, and therefore the adsense is reloaded everytime. i guess it might be aginst the terms of use of google-adsense to create all these impressions (i have posted this question to google already, so i'll find out soon). so it probably could be helpful if i could catch an event that is triggered only the first time the table is drawn, and not while sorting or paginating. i tried fnInitCallback instead of fnDrawCallback, but that one doesn't work in this case, the adsense is not loaded at all.
    is there such an event?

    Best regards
    Peter
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    Hi Peter,

    fnInitCallback() is the function that is called after initialisation has completed, and is called only once, so might help you a bit here - but then you only get your Google ads on the first page. This is what I was talking about when I mentioned creating the ads row only the first time and then moving it around the DOM.

    I'm guessing you have a document.createElement being fired in the draw callback every time at the moment, which I agree, Google might well object to. What you need to do is only create this TR element once. I'm not one to normally just write the solution, but it might be better to get understanding from that, on this occasion:

    [code]
    var gnTr;

    $(document).ready( function () {
    gnTr = document.createElement( 'tr' );
    var nCell = document.createElement( 'td' );
    nCell.colSpan = 9;
    nCell.innerHTML = "google code";
    gnTr.appendChild( nCell );

    $('#example').datatable( {
    "fnDrawCallback": function () {
    var nTrs = $('#table_results tbody tr');
    nTrs[0].parentNode.insertBefore( gnTr, nTrs[0] );
    }
    } );
    } );
    [/code]
    Warning - not actually tested so there might be a daft mistake - but the idea should be good.

    Allan
  • PeterPeter Posts: 8Questions: 0Answers: 0
    Thanks Allan,

    unfortunately this doesn't change anything. The iFrame with the google-code is reloaded anyway on each draw.

    So i came to this solution:

    [code]
    "fnDrawCallback": function () {
    if(iFirstPage==1)
    {
    var jqRows = $('#table_results tbody tr');
    var iRows = jqRows.length;
    var iCenter = Math.floor( iRows / 2 );
    var nInsertPoint = jqRows[ iCenter ];
    $(nRow).insertAfter( nInsertPoint );
    }
    },

    "fnHeaderCallback": function( nHead, aasData, iStart, iEnd, aiDisplay ) {
    if(iStart==0 && iEnd!=0)
    {
    iFirstPage=1;
    }
    else
    {
    iFirstPage=0;
    }
    }
    [/code]

    It checks through fnHeaderCallback if it is displaying the first of all pages, saves it into a global var (iFirstPage) and then let fnDrawCallback do the job. It is not fancy but it does work properly.

    there is just one little unwanted sideeffect:

    if the user is e.g. going to page 2 and then coming back to page 1, the google-iframe is reloaded of course.
    The problem is that i can't check if the table (page) is loaded for the first time or not.
    I tried the fnInitComplete function, but it seems to me that the rendering of the page is already done when that function is called. It did load the iFrame with the google code, but didn't display it anywhere.

    Peter
  • allanallan Posts: 63,494Questions: 1Answers: 10,470 Site admin
    Hi,

    fnInitComplete - yes this is the last function that DataTables will call (i.e. after the draw etc), which allows manipulation of the table once it's fully initialised. You could just have a global variable which is == 1 initially, and if that is the case, take a particular action for inserting the google row, then in fnInitComplete, set it to 2, which will indicate whatever other action is required.

    It's funny that it reloads the google data in the iFrame - I would have thought it would retain the DOM instance - but perhaps it does something odd with iFrames as opposed to other DOM elements.

    Allan
This discussion has been closed.