pagination, search, and sort now working in datatables views
authorScott Baker <smbaker@gmail.com>
Fri, 12 Dec 2014 07:08:31 +0000 (23:08 -0800)
committerScott Baker <smbaker@gmail.com>
Fri, 12 Dec 2014 07:08:31 +0000 (23:08 -0800)
planetstack/core/xoslib/static/js/xoslib/xos-backbone.js
planetstack/core/xoslib/static/js/xoslib/xosHelper.js

index 1303633..551ee80 100644 (file)
@@ -335,7 +335,7 @@ if (! window.XOSLIB_LOADED ) {
 
         for (key in attrs) {
             value = attrs[key];
-            if ($.inArray(key, ["urlRoot", "modelName", "collectionName", "listFields", "addFields", "detailFields", "foreignFields", "inputType", "relatedCollections", "foreignCollections"])>=0) {
+            if ($.inArray(key, ["urlRoot", "modelName", "collectionName", "listFields", "addFields", "detailFields", "detailLinkFields", "foreignFields", "inputType", "relatedCollections", "foreignCollections"])>=0) {
                 modelAttrs[key] = value;
                 collectionAttrs[key] = value;
             }
index b7cfc58..5e4b1cc 100644 (file)
@@ -748,33 +748,58 @@ XOSDataTableView = Marionette.View.extend( {
     render: function() {
         var view = this;
 
-        view.aoColumns = [];
+        view.columnsByIndex = [];
+        view.columnsByFieldName = {};
         _.each(this.collection.listFields, function(fieldName) {
             mRender = undefined;
+            mSearchText = undefined;
             if (fieldName in view.collection.foreignFields) {
                 var foreignCollection = view.collection.foreignFields[fieldName];
-                mRender = function(x) { return idToName(x, foreignCollection, "humanReadableName"); };
-            } else if ($.inArray(fieldName, view.collection.detailLinkFields)>=0) {
+                mSearchText = function(x) { return idToName(x, foreignCollection, "humanReadableName"); };
+            }
+            if ($.inArray(fieldName, view.collection.detailLinkFields)>=0) {
                 var collectionName = view.collection.collectionName;
                 mRender = function(x,y,z) { return '<a href="#' + collectionName + '/' + z.id + '">' + x + '</a>'; };
             }
-            view.aoColumns.push( {sTitle: fieldNameToHumanReadable(fieldName), mData: fieldName, mRender: mRender} );
+            thisColumn = {sTitle: fieldNameToHumanReadable(fieldName), mData: fieldName, mRender: mRender, mSearchText: mSearchText};
+            view.columnsByIndex.push( thisColumn );
+            view.columnsByFieldName[fieldName] = thisColumn;
         });
 
         oTable = $(this.el).find("table").dataTable( {
             "bJQueryUI": true,
             "bStateSave": true,
             "bServerSide": true,
-            "aoColumns": view.aoColumns,
+            "aoColumns": view.columnsByIndex,
 
             fnServerData: function(sSource, aoData, fnCallback, settings) {
                 var compareColumns = function(sortCols, sortDirs, a, b) {
-                    result = a[sortCols[0]] < b[sortCols[0]];
+                    a = a[sortCols[0]];
+                    b = b[sortCols[0]];
+                    result = (a==b) ? 0 : ((a<b) ? -1 : 1);
                     if (sortDirs[0] == "desc") {
                         result = -result;
                     }
                     return result;
                 };
+
+                var searchMatch = function(row, sSearch) {
+                    for (fieldName in row) {
+                        if (fieldName in view.columnsByFieldName) {
+                            try {
+                                value = row[fieldName].toString();
+                            } catch(e) {
+                                continue;
+                            }
+                            if (value.indexOf(sSearch) >= 0) {
+                                return true;
+                            }
+                        }
+                    }
+                    return false;
+                };
+
+                console.log(aoData);
 \r
                 // function used to populate the DataTable with the current\r
                 // content of the collection\r
@@ -783,27 +808,59 @@ XOSDataTableView = Marionette.View.extend( {
                   // clear out old row views\r
                   rows = [];\r
 \r
+                  sSearch = null;\r
+                  iDisplayStart = 0;\r
+                  iDisplayLength = 1000;\r
                   sortDirs = [];\r
                   sortCols = [];\r
                   _.each(aoData, function(param) {\r
                       if (param.name == "sSortDir_0") {\r
                           sortDirs = [param.value];\r
                       } else if (param.name == "iSortCol_0") {\r
-                          sortCols = [view.aoColumns[param.value].mData];\r
+                          sortCols = [view.columnsByIndex[param.value].mData];\r
+                      } else if (param.name == "iDisplayStart") {\r
+                          iDisplayStart = param.value;\r
+                      } else if (param.name == "iDisplayLength") {\r
+                          iDisplayLength = param.value;\r
+                      } else if (param.name == "sSearch") {\r
+                          sSearch = param.value;\r
                       }\r
                   });\r
 \r
                   aaData = view.collection.toJSON();\r
 \r
+                  // apply backbone filtering on the models\r
                   if (view.filter) {\r
                       aaData = aaData.filter( function(row) { model = {}; model.attributes = row; return view.filter(model); } );\r
                   }\r
 \r
+                  var totalSize = aaData.length;\r
+\r
+                  // turn the ForeignKey fields into human readable things\r
+                  for (rowIndex in aaData) {\r
+                      row = aaData[rowIndex];\r
+                      for (fieldName in row) {\r
+                          if (fieldName in view.columnsByFieldName) {\r
+                              mSearchText = view.columnsByFieldName[fieldName].mSearchText;\r
+                              if (mSearchText) {\r
+                                  row[fieldName] = mSearchText(row[fieldName]);\r
+                              }\r
+                          }\r
+                      }\r
+                  }\r
+\r
+                  // apply datatables search\r
+                  if (sSearch) {\r
+                      aaData = aaData.filter( function(row) { return searchMatch(row, sSearch); });\r
+                  }\r
+\r
+                  var filteredSize = aaData.length;\r
+\r
+                  // apply datatables sort\r
                   aaData.sort(function(a,b) { return compareColumns(sortCols, sortDirs, a, b); });\r
 \r
-                  // these 'meta' attributes are set by the collection's parse method\r
-                  var totalSize = view.collection.length;\r
-                  var filteredSize = view.collection.length;\r
+                  // slice it for pagination\r
+                  aaData = aaData.slice(iDisplayStart, iDisplayStart+iDisplayLength);\r
 \r
                   return fnCallback({iTotalRecords: totalSize,\r
                          iTotalDisplayRecords: filteredSize,\r