web-dev-qa-db-fra.com

comment puis-je déclencher jquery datatables fnServerData pour mettre à jour une table via AJAX quand je clique sur un bouton?

J'utilise le plugin datatables avec des données côté serveur et je mets à jour la table en utilisant AJAX.

Ma configuration de dataTables ressemble à ceci:

tblOrders = parameters.table.dataTable( {
    "sDom": '<"S"f>t<"E"lp>',
    "sAjaxSource": "../file.cfc",
    "bServerSide": true,
    "sPaginationType": "full_numbers",  
    "bPaginate": true,
    "bRetrieve": true,
    "bLengthChange": false,         
    "bAutoWidth": false,
    "aaSorting": [[ 10, "desc" ]],      
    "aoColumns": [                      
        ... columns 
                  ],
    "fnInitComplete": function(oSettings, json) {
        // trying to listen for updates
        $(window).on('repaint_orders', function(){
            $('.tbl_orders').fnServerData( sSource, aoData, fnCallback, oSettings );
            });
        },
    "fnServerData": function ( sSource, aoData, fnCallback, oSettings ) {
        var page = $(oSettings.nTable).closest('div:jqmData(wrapper="true")')
        aoData.Push(
            { "name": "returnformat", "value": "plain"},
            { "name": "s_status", "value": page.find('input[name="s_status"]').val() },
            { "name": "s_bestellnr", "value": page.find('input[name="s_bestellnr"]').val() },
            { "name": "form_submitted", "value": "dynaTable" }
            );
        $.ajax({ "dataType": 'json', "type": "POST", "url": sSource, "data": aoData , "success": fnCallback });
        }

J'ai des champs personnalisés pour filtrer les données côté serveur, que je pousse avec la demande AJAX. Le problème est que je ne sais pas comment déclencher une demande JSON en dehors de la table. Si l'utilisateur tape dans le filtre, fnServerData est déclenché et met à jour la table. Cependant, si l'utilisateur choisit un contrôle en dehors de la table, je ne sais pas comment déclencher la fonction fnServerData .

En ce moment, j'essaie avec un événement personnalisé que je déclenche et que j'écoute dans fnInitComplete. Bien que je puisse détecter l'utilisateur qui sélectionne un critère de filtrage personnalisé, il me manque tous les paramètres nécessaires au bon déclenchement de fnServerData.

Question :
Existe-t-il un moyen de déclencher fnServerData à partir d'un bouton situé en dehors de la table dataTables réelle?

Je suppose que je pourrais essayer d'ajouter un espace au filtre, mais ce n'est pas vraiment une option.

Merci pour votre contribution!

Question

18
frequent

J'ai trouvé ce script il y a quelque temps (donc je ne me souviens pas d'où il vient :( et à qui le créditer: '() mais ici:

$.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);
}

Ajoutez celaAVANTvous appelez la fonction d'initialisation datatable. alors vous pouvez simplement appeler le rechargement comme ceci:

$("#userFilter").on("change", function () {
        oTable.fnReloadAjax(); // In your case this would be 'tblOrders.fnReloadAjax();'
    });

userFilter est un identifiant pour une liste déroulante. Ainsi, lorsqu'il change, il recharge les données de la table. Je viens d'ajouter ceci à titre d'exemple, mais vous pouvez le déclencher pour n'importe quel événement.

11
Drakkainen

D'après une discussion ici , Allan (le responsable des DataTables) suggère d'appeler simplement fnDraw pour obtenir les résultats escomptés. C’est la méthode que j’utilise pour recharger les ressources côté serveur (via fnServerData, ce qui est important), et cela a fonctionné jusqu’à présent.

$("#userFilter").on("change", function() {
    oTable.fnDraw();  // In your case this would be 'tblOrders.fnDraw();'
});
18
Chuck

Toutes les solutions mentionnées ci-dessus ont un problème (par exemple, les paramètres supplémentaires d'utilisateur http ne sont pas publiés ou sont périmés). Je suis donc venu avec la solution suivante qui fonctionne bien.

Fonction d'extension (Mes paramètres sont un tableau de paires de valeurs clés)

<pre>
$.fn.dataTableExt.oApi.fnReloadAjax = function (oSettings, sNewSource, myParams ) {
if ( oSettings.oFeatures.bServerSide ) {
    oSettings.aoServerParams = [];
    oSettings.aoServerParams.Push({"sName": "user",
        "fn": function (aoData) {
            for (var i=0;i<myParams.length;i++){
            aoData.Push( {"name" : myParams[i][0], "value" : myParams[i][1]});
         }
     }});
     this.fnClearTable(oSettings);
     this.fnDraw();
     return;
    }
};
</pre>

Exemple d'utilisation pour mettre à jour votre écouteur d'événements.

<pre>
oTable.fnReloadAjax(oTable.oSettings, supplier, val);
</pre>

Juste une chose à faire attention. Ne redessinez pas la table, une fois créée, cela prend du temps. Veillez donc à ne le dessiner que la première fois. Sinon, rechargez-le

<pre>
var oTable;
if (oTable == null) {
    oTable = $(".items").dataTable(/* your inti stuff here */); {
}else{
    oTable.fnReloadAjax(oTable.oSettings, supplier, val);
}
</pre>
4
Mitja Gustin

Je sais que c'est tard dans le jeu, mais fnDraw (de cette réponse ci-dessus - qui devrait être la réponse acceptée), est obsolète à partir de v1.10

La nouvelle méthode est:

this.api( true ).draw( true );

Qui, BTW, a un commentaire qui se lit comme suit:

// Note that this isn't an exact match to the old call to _fnDraw - it takes
// into account the new data, but can hold position.
1
cale_b

Dans l'initialisation, utilisez:

"fnServerData": function ( sSource, aoData, fnCallback ) {
                    //* Add some extra data to the sender *
                    newData = aoData;
                    newData.Push({ "name": "key", "value": $('#value').val() });

                    $.getJSON( sSource, newData, function (json) {
                        //* Do whatever additional processing you want on the callback, then tell DataTables *
                        fnCallback(json);
                    } );
                },

Et puis juste utiliser:

$("#table_id").dataTable().fnDraw();

La chose importante dans le fnServerData est:

    newData = aoData;
    newData.Push({ "name": "key", "value": $('#value').val() });

si vous appuyez directement sur aoData, la modification est permanente la première fois et lorsque vous redessinez la table, le fnDraw ne fonctionne pas comme vous le souhaitez. Utilisez donc une copie de aoData pour envoyer des données à l'ajax.

1
laromicas

Pour recharger les données, vous devez simplement sélectionner le DataTable à l'aide du sélecteur jquery avec la fonction DataTable() et appeler la fonction _fnAjaxUpdate.

Voici un exemple:

$('#exampleDataTable').DataTable()._fnAjaxUpdate();
0
raBne

Similaire à la réponse de Mitja Gustin. Modification d'une boucle, ajout de sNewSource.

$.fn.dataTableExt.oApi.fnReloadAjax = function (oSettings, sNewSource, myParams ) {
    if(oSettings.oFeatures.bServerSide) {
        if ( typeof sNewSource != 'undefined' && sNewSource != null ) {
            oSettings.sAjaxSource = sNewSource;
        }
        oSettings.aoServerParams = [];
        oSettings.aoServerParams.Push({"sName": "user",
            "fn": function (aoData) {
                for(var index in myParams) {
                    aoData.Push( { "name" : index, "value" : myParams[index] });
                }
            }
        });
        this.fnClearTable(oSettings);
        return;
    }
};

var myArray = {
    "key1": "value1",
    "key2": "value2"
};

var oTable = $("#myTable").dataTable();
oTable.fnReloadAjax(oTable.oSettings, myArray);
0
Tomasz Majerski