| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /**
- * This base class is used to handle data preparation (e.g., sorting, filtering and
- * group summary).
- */
- Ext.define('Ext.ux.ajax.DataSimlet', function () {
-
- function makeSortFn (def, cmp) {
- var order = def.direction,
- sign = (order && order.toUpperCase() === 'DESC') ? -1 : 1;
-
- return function (leftRec, rightRec) {
- var lhs = leftRec[def.property],
- rhs = rightRec[def.property],
- c = (lhs < rhs) ? -1 : ((rhs < lhs) ? 1 : 0);
-
- if (c || !cmp) {
- return c * sign;
- }
-
- return cmp(leftRec, rightRec);
- };
- }
-
- function makeSortFns (defs, cmp) {
- for (var sortFn = cmp, i = defs && defs.length; i; ) {
- sortFn = makeSortFn(defs[--i], sortFn);
- }
- return sortFn;
- }
-
- return {
- extend: 'Ext.ux.ajax.Simlet',
-
- buildNodes: function (node, path) {
- var me = this,
- nodeData = {
- data: []
- },
- len = node.length,
- children, i, child, name;
-
- me.nodes[path] = nodeData;
-
- for (i = 0; i < len; ++i) {
- nodeData.data.push(child = node[i]);
- name = child.text || child.title;
-
- child.id = path ? path + '/' + name : name;
- children = child.children;
-
- if (!(child.leaf = !children)) {
- delete child.children;
-
- me.buildNodes(children, child.id);
- }
- }
- },
-
- deleteRecord : function(pos) {
- if(this.data && typeof this.data !== 'function') {
- Ext.Array.removeAt(this.data,pos);
- }
- },
-
- fixTree: function (ctx, tree) {
- var me = this,
- node = ctx.params.node,
- nodes;
-
- if (!(nodes = me.nodes)) {
- me.nodes = nodes = {};
- me.buildNodes(tree, '');
- }
-
- node = nodes[node];
- if (node) {
- if (me.node) {
- me.node.sortedData = me.sortedData;
- me.node.currentOrder = me.currentOrder;
- }
-
- me.node = node;
- me.data = node.data;
- me.sortedData = node.sortedData;
- me.currentOrder = node.currentOrder;
- } else {
- me.data = null;
- }
- },
-
- getData: function (ctx) {
- var me = this,
- params = ctx.params,
- order = (params.filter || '') + (params.group || '') + '-' + (params.sort || '') + '-' + (params.dir || ''),
- tree = me.tree,
- dynamicData,
- data, fields, sortFn;
-
- if (tree) {
- me.fixTree(ctx, tree);
- }
-
- data = me.data;
- if (typeof data === 'function') {
- dynamicData = true;
- data = data.call(this, ctx);
- }
-
- // If order is '--' then it means we had no order passed, due to the string concat above
- if (!data || order === '--') {
- return data || [];
- }
-
- if (!dynamicData && order == me.currentOrder) {
- return me.sortedData;
- }
-
- ctx.filterSpec = params.filter && Ext.decode(params.filter);
- ctx.groupSpec = params.group && Ext.decode(params.group);
-
- fields = params.sort;
- if (params.dir) {
- fields = [{ direction: params.dir, property: fields }];
- } else {
- fields = Ext.decode(params.sort);
- }
-
- if (ctx.filterSpec) {
- var filters = new Ext.util.FilterCollection();
- filters.add(this.processFilters(ctx.filterSpec));
- data = Ext.Array.filter(data, filters.getFilterFn());
- }
-
- sortFn = makeSortFns((ctx.sortSpec = fields));
- if (ctx.groupSpec) {
- sortFn = makeSortFns([ctx.groupSpec], sortFn);
- }
-
- // If a straight Ajax request, data may not be an array.
- // If an Array, preserve 'physical' order of raw data...
- data = Ext.isArray(data) ? data.slice(0) : data;
- if (sortFn) {
- Ext.Array.sort(data, sortFn);
- }
-
- me.sortedData = data;
- me.currentOrder = order;
-
- return data;
- },
-
- processFilters: Ext.identityFn,
-
- getPage: function (ctx, data) {
- var ret = data,
- length = data.length,
- start = ctx.params.start || 0,
- end = ctx.params.limit ? Math.min(length, start + ctx.params.limit) : length;
-
- if (start || end < length) {
- ret = ret.slice(start, end);
- }
-
- return ret;
- },
-
- getGroupSummary: function (groupField, rows, ctx) {
- return rows[0];
- },
-
- getSummary: function (ctx, data, page) {
- var me = this,
- groupField = ctx.groupSpec.property,
- accum,
- todo = {},
- summary = [],
- fieldValue,
- lastFieldValue;
-
- Ext.each(page, function (rec) {
- fieldValue = rec[groupField];
- todo[fieldValue] = true;
- });
-
- function flush () {
- if (accum) {
- summary.push(me.getGroupSummary(groupField, accum, ctx));
- accum = null;
- }
- }
-
- // data is ordered primarily by the groupField, so one pass can pick up all
- // the summaries one at a time.
- Ext.each(data, function (rec) {
- fieldValue = rec[groupField];
-
- if (lastFieldValue !== fieldValue) {
- flush();
- lastFieldValue = fieldValue;
- }
-
- if (!todo[fieldValue]) {
- // if we have even 1 summary, we have summarized all that we need
- // (again because data and page are ordered by groupField)
- return !summary.length;
- }
-
- if (accum) {
- accum.push(rec);
- } else {
- accum = [rec];
- }
-
- return true;
- });
-
- flush(); // make sure that last pesky summary goes...
-
- return summary;
- }
- };
- }());
|