Select the datatable instance in a function under fnServerData

Select the datatable instance in a function under fnServerData

matthttammatthttam Posts: 40Questions: 2Answers: 0
edited November 2012 in DataTables 1.9
Hell again!

I don't completely understand things in javascript so I was hoping someone could answer this question.

The following code works great! And it is repeated on all 4 tables. I wanted to create a function for it and send the variables I need but that won't work for some reason. Here is the code I am talking about:

Works:
[code]
"fnServerData": function ( sSource, aoData, fnCallback ) {
/* ... additional variables ... */
$.getJSON( sSource, aoData, function (json) {
if(json.error == 'expired'){
timeoutLogoff();
}else{
/* Create the select elements on the first run */
if ( json.sEcho == 1 )
{
build_dropdowns('Assignments',json,oTable);
}
/* DataTables callback */
fnCallback(json)
}
} );
}
[/code]

note that build_dropdowns is a function that will create teh drop downs based off the json data. Here is it's code:
[code]
function build_dropdowns(tableID, json, refName){
$("#"+tableID+" tfoot th.dropdown").each( function () {
index = refName.fnVisibleToColumnIndex($(this).index());
$(this).html(fnCreateSelect(json.select[index], index));
$('select', $(this)).change( function () {
refName.fnFilter( $(this).val(), refName.fnVisibleToColumnIndex($(this).parent().index() ));
} );
} );
}
[/code]

Notice how this function needs the refName (like oTable or wTable) to call fnFilter etc... I couldn't figure out a way to get the instance of datatable based off the ID of the table.

So, I changed fnServerData to this:
[code]
//**in the global scope area at the top of the page**//
function build_fnServerData(table,refName,sSource, aoData,fnCallback){
$.getJSON( sSource, aoData, function (json) {
if(json.error == 'expired'){
timeoutLogoff();
}else{
if ( json.sEcho == 1 ) {
build_dropdowns(table,json,refName); // Create the select elements on the first run
}
return fnCallback(json)
}
} );
}
/* ... */

//**in the wTable datatable setup area**//
"fnServerData": function ( sSource, aoData, fnCallback ) {
build_fnServerData('WO',wTable,sSource, aoData,fnCallback);
}
[/code]

I don't know the best solution. Is there a way to reference wTable dynamically?
When I pass wTable from fnServerData it says "wTable not defined" but if I hard code wTable into the build_dropdowns function within build_fnServerData it will work... Is this because getJSON is asyncronous so when getJSON is called the datatables object is created? Is there a way to dynamically get the datatable instance like $('#WO').thisInstanceOfDatatables? Should I pass a string (or have a global has value to convert) and use eval to use the correct variable name when it is needed?

Thanks for the help!

Replies

  • matthttammatthttam Posts: 40Questions: 2Answers: 0
    edited November 2012
    Hmmm... is there anything wrong with doing eval?
    [code]
    build_dropdowns(table,json,eval(varLookup[table]));
    /* where varLookup is */
    var varLookup = {'WO':'wTable'};
    [/code]
  • allanallan Posts: 63,394Questions: 1Answers: 10,450 Site admin
    Yes - eval is evil and should be avoided unless you really really really need to use it.

    The key thing to know here is that the DataTables callbacks are executed with the scope of the DataTables instance. That means that `this` is your instance. For example:

    [code]
    "fnServerData": function ( sSource, aoData, fnCallback ) {
    var that = this;

    $.getJSON( sSource, aoData, function (json) {
    if(json.error == 'expired'){
    timeoutLogoff();
    }else{
    /* Create the select elements on the first run */
    if ( json.sEcho == 1 )
    {
    build_dropdowns('Assignments',json, that);
    }
    /* DataTables callback */
    fnCallback(json)
    }
    } );
    }
    [/code]

    Note how I've used `that` in your `build_dropdowns` function. `that` has been assigned `this` at the top of the function - `this` where `build_dropdowns` is called related to the getJSON callback which is why this is needed!

    Allan
  • matthttammatthttam Posts: 40Questions: 2Answers: 0
    I must be dense or something. I thought I tried this... but I think I used $(this). Don't know if that would make a difference or not. I just tested sending 'this' to the function and it worked fine. On a side note, I found out I could access the instance using window['wTable']. I plan on making one object at the top and a for loop with that object to create all 4 tables instead of how I have it setup now. This will allow me to make a change once and it affect all 4 tables instead of having to copy and paste all those times. With this in mind this works great: window[varLookup[tableID].obj];.

    Thanks for the this thing though. I'll console.log 'this' and see if I can find the ID of the table in it. This would reduce the complexity of my function calls a bit.

    Thanks for the help.
    Bil
  • matthttammatthttam Posts: 40Questions: 2Answers: 0
    Thanks again for the help. Here is my final code! Now I can call build_fnServerData in a loop (later after i fix several other functions) and it will work! I am using this.selector to get the ID of the table when I need to select elements of the table I am working on.

    [code]
    function build_fnServerData(that,sSource, aoData,fnCallback){
    $.getJSON( sSource, aoData, function (json) {
    if(json.error == 'expired'){
    timeoutLogoff();
    }else{
    if ( json.sEcho == 1 ) {
    build_dropdowns(that,json); // Create the select elements on the first run
    }
    return fnCallback(json);
    }
    } );
    }

    function build_dropdowns(that, json){
    $(that.selector+" tfoot th.dropdown").each( function () {
    index = that.fnVisibleToColumnIndex($(this).index());
    $(this).html(fnCreateSelect(json.select[index], index));
    $('select', $(this)).change( function () {
    that.fnFilter( $(this).val(), that.fnVisibleToColumnIndex($(this).parent().index() ));
    } );
    } );
    }
    /* ... snippet from dataTable() initialization ... */
    "fnServerData": function ( sSource, aoData, fnCallback ) {
    build_fnServerData(this,sSource, aoData,fnCallback);
    }
    [/code]
  • allanallan Posts: 63,394Questions: 1Answers: 10,450 Site admin
    > $(this)

    That makes a jQuery object of the current object. That might or might not be what you want. It typically isn't with a DataTables instance.

    However, good to hear you got a solution that works for you :-)

    Allan
This discussion has been closed.