Skip to content

Instantly share code, notes, and snippets.

@JoeHetfield
Last active December 21, 2015 02:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoeHetfield/6239004 to your computer and use it in GitHub Desktop.
Save JoeHetfield/6239004 to your computer and use it in GitHub Desktop.
This is data source for fuelux's datagrid, which support nested property. property could nested in many level, until property path hit null or undefined, then the result will be "null" or "undefined". could be useful, I think.
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['underscore'], factory);
} else {
root.NestedDataSource = factory();
}
}(this, function () {
var NestedDataSource = function (options) {
this._formatter = options.formatter;
this._columns = options.columns;
this._delay = options.delay || 0;
this._data = options.data;
var self = this;
// all tricks are here, the rest are completely the same as StaticDataSource
// check every column
$.each(this._columns, function(index, column) {
// split column property by dot
var pros = column.property.split('.');
// if splited array length bigger than 1, we found column that point to a nested property
if (pros.length > 1) {
// here we give all data a 'flat' property
$.each(self._data, function(index, row) {
// setup a tick start from 1 (the property name after the first dot)
var tick = 1;
// here we actually get the nested object
var result = row[pros[0]];
// loop through the nested object, until we hit null or undefined
while (result && tick < pros.length) {
result = result[pros[tick]];
tick++;
}
// set the value of 'flat' property
row[column.property] = result;
});
}
});
};
NestedDataSource.prototype = {
columns: function () {
return this._columns;
},
data: function (options, callback) {
var self = this;
setTimeout(function () {
var data = $.extend(true, [], self._data);
// SEARCHING
if (options.search) {
data = _.filter(data, function (item) {
var match = false;
_.each(item, function (prop) {
if (_.isString(prop) || _.isFinite(prop)) {
if (prop.toString().toLowerCase().indexOf(options.search.toLowerCase()) !== -1) match = true;
}
});
return match;
});
}
// FILTERING
if (options.filter) {
data = _.filter(data, function (item) {
switch(options.filter.value) {
case 'lt5m':
if(item.population < 5000000) return true;
break;
case 'gte5m':
if(item.population >= 5000000) return true;
break;
default:
return true;
break;
}
});
}
var count = data.length;
// SORTING
if (options.sortProperty) {
data = _.sortBy(data, options.sortProperty);
if (options.sortDirection === 'desc') data.reverse();
}
// PAGING
var startIndex = options.pageIndex * options.pageSize;
var endIndex = startIndex + options.pageSize;
var end = (endIndex > count) ? count : endIndex;
var pages = Math.ceil(count / options.pageSize);
var page = options.pageIndex + 1;
var start = startIndex + 1;
data = data.slice(startIndex, endIndex);
if (self._formatter) self._formatter(data);
callback({ data: data, start: start, end: end, count: count, pages: pages, page: page });
}, this._delay)
}
};
return NestedDataSource;
}));
// usage
// say I have a "me" object:
// {
// name: "JoeHetfield",
// age: 39,
// pet: {
// name: "Back Jack",
// age: 5
// }
// }
// then I can use datagrid like this:
// INITIALIZING THE DATAGRID
var dataSource = new StaticDataSource({
columns: [
{
property: 'name',
label: 'My Name',
sortable: true
},
{
property: 'age',
label: 'My Age',
sortable: true
},
{
property: 'pet.name',
label: 'Pet Name',
sortable: true
},
{
property: 'pet.age',
label: 'Pet Age',
sortable: true
}
],
data: dataOfPersonAndTheirPet,
delay: 250
});
$('#MyGrid').datagrid({
dataSource: dataSource,
stretchHeight: true
});
@urbanusjam
Copy link

Hi! I'm trying to use this implementation with an ajax function that loads the data but I can't make it work. It fails right at the beginning of the iteration ( $.each(this._columns, function(index, column)... ). The stack strace says my data array is "undefined". Without your nested property code, ajax works fine. Do you have any other example or advice that may be helpful to me? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment