8

I've created a simple form and I'm using the Datatables jQuery plugin to display some data in it. Data are being populated by a php script (process.php) which returns the proper results in JSON format. In the form, there is a button that sends the value of the textbox to the process.php. The problem is that I cannot update/alter datatable with the new data received by process.php script when the button is clicked.

The code of the form:

<form name="myform" id="myform" action="" method="POST">  
    <label for="id">Enter an id:</label>  
    <input type="text" name="txtId" id="txtId" value=""/> 
    <input type="button" id="btnSubmit" name="btnSubmit" value="Search"> 
</form>

<div id="results">
    <table class="display" id="example">
        <thead>
            <tr>
                <th>id</th>
                <th>Surname</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            <!-- data goes here -->
        </tbody>
    </table>
</div> 

To create the datatable, I'm using the following JQuery code:

    $(document).ready(function() {
            var oTable = $('#example').dataTable( {
                "sPaginationType": "full_numbers",
                "iDisplayLength": 10,
                //"bServerSide": true,
                "sAjaxSource": "process.php"
            } );

        $("#btnSubmit").click(function(){
            $.ajax({  
                type: "POST",  
                url: "process.php",  
                data: 'txtId=' + $("txtId").val(),  
                success: function(result) {  
                    oTable.fnReloadAjax();
                    oTable.fnDraw();
                }  
            });
        });
    } );

process.php script (works fine) is:

<?php
$result="";
if (empty($_REQUEST["txtId"])) {    
    $result = '{"aaData":[["1","Surname1","Name1"]]}';
}
else {
    $result = '{"aaData":[["2","Surname2","Name2"]]}';
}
print $result;
?>
2
  • 1
    never create JSON using string functions. PHP has json_encode(). In your case, you'd use echo json_encode(array('aaData' => array(array('1', 'Surname1', 'Name1')))); Commented Apr 15, 2012 at 9:38
  • Yes, I know about json_encode() funtion. The above process.php script was written for simplicity reasons. Thanks anyway, ThiefMaster! Commented Apr 15, 2012 at 11:43

5 Answers 5

4

fnReloadAjax is what you should use (and I believe that it might have a redraw built into the function). But the problem is that, although you make a second .ajax call, the data in that call is not associated with your datatable at all and will never be bound to it.

Using fnReloadAjax will make the same Ajax call that you specified in your table initialization. So what you need, as Stefan mentioned, is to specify your fnServerData parameter in your datatable settings (but trash the Success parameters, because something along those lines is already assumed by datatables). Then just make your button call fnReloadAjax().

Here's what your final code should look like:

$(document).ready(function() {
        var oTable = $('#example').dataTable( {
            "sPaginationType": "full_numbers",
            "iDisplayLength": 10,
            "sAjaxSource": "process.php",
            "fnServerData": function ( sSource, aoData, fnCallback ) {
                $.ajax( {
                    "dataType": 'json', 
                    "type": "POST", 
                    "url": sSource, 
                    "data": 'txtId=' + $("txtId").val(), 
                    "success": fnCallback
                } );
            }
        } );

    $("#btnSubmit").click(function(){ 
        oTable.fnReloadAjax();
    });
} );
Sign up to request clarification or add additional context in comments.

3 Comments

This is a great explanation. So it looks as if it might not even be necessary to use fnServerData if you don't insist on using POST to pass parameters to the script - since by default GET will be used.
Your code seems right but it didn't work for me. I solved the problem by adding the fnReloadAjax() plugin API code (found in datatables.net/plug-ins/api) after the script tags which load datatables and before $(document).ready() function. I also changed the jquery code of my submit button to this: $("#btnSubmit").click(function(){ oTable.fnReloadAjax("process.php?txtId=" + $("txtId").val()); }); Thanks!
Perfect! If you use fnReloadAjax specifying a new source for your button click, fnServerData is not needed. Glad to hear you got it working.
3

At last, I found the solution! There were 2 problems in my JQuery code:

  1. I had to add the fnReloadAjax() code after the script tags which load datatables and before the $(document).ready() statement.
  2. I had to alter the JQuery code of my submit button (no need for an AJAX call, only fnReloadAjax() is necessary).

Thank you both Stefan & mbeasley!!

JQuery code now is:

//
// fnReloadAjax() code      
//
    $.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw )
    {
        if ( typeof sNewSource != 'undefined' && sNewSource != null )
        {
            oSettings.sAjaxSource = sNewSource;
        }
        this.oApi._fnProcessingDisplay( oSettings, true );
        var that = this;
        var iStart = oSettings._iDisplayStart;
        var aData = [];

        this.oApi._fnServerParams( oSettings, aData );

        oSettings.fnServerData( oSettings.sAjaxSource, aData, function(json) {
            /* Clear the old information from the table */
            that.oApi._fnClearTable( oSettings );

            /* Got the data - add it to the table */
            var aData =  (oSettings.sAjaxDataProp !== "") ?
                that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json;

            for ( var i=0 ; i<aData.length ; i++ )
            {
                that.oApi._fnAddData( oSettings, aData[i] );
            }

            oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
            that.fnDraw();

            if ( typeof bStandingRedraw != 'undefined' && bStandingRedraw === true )
            {
                oSettings._iDisplayStart = iStart;
                that.fnDraw( false );
            }

            that.oApi._fnProcessingDisplay( oSettings, false );

            /* Callback user function - for event handlers etc */
            if ( typeof fnCallback == 'function' && fnCallback != null )
            {
                fnCallback( oSettings );
            }
        }, oSettings );
    }


    $(document).ready(function() {

        var oTable = $('#example').dataTable( {
            "sPaginationType": "full_numbers",
            "iDisplayLength": 10,
            //"bServerSide": true,
            "sAjaxSource": "process.php"
        });

        $("#btnSubmit").click(function(){
            oTable.fnReloadAjax("process.php?txtId=" + $("txtId").val());
        });

    } );

Comments

1

It looks like you should also specify fnServerData when you setup your datable, if you want to use ajax POST: http://datatables.net/ref#fnServerData

It's also possible that you don't need to call fnReloadAjax(), but only fnDraw(). fnReloadAjax() is a plugin function, so I assume you did previously load it.

4 Comments

It seems that I didn't load the fnReloadAjax() plugin. I copied/pasted plugin's code at the beggining of my JQuery script but nothing happend. I'll try again as well as I'll give a try to fnServerData. Thanks Stefan!
At last, I found the solution! There were 2 problems in my JQuery code. First, I had to add the fnReloadAjax() code after the <script>...</script> tags which loads datatables and before the $(document).ready() statement. Second, I had to alter the JQuery code of my submit button (no need for an AJAX call, only fnReloadAjax() is necessary). Thanks again, Stefan. Nice work!!
@dimmat: You are welcome. So in addition to not needing to call .ajax(), are you saying that you didn't need to specify fnServerData either? (In which case GET is used to automatically pass your 'txtId' parameter to your script). Also, I found mbeasley's answer to be very illuminating and maybe it should be the accepted answer instead.
Yes, indeed. fnServerData is not necessary!! :-) I also believed that mbeasley's answer will work. But nothing happened with his code... I forgot to mention that I used fnReloadAjax like this: $("#btnSubmit").click(function(){ oTable.fnReloadAjax("process.php?txtId=" + $("txtId").val()); });
0

You could alternatively just destroy the table and recreate it too.

var oTable = null;

function reloadTable() {
    if (oTable) {
        oTable.fnDestroy();
    }

    oTable = $('#example').dataTable( {
        "sPaginationType": "full_numbers",
        "iDisplayLength": 10,
        //"bServerSide": true,
        "sAjaxSource": "process.php"
    } );
}

reloadTable();

Comments

0

you can use.

otable.ajax.reload()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.