web-dev-qa-db-fra.com

Comment puis-je obtenir que jQuery DataTables trie les valeurs cachées mais recherche les valeurs affichées?

J'ai une grille DataTables simple qui contient des colonnes de date. J'ai fourni deux valeurs pour la date dans mon ensemble de données JSON, une pour l'affichage et l'autre spécialement conçue pour que DataTables puisse la trier. Mon application Web permet aux utilisateurs de choisir différents formats de date. Elle doit donc être flexible.

Voici mes données JSON que DataTables obtient du serveur Web via sAjaxSource.

{
  Reports : [
    { Date: { Sort = "20101131133000", Display : "11/31/2010 1:30 PM" } }, 
    { Date: { Sort = "20100912120000", Display : "1200 EST 2010-09-12" } }, 
  ]
}

Il est facile de dire à DataTables de trier en fonction de la propriété Date.SortValue et de rendre la propriété Display visible pour l'utilisateur à l'aide de fnRender(). Donc, cela me mène à mi-chemin de mon objectif.

var dataTableConfig = {
  sAjaxSource: "/getreports",
  sAjaxDataProp: "Reports",
  aoColumns: [
    { mDataProp: "User" },
    { mDataProp: "Date.Sort", 
      bSortable: true, 
      sName: "Date", 
      bUseRendered: false, 
      fnRender: function (oObj) {
        return oObj.aData[oObj.oSettings.aoColumns[oObj.iDataColumn].sName].Display;
      }
    }
  ]
};

Voici mon problème.Je souhaite autoriser l'utilisateur à entrer un filtre (à l'aide de l'entrée de filtre intégrée fournie par DataTables) en fonction de la valeur affichée, mais ce n'est pas le cas.

Par exemple. Si un utilisateur saisissait "EST", il n'aurait aucun résultat, car les filtres de tables de données étaient basés sur la valeur spécifiée dans mDataProp et non sur la valeur renvoyée par fnRender.

Quelqu'un peut-il m'aider à comprendre comment trier ET filtrer une colonne de date? Merci.

30
jessegavin

Ceci est un ancien post, mais j'espère que cela aidera quelqu'un d'autre qui vient ici.

Dans une version plus récente de DataTables, bUseRendered et fnRender sont obsolètes.

mRender est la nouvelle façon de faire ce genre de chose et a une approche légèrement différente.

Vous pouvez résoudre votre problème avec quelque chose comme:

...
{ mDataProp: "Date.Sort"
  bSortable: true, 
  sName: "Date", 
  // this will return the Display value for everything
  // except for when it's used for sorting,
  // which then it will use the Sort value
  mRender: function (data, type, full) {
    if(type == 'sort') return data.Sort;
    return data.Display
  }
}
...
17
CWSpear

Je crois que les réponses existantes sont obsolètes à cause des mises à jour de DataTables. HTML5 prend en charge les attributs que DataTables peut utiliser pour facilement trier les colonnes. Spécifiquement l'attribut data-sort. (Voir https://datatables.net/examples/advanced_init/html5-data-attributes.html )

Je peux facilement trier les tables comme suit:

<table>
  <thead>
    <tr>
      <td>Name</td>
      <td>Age</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Doe</td>
      <td data-sort="37">2/1/78 (37 years old)</td>
    </tr>
    <tr>
      <td>Jane Doe</td>
      <td data-sort="35">12/1/80 (35 years old)</td>
    </tr>
  </tbody>
</table>

Peu importe que la colonne 'Age' contienne des nombres, des symboles et des lettres, DataTables triera en utilisant l'attribut 'data-sort'.

59
Aaron C. de Bruyn

Essayez une approche un peu différente:

Mettez les deux colonnes dans la table (je les appellerai DateDisplay et DateSort), n'utilisez pas la fonction de rendu et masquez simplement la colonne DateSort. Ensuite, dans le tableau aoColumns de la colonne DateDisplay, mettez { "iDataSort": 2 }, où 2 est un index de la colonne DateSort.

Dans ce cas, la colonne DateDisplay sera affichée dans les données d'origine et le filtre sera filtré à l'aide de cette colonne, mais le tri sera effectué en fonction des valeurs de la colonne DateSort.

Il y a plus de détails sur la propriété iDataSort sur le site datatables ou dans la http://www.codeproject.com/KB/scripting/JQuery-DataTables.aspx section "Configurer le tri".

20
Jovan MSFT

Umm ... au lieu de passer par tout ce rigolage, ajoutez simplement une span cachée avec votre "Trier par" à l'avant:

<td><span style="display:none;">20101131133000</span>11/31/2010 1:30 PM</td>

Note : Cela signifie qu'ils peuvent rechercher par la valeur cachée ou montrée ... cela peut être une conséquence avec laquelle vous ne pouvez pas vivre.

13
Serj Sagan

+1 JocaPC

J'aimerais ajouter à la réponse de JocaPC en rappelant à tout le monde que javascript utilise des tableaux sans index. 

Exemple:

 HiddenSortString (0) | Date (1) | Un peu de texte (2) 
.......................................... .........................
 1349035566 | 30 septembre 2012 14h06 | bla bla 
 1349118137 | 01 octobre 2012 13h02 | bla bla 
 1349371297 | 04 octobre 2012 11h21 | bla bla 
............................................. ......................

Pour trier le champ de date à l'aide de la chaîne masquée, vous devez utiliser ce qui suit.

$('.mytable').dataTable({
    "aoColumns": [{"bVisible": false},{"iDataSort": 0},null]
});
11
Brian

Puisque vous avez déjà vos données dans un format triable et affichable, tout ce dont vous avez besoin est du code.

Il utilisera Date.Sort pour le tri et Date.Display pour les éléments visuels. Ceci est documenté ici .

columns: [{
    data: 'Date',
    render: {
        _:   'Display',
        sort: 'Sort'
    }
}]
2
Martin Wickman

Vous devez trier la colonne par une colonne cachée (Trier). Pour cela, vous devez inclure une colonne contenant les données de tri, masquer la colonne et trier la colonne d'affichage en fonction de la colonne masquée. 

   "aoColumnDefs:[
    {"sTitle": "Display", "iDataSort":1, "aTargets":[2]},
    {"bVisible": false, "aTargets":[2]}
    ], 

aoColumns: [
    { mData: "User" },
    { mData: "Display"},
    { mData: "Sort"}
  ]
0
user3114969

Pour ceux qui utilisent une source de données ajax, vous pouvez utiliser Données orthogonales. Par exemple, dans votre réponse ajax, renvoyez l'une de vos colonnes sous forme d'objet avec une valeur d'affichage et une valeur de tri (similaire à ce que l'OP a fait):

{
   "data":[
      {
         "customer":"JOHN DOE",
         "rating":{
            "display": "★★★",
            "sort":"3"
         },
      },
      {
         "customer":"BILLY NOAH",
         "rating":{
            "display": "★★★★★",
            "sort":"5"
         },
      }
   ]
}

Maintenant, dans vos options de table, vous pouvez utiliser columns() comme ceci:

"columns" : [
   {
      "data":"customer"
   },
   {
      "data":"rating",
      "render":{
         "_":"display",
         "sort":"sort"
      }
   }
]
0
billynoah