Pulling my hair out! Ajax keeps getting the same information

Pulling my hair out! Ajax keeps getting the same information

rh0diumrh0dium Posts: 14Questions: 0Answers: 0
edited September 2011 in DataTables 1.8
Hi There,

I LOVE DATATABLES. I've used them forever and now I want to wrap them in some Ajax love with Django.. Well I'm not feeling it yet..

In short - I want to click a button and have the data get updated.

So.. This works

[code]
$(document).ready(function() {
oTable = $('#table').dataTable({
'sPaginationType':'full_numbers',
"bServerSide":true,
"bProcessing": true,
"sAjaxSource":"{% if tree == 'catalog' %}{% url catalog_ajax %}{% else %}{%url projects_ajax %}{% endif %}",
"aoColumns":[
{ "bSearchable":true},
{ "bSearchable":true},
{ "bSearchable":true},
{ "bSearchable":false},
{ "bSearchable":false}
]
});
});
[/code]

All of the data is coming in. And I see everything as I should. Now I want to POST a "key" which will then narrow down this list. Prior to using datatables I did this via a simple function.

[code]
function doAjax(id){
var data = id;
$.ajax({ {% if tree == 'catalog' %}
url: '{%url catalog_ajax %}', {% else %}
url: '{%url projects_ajax %}', {% endif %}
type : "POST",
async: false,
data : { data:data },
error: function() {
alert("Error getting {{tree}} data!");
},
success: updateDiv
});
};
[/code]

And for those observant updateDiv simply cleared the table and redrew everything. BUT with data tables and server side processing I shouldn't need this (assuming I'm formatting everything correct - because it draws the first time).

THE PROBLEM

I can see the data coming back the first time correctly. I then see a subsequent POST which effectively kills the new data and replaces it with the same original data. Now (obviously) this is because bServerSide is set to true and refetching the data.

I feel I'm VERY close. In reading the docs I thought I could simply replace updateDiv with the [quote]oTable.fnReloadAjax(data.aaData)[/quote]. I've also tried various forms of [quote] "fnServerData": doAjax() [/quote]. All to no avail.

Can someone please point out my error - I AM CLOSE!

Replies

  • GregPGregP Posts: 500Questions: 10Answers: 0
    edited September 2011
    What does "updateDiv" do? Be handy to see that code as part of the puzzle. Also, does doAjax request the data set meant to populate the table again? Because currently I do not see the returned data being passed along.

    In general, using server-side processing, getting new data is easy:

    [code]
    oTable.fnDraw();
    [/code]

    Put that into your update function and Bob should be your uncle.
  • rh0diumrh0dium Posts: 14Questions: 0Answers: 0
    edited September 2011
    Hey GrebP

    (as an aside I haven't heard Bob should be your uncle in a long time - that still rules)

    Update div was this .. BUT (continued after the code)
    [code]
    function updateDiv(data){
    var table_length = data.length;
    $('#table td').remove();
    if( data.length != 0 ){
    for(var i = 0; i < data.length; i++){
    $('#table').append('\
    ' + data[i].name + ' \
    ' + data[i].variant_name + ' \
    ' + data[i].description + ' \
    ' + data[i].site + ' \
    ' + data[i].protocol + ' \
    ');
    }
    }else{
    $('#table').append('No projects found.')
    }
    };
    [/code]

    Now clearly this is no longer needed as I am getting the data and processing this server side.

    So where am I at..

    1.) I have a click function where the text is the piece of information I need to send back to the server. This correctly gets me the info I need to send back.
    [code]
    $('a.menu').click(function(){
    alert($(this).text())
    });
    [/code]

    2.) I have the core datatable jquery piece. This correctly gets the first round of data and handles the updates and re-sorting etc.
    [code]
    $(document).ready(function() {
    oTable = $('#table').dataTable({
    'sPaginationType':'full_numbers',
    "bServerSide":true,
    "bProcessing": true,
    "sAjaxSource":"{% if tree == 'catalog' %}{% url catalog_ajax %}{% else %}{%url projects_ajax %}{% endif %}",
    "aoColumns":[
    { "bSearchable":true},
    { "bSearchable":true},
    { "bSearchable":true},
    { "bSearchable":false},
    { "bSearchable":false}
    ]
    });
    });
    [/code]

    3.) On the receiving side I'm expecting my POST['identifier'] to contain the information from #1. When it does have this it correctly sends the data back.

    THE PROBLEM.

    How do I wrap this up and tie #1 to #2 so that a click correctly sends the POST data to the server?

    Thanks much
  • rh0diumrh0dium Posts: 14Questions: 0Answers: 0
    edited September 2011
    A bit more..

    I've figured out how to tie them together.. But I broke it in the process. I now see the data coming back but I never see it show upon hitting the page the first time or any subsequent hit. I can tell I'm getting the data back by looking at the response. The pages just says processing...

    Here is where I am at:

    [code]

    $(document).ready(function() {
    oTable = $('#table').dataTable({
    'sPaginationType':'full_numbers',
    "bServerSide":true,
    "bProcessing": true,
    "sAjaxSource":"{% if tree == 'catalog' %}{% url catalog_ajax %}{% else %}{%url projects_ajax %}{% endif %}",
    "fnServerData": function (sSource,aoData,fnCallback){
    aoData.push({"name":"identifier","value": identifier});
    $.ajax({
    "dataType":'json',
    "type":'POST',
    "url":sSource,
    "data":aoData
    });
    }
    });

    $('a.menu').click(function(){
    identifier = $(this).text();
    oTable.fnDraw(false);
    });

    [/code]

    I'm so close I can taste it... Any advice would be greatly appreciated..
  • GregPGregP Posts: 500Questions: 10Answers: 0
    Wish I had a live example to look at. ;-)

    I don't see where identifier is first declared. You need to have it in a scope that your click handler and dataTable object can both access. Although JavaScript will forgive you, you should probably also use 'var' in front of the oTable chunk.

    Based solely on the code above, it looks like it's trying to use 'identifier' too early. dataTable() will in fact be called during your object declaration, but from what I can see, 'identifier' is undefined the first time it's being called.

    Again, hard to tell without seeing the live version, but I would be tempted to take this approach instead:

    [code]
    $(document).ready(function() {
    var identifier = "some initial value, either hard-coded or via a function call";

    var oTable = $('#table').dataTable({
    'sPaginationType':'full_numbers',
    "bServerSide":true,
    "bProcessing": true,
    "sAjaxSource":"{% if tree == 'catalog' %}{% url catalog_ajax %}{% else %}{%url projects_ajax %}{% endif %}",
    "fnServerData": function (sSource,aoData,fnCallback){
    aoData.push({"name":"identifier","value": identifier});
    $.ajax({
    "dataType":'json',
    "type":'POST',
    "url":sSource,
    "data":aoData
    });
    }
    });

    $('a.menu').click(function(){
    identifier = $(this).text();
    oTable.fnDraw();
    });
    }); //notice I added these; you probably have them too but just didn't paste them.
    [/code]
  • GregPGregP Posts: 500Questions: 10Answers: 0
    If that doesn't work, I would be curious to see if there are any errors appearing in your JavaScript console. If you're not using a JavaScript console yet, there's one built into Chrome and IE, and the one most people around here use is available through Firebug, a Firefox add-on.
  • rh0diumrh0dium Posts: 14Questions: 0Answers: 0
    Hi Greg,

    Here is all of it. I know I'm close.. I see the data coming back from the server (through firebug) but It's not updating the table itself. All I was seeing was "Processing" but then I removed the bProcessing and that cleaned up (Came from earlier today tweaking)..

    [code]



    var identifier;
    var oTable;

    $(window).load(function() {
    $('#menu').treeview({collapsed:true});
    });

    $(document).ready(function() {
    oTable = $('#table').dataTable({
    'sPaginationType':'full_numbers',
    "bServerSide":true,
    "sAjaxSource":"{% if tree == 'catalog' %}{% url catalog_ajax %}{% else %}{%url projects_ajax %}{% endif %}",
    "fnServerData": function (sSource,aoData,fnCallback){
    aoData.push({"name":"identifier","value": identifier});
    $.ajax({
    "dataType":'json',
    "type":'POST',
    "url":sSource,
    "data":aoData
    });
    },
    "aoColumns": [
    { "bSearchable": true},
    { "bSearchable": true},
    { "bSearchable": true},
    { "bSearchable": false},
    { "bSearchable": false}
    ]
    });

    $('a.menu').click(function(){
    identifier = $(this).text();
    oTable.fnDraw(false);
    });

    });


    [/code]
  • rh0diumrh0dium Posts: 14Questions: 0Answers: 0
    Last comments before I head to bed..

    The problem seems to be centered around fnServerdata..
    Notice my json.aaData - That errors out.

    [code]
    'fnServerData': function (sSource,aoData,fnCallback){
    aoData.push({"name":"identifier","value": identifier});
    $.ajax({
    "dataType": 'json',
    "type": "POST",
    "url": sSource,
    "data": aoData,
    "success": function(json){
    fnCallback(json.aaData);
    },
    "error": function (msg) { alert("Shit!") }
    })
    },

    [/code]

    And if I do this It works but doesn't update..

    [code]
    'fnServerData': function (sSource,aoData,fnCallback){
    aoData.push({"name":"identifier","value": identifier});
    $.getJSON( sSource, aoData, function (json) {
    fnCallback(json)
    }) ;
    },
    [/code]

    I'm sure there is very logical explanation to this...
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    There is actually an easier way of doing this with DataTables 1.8.2: http://datatables.net/ref#fnServerParams . With this function you don't need to modify fnServerData if you just want to pass extra data to the server (which if I understand correctly is what you want) - you can just put the extra information onto the passed in array.

    Hopefully save you a lot of time messing around with fnServerData!

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    In the top sample, type is switched to "POST". In the second, it's using .getJSON. Make sure you're consistent in whether you're using POST or GET to retrieve the data.

    If you are using POST, you will need fnServerData. If you are using GET, you can use fnServerParams as Allan suggests (just make sure you are using DataTables 1.8.2)
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Ah yes - for POST you would need to use fnServerData currently. I think I might add an init option for that as well...

    Allan
This discussion has been closed.