Comment modifiez-vous les données renvoyées par un appel AJAX avant leur affichage dans jqGrid?

Contexte

J’ai repris un travail incomplet d’un autre développeur qui implique l’affichage des résultats d’une recherche. Son approche consistait à rendre les résultats dans un tableau HTML en utilisant Javascript et jQuery inline comme suit.

Grille utilisant la table et le Javascript intégré

J’essaie d’achever le travail, mais je préférerais écrire moins de code et utiliser jqGrid, car il inclut une fonctionnalité de sorting et un code plus ordonné. Obtenir le jqGrid pour afficher les résultats est facile, mais il est plus difficile de placer les boutons radio dans une colonne vide que je ne le pensais.

La version de jqGrid dans l’application est 3.7.2. La grid doit avoir des boutons radio à gauche pour la sélection afin que les éléments soient cohérents avec le rest de l’application.

Où je suis coincé

Il ne semble pas y avoir de moyen d’avoir une colonne non liée dans jqGrid. C’est-à-dire que chaque colonne semble avoir besoin d’un champ dans les données sous-jacentes. Si vous n’avez pas de champ factice, les données de la ligne et les en-têtes de colonne sont mal alignés.

J’ai rencontré un exemple (voir Modification de ligne -> Modification personnalisée) qui renvoie JSON avec un champ factice dans les données, puis modifie les données de grid pour insérer des boutons.

Ma préférence est de ne pas inclure les données factices, car cela semble sale :). J’aimerais que mon JSON n’inclue que les données dont il a besoin pour représenter les résultats de la recherche. Je pensais donc qu’il serait préférable d’append le champ factice dans le code du script afin de garder le code propre côté serveur.

J’essaie de modifier les données renvoyées par l’appel AJAX avant que jqGrid ne les rende. J’ai essayé de me loadComplete événement loadComplete , mais lorsque je modifie les données, celles-ci semblent être postérieures au rendu.

J’ai également essayé de me ajaxGridOptions l’événement success sur le champ d’ options ajaxGridOptions mais cela semble annuler totalement l’événement et jqGrid ne restitue pas les données.

Comment modifier les données renvoyées par un appel de service Web avant que jqGrid ne les rende?

J’ai réussi à comprendre comment le faire. Plutôt que de laisser jqGrid charger les données automatiquement, il est nécessaire d’effectuer manuellement la demande, puis de la charger via un appel à addJSONData .

Mon jqGrid est défini dans le balisage comme suit:

 

J’initialise la grid avec le code suivant:

 // Initialize the grid this._searchResults = this._dialog.find("#eventSearchDialog-results"); this._searchResults.jqGrid( { datatype: "local", colNames: ['', 'Event Name', 'Event Type', 'Start Date', 'End Date', 'Location', 'Event Country', 'Sports'], colModel: [ { name: 'selector', index: 'selector', width: 30 }, { name: 'EventName', index: 'EventName', formatter: jqgridCellFormatter, width: 150 }, { name: 'EventType', index: 'EventType', formatter: jqgridCellFormatter, width: 120 }, { name: 'StartDate', index: 'StartDate', formatter: jqgridCellFormatter, width: 100 }, { name: 'EndDate', index: 'EndDate', formatter: jqgridCellFormatter, width: 100 }, { name: 'Location', index: 'Location', formatter: jqgridCellFormatter, width: 100 }, { name: 'EventCountry', index: 'EventCountry', formatter: jqgridCellFormatter, width: 100 }, { name: 'Sports', index: 'Sports', formatter: jqgridCellFormatter } ], rowNum: 10, rowList: [10, 20, 30], pager: this._dialog.find("#eventSearchDialog-pager"), pginput: true, sortname: 'EventName', viewrecords: true, sortorder: "asc", hidegrid: false, height: "auto", shrinkToFit: true, width: 630, jsonReader: { page: "pageIndex", total: "pageCount", records: "recordCount", root: "rows", repeatitems: true }, prmNames: { page: "pageIndex", rows: "pageSize", sort: "sortField", order: "sortOrder" } } ); // Set the data type to JSON, we don't do this in the options because it will cause a request to occur, // but we do need it to be set to JSON so that the calls to addJSONData work later. this._searchResults.jqGrid("setGridParam", { datatype: "json" }); 

Je charge la grid avec les données d’un appel jQuery $.ajax() et, dans le gestionnaire d’événements de success , je complète les données, puis je les charge dans jqGrid à l’aide de addJSONData .

Mon JSON ressemble à ceci:

 { "pageCount":1, "pageIndex":1, "recordCount":2, "rows": [ {"id":3, "cell":["Stevens Event 2", "Commonwealth Games", "03/05/2011", "16/05/2011", "sersdfweqr", "New Zealand", ["Archery"]]}, {"id":4, "cell":["Test - multiple sports", "Other", "01/05/2011", "30/06/2011", "Kobe", "Japan", ["Judo", "Karate", "Motor Sport", "Motorcycling", "Taekwondo"]]} ] } 

Ceci est mon gestionnaire de success :

 success: function (data, textStatus, xhr) { // Pad data for our radio button column that has no corresponding field in the data for (var counter = 0; counter < data.rows.length; counter++) { data.rows[counter].cell.splice(0, 0, null); } thisEventSearchDialog._searchResults[0].addJSONData(data); thisEventSearchDialog._createRadioButtons(); }, 

JqGrid contenant la colonne de boutons radio pour lesquels les données factices étaient nécessaires. Sans les données factices, les données de ligne ne correspondaient pas aux en-têtes. entrez la description de l'image ici

La solution dans ma réponse précédente a cassé le sorting alors je suis venu avec une autre solution.

Comme jqGrid ne fournit pas les points d’ancrage permettant de modifier facilement les données, il était nécessaire de rétrograder un niveau et de se connecter à jQuery. J’ai remplacé la $.ajax() par la mienne. Tout d’abord, il vérifie s’il s’agit d’une opération lancée par jqGrid. Dans l’affirmative, il complète les données, appelle le gestionnaire de success jqGrid d’origine, puis ajoute les boutons d’option à la grid. Le sorting fonctionne toujours, le type de données est toujours JSON, et il n’y a aucun appel manuel à addJSONData et je suis toujours en mesure de réaliser ce dont j’avais besoin de la solution précédente. En gros, faire ce petit bidouillage jQuery me permet de me débrouiller sans faire de bidouilles jqGrid, ce qui est bien plus compliqué.

 // Set up $.ajax() hook for modifying the data before jqGrid receives it if (!this._ajaxOverridden) { var oldAjax = $.ajax; $.ajax = function (options) { // Check whether this call is from jqGrid to our web service if (options.url == config.eventSearchUrl && options.success) { // Wrap the success event handler with our own handler that pads the data and creates the radio buttons var oldSuccess = options.success; options.success = function () { thisEventSearchDialog._padData(arguments[0]); oldSuccess.apply(this, arguments); thisEventSearchDialog._createRadioButtons(); } } oldAjax(options); }; this._ajaxOverridden = true; } 

Cette question est ancienne et ne s’applique peut-être pas à la version de jqGrid mentionnée (3.7.2), mais elle semble être liée à ceci: J’ai raison (sur le fait d’être lié), alors la bonne réponse est le paramètre / fonction ajaxGridOption paramètre ajaxGridOption . Cela a fonctionné pour moi.