syncfusion-ember/common/ej.data.js

4063 строки
149 KiB
JavaScript

window.ej = window.Syncfusion = window.Syncfusion || {};
(function ($, ej, doc, undefined) {
'use strict';
ej.DataManager = function (dataSource, query, adaptor) {
if (!(this instanceof ej.DataManager))
return new ej.DataManager(dataSource, query, adaptor);
if (!dataSource)
dataSource = [];
adaptor = adaptor || dataSource.adaptor;
if (typeof (adaptor) === "string")
adaptor = new ej[adaptor]();
var data = [], self = this;
if (dataSource instanceof Array) {
// JSON array
data = {
json: dataSource,
offline: true
};
} else if (typeof dataSource === "object") {
if ($.isPlainObject(dataSource)) {
if (!dataSource.json)
dataSource.json = [];
if (dataSource.table)
dataSource.json = this._getJsonFromElement(dataSource.table, dataSource.headerOption);
data = {
url: dataSource.url,
insertUrl: dataSource.insertUrl,
removeUrl: dataSource.removeUrl,
updateUrl: dataSource.updateUrl,
crudUrl: dataSource.crudUrl,
batchUrl: dataSource.batchUrl,
json: dataSource.json,
headers: dataSource.headers,
accept: dataSource.accept,
data: dataSource.data,
async : dataSource.async,
timeTillExpiration: dataSource.timeTillExpiration,
cachingPageSize: dataSource.cachingPageSize,
enableCaching: dataSource.enableCaching,
requestType: dataSource.requestType,
key: dataSource.key,
crossDomain: dataSource.crossDomain,
antiForgery: dataSource.antiForgery,
jsonp: dataSource.jsonp,
dataType: dataSource.dataType,
enableAjaxCache: dataSource.enableAjaxCache,
offline: dataSource.offline !== undefined ? dataSource.offline : dataSource.adaptor == "remoteSaveAdaptor" || dataSource.adaptor instanceof ej.remoteSaveAdaptor ? false : dataSource.url ? false : true,
requiresFormat: dataSource.requiresFormat
};
} else if (dataSource.jquery || isHtmlElement(dataSource)) {
data = {
json: this._getJsonFromElement(dataSource),
offline: true,
table: dataSource
};
}
} else if (typeof dataSource === "string") {
data = {
url: dataSource,
offline: false,
dataType: "json",
json: []
};
}
if (data.requiresFormat === undefined && !ej.support.cors)
data.requiresFormat = isNull(data.crossDomain) ? true : data.crossDomain;
if(data.antiForgery){
this.antiForgeryToken();
}
if (data.dataType === undefined)
data.dataType = "json";
this.dataSource = data;
this.defaultQuery = query;
if (data.url && data.offline && !data.json.length) {
this.isDataAvailable = false;
this.adaptor = adaptor || new ej.ODataAdaptor();
this.dataSource.offline = false;
this.ready = this.executeQuery(query || ej.Query()).done(function (e) {
self.dataSource.offline = true;
self.isDataAvailable = true;
data.json = e.result;
self.adaptor = new ej.JsonAdaptor();
});
}
else
this.adaptor = data.offline ? new ej.JsonAdaptor() : new ej.ODataAdaptor();
if (!data.jsonp && this.adaptor instanceof ej.ODataAdaptor)
data.jsonp = "callback";
this.adaptor = adaptor || this.adaptor;
if (data.enableCaching)
this.adaptor = new ej.CacheAdaptor(this.adaptor, data.timeTillExpiration, data.cachingPageSize);
return this;
};
ej.DataManager.prototype = {
setDefaultQuery: function (query) {
this.defaultQuery = query;
},
executeQuery: function (query, done, fail, always) {
if (typeof query === "function") {
always = fail;
fail = done;
done = query;
query = null;
}
if (!query)
query = this.defaultQuery;
if (!(query instanceof ej.Query))
throwError("DataManager - executeQuery() : A query is required to execute");
var deffered = $.Deferred();
deffered.then(done, fail, always);
var args = { query: query };
if (!this.dataSource.offline && this.dataSource.url != undefined) {
var result = this.adaptor.processQuery(this, query);
if (!ej.isNullOrUndefined(result.url))
this._makeRequest(result, deffered, args, query);
else {
nextTick(function () {
args = this._getDeferedArgs(query, result, args);
deffered.resolveWith(this, [args]);;
}, this);
}
} else {
if(!ej.isNullOrUndefined(this.dataSource.async) && this.dataSource.async == false)
this._localQueryProcess(query, args, deffered);
else{
nextTick(function () {
this._localQueryProcess(query, args, deffered);
}, this);
}
}
return deffered.promise();
},
_localQueryProcess: function(query, args, deffered){
var res = this.executeLocal(query);
args = this._getDeferedArgs(query, res, args);
deffered.resolveWith(this, [args]);
},
_getDeferedArgs: function (query, result, args) {
if (query._requiresCount) {
args.result = result.result;
args.count = result.count;
} else
args.result = result;
args.getTableModel = getTableModel(query._fromTable, args.result, this);
args.getKnockoutModel = getKnockoutModel(args.result);
return args;
},
executeLocal: function (query) {
if (!this.defaultQuery && !(query instanceof ej.Query))
throwError("DataManager - executeLocal() : A query is required to execute");
if (!this.dataSource.json)
throwError("DataManager - executeLocal() : Json data is required to execute");
query = query || this.defaultQuery;
var result = this.adaptor.processQuery(this, query);
if (query._subQuery) {
var from = query._subQuery._fromTable, lookup = query._subQuery._lookup,
res = query._requiresCount ? result.result : result;
if (lookup && lookup instanceof Array) {
buildHierarchy(query._subQuery._fKey, from, res, lookup, query._subQuery._key);
}
for (var j = 0; j < res.length; j++) {
if (res[j][from] instanceof Array) {
res[j] = $.extend({}, res[j]);
res[j][from] = this.adaptor.processResponse(query._subQuery.using(ej.DataManager(res[j][from].slice(0))).executeLocal(), this, query);
}
}
}
return this.adaptor.processResponse(result, this, query);
},
_makeRequest: function (url, deffered, args, query) {
var isSelector = !!query._subQuerySelector;
var fnFail = $proxy(function (e) {
args.error = e;
deffered.rejectWith(this, [args]);
}, this);
var process = $proxy(function (data, count, xhr, request, actual, aggregates, virtualSelectRecords) {
if (isSelector) return;
args.xhr = xhr;
args.count = parseInt(count, 10);
args.result = data;
args.request = request;
args.aggregates = aggregates;
args.getTableModel = getTableModel(query._fromTable, data, this);
args.getKnockoutModel = getKnockoutModel(data);
args.actual = actual;
args.virtualSelectRecords = virtualSelectRecords;
deffered.resolveWith(this, [args]);
}, this);
var fnQueryChild = $proxy(function (data, selector) {
var subDeffer = $.Deferred(),
childArgs = { parent: args };
query._subQuery._isChild = true;
var subUrl = this.adaptor.processQuery(this, query._subQuery, data ? this.adaptor.processResponse(data) : selector);
var childReq = this._makeRequest(subUrl, subDeffer, childArgs, query._subQuery);
if(!isSelector)
subDeffer.then(function (subData) {
if (data) {
buildHierarchy(query._subQuery._fKey, query._subQuery._fromTable, data, subData, query._subQuery._key);
process(data);
}
}, fnFail);
return childReq;
}, this);
var fnSuccess = proxy(function (data, status, xhr, request) {
if (xhr.getResponseHeader("Content-Type").indexOf("xml") == -1 && ej.dateParse)
data = ej.parseJSON(data);
var result = this.adaptor.processResponse(data, this, query, xhr, request), count = 0, aggregates = null;
var virtualSelectRecords = data.virtualSelectRecords;
if (query._requiresCount) {
count = result.count;
aggregates = result.aggregates;
result = result.result;
}
if (!query._subQuery) {
process(result, count, xhr, request, data, aggregates, virtualSelectRecords);
return;
}
if (!isSelector)
fnQueryChild(result);
}, this);
var req = $.extend({
type: "GET",
dataType: this.dataSource.dataType,
crossDomain: this.dataSource.crossDomain,
jsonp: this.dataSource.jsonp,
cache: ej.isNullOrUndefined(this.dataSource.enableAjaxCache) ? true: this.dataSource.enableAjaxCache,
beforeSend: $proxy(this._beforeSend, this),
processData: false,
success: fnSuccess,
error: fnFail
}, url);
if ("async" in this.dataSource)
req.async = this.dataSource.async;
req = $.ajax(req);
if (isSelector) {
var res = query._subQuerySelector.call(this, { query: query._subQuery, parent: query });
if (res && res.length) {
req = $.when(req, fnQueryChild(null, res));
req.then(proxy(function (pData, cData, requests) {
var pResult = this.adaptor.processResponse(pData[0], this, query, pData[2], requests[0]), count = 0;
if (query._requiresCount) {
count = pResult.count;
pResult = pResult.result;
}
var cResult = this.adaptor.processResponse(cData[0], this, query._subQuery, cData[2], requests[1]), count = 0;
if (query._subQuery._requiresCount) {
count = cResult.count;
cResult = cResult.result;
}
buildHierarchy(query._subQuery._fKey, query._subQuery._fromTable, pResult, cResult, query._subQuery._key);
isSelector = false;
process(pResult, count, pData[2]);
}, this), fnFail);
} else {
isSelector = false;
}
}
return req;
},
_beforeSend: function (request, settings) {
this.adaptor.beforeSend(this, request, settings);
var headers = this.dataSource.headers, props;
for (var i = 0; headers && i < headers.length; i++) {
props = [];
for (var prop in headers[i]) {
props.push(prop);
request.setRequestHeader(prop, headers[i][prop]);
}
}
},
saveChanges: function (changes, key, tableName, query) {
if (tableName instanceof ej.Query) {
query = tableName;
tableName = null;
}
var args = {
url: tableName,
key: key || this.dataSource.key
};
var req = this.adaptor.batchRequest(this, changes, args, query);
if (this.dataSource.offline) {
return req;
}
var deff = $.Deferred();
$.ajax($.extend({
beforeSend: $proxy(this._beforeSend, this),
success: proxy(function (data, status, xhr, request) {
deff.resolveWith(this, [this.adaptor.processResponse(data, this, null, xhr, request, changes, key)]);
}, this),
error: function (e) {
deff.rejectWith(this, [{ error: e }]);
}
}, req));
return deff.promise();
},
insert: function (data, tableName, query) {
// Additional paramater is included based on the task (JS-56499) to prevent addition of serverOffset multiple times
data = p.replacer(data, true);
if (tableName instanceof ej.Query) {
query = tableName;
tableName = null;
}
var res = this.adaptor.insert(this, data, tableName, query);
if (this.dataSource.offline) {
return res;
}
var deffer = $.Deferred();
$.ajax($.extend({
type: "POST",
contentType: "application/json; charset=utf-8",
processData: false,
beforeSend: $proxy(this._beforeSend, this),
success: proxy(function (record, status, xhr, request) {
try {
if (ej.isNullOrUndefined(record))
record = [];
else
p.parseJson(record);
}
catch (e) {
record = [];
}
record = this.adaptor.processResponse(p.parseJson(record), this, null, xhr, request);
deffer.resolveWith(this, [{ record: record, dataManager: this }]);
}, this),
error: function (e) {
deffer.rejectWith(this, [{ error: e, dataManager: this }]);
}
}, res));
return deffer.promise();
},
antiForgeryToken: function () {
var tokens = {};
if(ej.isNullOrUndefined($("input[name='_ejRequestVerifyToken']").val()))
var input = ej.buildTag("input", "", "", { type: "hidden", name: "_ejRequestVerifyToken" , value: ej.getGuid()}).appendTo("body");
else
$("input[name='_ejRequestVerifyToken']").val(ej.getGuid());
ej.cookie.set("_ejRequestVerifyToken", $("input[name='_ejRequestVerifyToken']").val());
tokens ={name: "_ejRequestVerifyToken", value: $("input[name='_ejRequestVerifyToken']").val()}
return tokens;
},
remove: function (keyField, value, tableName, query) {
if (typeof value === "object")
value = value[keyField];
if (tableName instanceof ej.Query) {
query = tableName;
tableName = null;
}
var res = this.adaptor.remove(this, keyField, value, tableName, query);
if (this.dataSource.offline)
return res;
var deffer = $.Deferred();
$.ajax($.extend({
type: "POST",
contentType: "application/json; charset=utf-8",
beforeSend: $proxy(this._beforeSend, this),
success: proxy(function (record, status, xhr, request) {
try {
if (ej.isNullOrUndefined(record))
record = [];
else
p.parseJson(record);
}
catch (e) {
record = [];
}
record = this.adaptor.processResponse(p.parseJson(record), this, null, xhr, request);
deffer.resolveWith(this, [{ record: record, dataManager: this }]);
}, this),
error: function (e) {
deffer.rejectWith(this, [{ error: e, dataManager: this }]);
}
}, res));
return deffer.promise();
},
update: function (keyField, value, tableName, query) {
// Additional paramater is included based on this task (JS-56499) to prevent addition of serverOffset multiple times
value = p.replacer(value, true);
if (tableName instanceof ej.Query) {
query = tableName;
tableName = null;
}
var res = this.adaptor.update(this, keyField, value, tableName, query);
if (this.dataSource.offline) {
return res;
}
var deffer = $.Deferred();
$.ajax($.extend({
contentType: "application/json; charset=utf-8",
beforeSend: $proxy(this._beforeSend, this),
success: proxy(function (record, status, xhr, request) {
try {
if (ej.isNullOrUndefined(record))
record = [];
else
p.parseJson(record);
}
catch (e) {
record = [];
}
record = this.adaptor.processResponse(p.parseJson(record), this, null, xhr, request);
deffer.resolveWith(this, [{ record: record, dataManager: this }]);
}, this),
error: function (e) {
deffer.rejectWith(this, [{ error: e, dataManager: this }]);
}
}, res));
return deffer.promise();
},
_getJsonFromElement: function (ds) {
if (typeof (ds) == "string")
ds = $($(ds).html());
ds = ds.jquery ? ds[0] : ds;
var tagName = ds.tagName.toLowerCase();
if (tagName !== "table")
throwError("ej.DataManager : Unsupported htmlElement : " + tagName);
return ej.parseTable(ds);
}
};
var buildHierarchy = function (fKey, from, source, lookup, pKey) {
var i, grp = {}, t;
if (lookup.result) lookup = lookup.result;
if (lookup.GROUPGUID)
throwError("ej.DataManager: Do not have support Grouping in hierarchy");
for (i = 0; i < lookup.length; i++) {
var fKeyData = ej.getObject(fKey, lookup[i]);
t = grp[fKeyData] || (grp[fKeyData] = []);
t.push(lookup[i]);
}
for (i = 0; i < source.length; i++) {
source[i][from] = grp[ej.getObject(pKey || fKey, source[i])];
}
};
var oData = {
accept: "application/json;odata=light;q=1,application/json;odata=verbose;q=0.5",
multipartAccept: "multipart/mixed",
batch: "$batch",
changeSet: "--changeset_",
batchPre: "batch_",
contentId: "Content-Id: ",
batchContent: "Content-Type: multipart/mixed; boundary=",
changeSetContent: "Content-Type: application/http\nContent-Transfer-Encoding: binary ",
batchChangeSetContentType: "Content-Type: application/json; charset=utf-8 "
};
var p = {
parseJson: function (jsonText) {
var type = typeof jsonText;
if (type === "string") {
jsonText = JSON.parse(jsonText, p.jsonReviver);
} else if (jsonText instanceof Array) {
p.iterateAndReviveArray(jsonText);
} else if (type === "object")
p.iterateAndReviveJson(jsonText);
return jsonText;
},
iterateAndReviveArray: function (array) {
for (var i = 0; i < array.length; i++) {
if (typeof array[i] === "object")
p.iterateAndReviveJson(array[i]);
else if (typeof array[i] === "string" && !/^[\s]*\[|^[\s]*\{|\"/g.test(array[i]))
array[i] = p.jsonReviver("",array[i]);
else
array[i] = p.parseJson(array[i]);
}
},
iterateAndReviveJson: function (json) {
var value;
for (var prop in json) {
if (prop.startsWith("__"))
continue;
value = json[prop];
if (typeof value === "object") {
if (value instanceof Array)
p.iterateAndReviveArray(value);
else
p.iterateAndReviveJson(value);
} else
json[prop] = p.jsonReviver(prop, value);
}
},
jsonReviver: function (field, value) {
var s = value;
if (typeof value === "string") {
var ms = /^\/Date\(([+-]?[0-9]+)([+-][0-9]{4})?\)\/$/.exec(value);
if (ms)
return ej.parseDateInUTC ? p.isValidDate(ms[0]) : p.replacer(new Date(parseInt(ms[1])));
else if (/^(\d{4}\-\d\d\-\d\d)|(\d{4}\-\d\d\-\d\d([tT][\d:\.]*){1})([zZ]|([+\-])(\d\d):?(\d\d))?$/.test(value)) {
value = ej.parseDateInUTC ? p.isValidDate(value) : p.replacer(new Date(value));
if (isNaN(value)) {
var a = s.split(/[^0-9]/);
value = p.replacer(new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]));
}
}
}
return value;
},
isValidDate: function (value) {
var prop = value;
if (typeof (prop) === "string" && prop.indexOf("/Date(") == 0) {
value = prop.replace(/\d+/, function (n) {
var offsetMiliseconds = new Date(parseInt(n)).getTimezoneOffset() * 60000;
var ticks = parseInt(n) + offsetMiliseconds;
return p.replacer(new Date(parseInt(ticks)));
});
}
if (typeof value === "string") {
value = value.replace("/Date(", function () { return ""; });
value = value.replace(")/", function () { return ""; })
var ms = new Date(value) instanceof Date;
if (ms)
return new Date(value);
else return value;
}
return value;
},
isJson: function (jsonData) {
if(typeof jsonData[0]== "string")
return jsonData;
return ej.parseJSON(jsonData);
},
isGuid: function (value) {
var regex = /[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}/i;
var match = regex.exec(value);
return match != null;
},
// Additional paramater is included based on this task (JS-56499) to prevent addition of serverOffset multiple times
replacer: function (value, serverOffset) {
if (ej.isPlainObject(value))
return p.jsonReplacer(value, serverOffset);
if (value instanceof Array)
return p.arrayReplacer(value);
if (value instanceof Date)
return p.jsonReplacer({ val: value }, serverOffset).val;
return value;
},
jsonReplacer: function (val, serverOffset) {
var value;
for (var prop in val) {
value = val[prop];
if (!(value instanceof Date))
continue;
// checking for update and insert operation and then including the proper offset, based on this task (JS-56499)
var offset = ej.serverTimezoneOffset * 60 * 60 * 1000 * (ej.isNullOrUndefined(serverOffset) || (serverOffset === false) ? (1) : -(1));
val[prop] = new Date(+value + offset);
}
return val;
},
arrayReplacer: function (val) {
for (var i = 0; i < val.length; i++) {
if (ej.isPlainObject(val[i]))
val[i] = p.jsonReplacer(val[i]);
else if (val[i] instanceof Date)
val[i] = p.jsonReplacer({ date: val[i] }).date;
}
return val;
}
};
ej.isJSON = p.isJson;
ej.parseJSON = p.parseJson;
ej.dateParse = true;
ej.isGUID = p.isGuid;
ej.Query = function (from) {
if (!(this instanceof ej.Query))
return new ej.Query(from);
this.queries = [];
this._key = "";
this._fKey = "";
if (typeof from === "string")
this._fromTable = from || "";
else if (from && from instanceof Array)
this._lookup = from;
this._expands = [];
this._sortedColumns = [];
this._groupedColumns = [];
this._subQuery = null;
this._isChild = false;
this._params = [];
return this;
};
ej.Query.prototype = {
key: function (field) {
if (typeof field === "string")
this._key = field;
return this;
},
using: function (dataManager) {
if (dataManager instanceof ej.DataManager) {
this.dataManagar = dataManager;
return this;
}
return throwError("Query - using() : 'using' function should be called with parameter of instance ej.DataManager");
},
execute: function (dataManager, done, fail, always) {
dataManager = dataManager || this.dataManagar;
if (dataManager && dataManager instanceof ej.DataManager)
return dataManager.executeQuery(this, done, fail, always);
return throwError("Query - execute() : dataManager needs to be is set using 'using' function or should be passed as argument");
},
executeLocal: function (dataManager) {
// this does not support for URL binding
dataManager = dataManager || this.dataManagar;
if (dataManager && dataManager instanceof ej.DataManager)
return dataManager.executeLocal(this);
return throwError("Query - executeLocal() : dataManager needs to be is set using 'using' function or should be passed as argument");
},
clone: function () {
var cl = new ej.Query();
cl.queries = this.queries.slice(0);
cl._key = this._key;
cl._isChild = this._isChild;
cl.dataManagar = this.dataManager;
cl._fromTable = this._fromTable;
cl._params = this._params.slice(0);
cl._expands = this._expands.slice(0);
cl._sortedColumns = this._sortedColumns.slice(0);
cl._groupedColumns = this._groupedColumns.slice(0);
cl._subQuerySelector = this._subQuerySelector;
cl._subQuery = this._subQuery;
cl._fKey = this._fKey;
cl._requiresCount = this._requiresCount;
return cl;
},
from: function (tableName) {
if (typeof tableName === "string")
this._fromTable = tableName;
return this;
},
addParams: function (key, value) {
if (typeof value !== "function" && !ej.isPlainObject(value))
this._params.push({ key: key, value: value });
else if (typeof value === "function")
this._params.push({ key: key, fn: value });
return this;
},
expand: function (tables) {
if (typeof tables === "string")
this._expands = [].slice.call(arguments, 0);
else
this._expands = tables.slice(0);
return this;
},
where: function (fieldName, operator, value, ignoreCase) {
operator = (operator || ej.FilterOperators.equal).toLowerCase();
var predicate = null;
if (typeof fieldName === "string")
predicate = new ej.Predicate(fieldName, operator, value, ignoreCase);
else if (fieldName instanceof ej.Predicate)
predicate = fieldName;
else
throwError("Query - where : Invalid arguments");
this.queries.push({
fn: "onWhere",
e: predicate
});
return this;
},
search: function (searchKey, fieldNames, operator, ignoreCase) {
if (!fieldNames || typeof fieldNames === "boolean") {
fieldNames = [];
ignoreCase = fieldNames;
} else if (typeof fieldNames === "string")
fieldNames = [fieldNames];
if (typeof operator === "boolean") {
ignoreCase = operator;
operator = null;
}
operator = operator || ej.FilterOperators.contains;
if (operator.length < 3)
operator = ej.data.operatorSymbols[operator];
var comparer = ej.data.fnOperators[operator] || ej.data.fnOperators.processSymbols(operator);
this.queries.push({
fn: "onSearch",
e: {
fieldNames: fieldNames,
operator: operator,
searchKey: searchKey,
ignoreCase: ignoreCase,
comparer: comparer
}
});
return this;
},
sortBy: function (fieldName, comparer, isFromGroup) {
var order = ej.sortOrder.Ascending, sorts, t;
if (typeof fieldName === "string" && fieldName.toLowerCase().endsWith(" desc")) {
fieldName = fieldName.replace(/ desc$/i, '');
comparer = ej.sortOrder.Descending;
}
if (fieldName instanceof Array) {
for(var i=0;i<fieldName.length;i++)
this.sortBy(fieldName[i],comparer,isFromGroup);
return this;
}
if (typeof comparer === "boolean")
comparer = !comparer ? ej.sortOrder.Ascending : ej.sortOrder.Descending;
else if (typeof comparer === "function")
order = "custom";
if (!comparer || typeof comparer === "string") {
order = comparer ? comparer.toLowerCase() : ej.sortOrder.Ascending;
comparer = ej.pvt.fnSort(comparer);
}
if (isFromGroup) {
sorts = filterQueries(this.queries, "onSortBy");
for (var i = 0; i < sorts.length; i++) {
t = sorts[i].e.fieldName;
if (typeof t === "string") {
if (t === fieldName) return this;
} else if (t instanceof Array) {
for (var j = 0; j < t.length; j++)
if (t[j] === fieldName || fieldName.toLowerCase() === t[j] + " desc")
return this;
}
}
}
this.queries.push({
fn: "onSortBy",
e: {
fieldName: fieldName,
comparer: comparer,
direction: order
}
});
return this;
},
sortByDesc: function (fieldName) {
return this.sortBy(fieldName, ej.sortOrder.Descending);
},
group: function (fieldName,fn) {
this.sortBy(fieldName, null, true);
this.queries.push({
fn: "onGroup",
e: {
fieldName: fieldName,
fn: fn
}
});
return this;
},
page: function (pageIndex, pageSize) {
this.queries.push({
fn: "onPage",
e: {
pageIndex: pageIndex,
pageSize: pageSize
}
});
return this;
},
range: function (start, end) {
if (typeof start !== "number" || typeof end !== "number")
throwError("Query() - range : Arguments type should be a number");
this.queries.push({
fn: "onRange",
e: {
start: start,
end: end
}
});
return this;
},
take: function (nos) {
if (typeof nos !== "number")
throwError("Query() - Take : Argument type should be a number");
this.queries.push({
fn: "onTake",
e: {
nos: nos
}
});
return this;
},
skip: function (nos) {
if (typeof nos !== "number")
throwError("Query() - Skip : Argument type should be a number");
this.queries.push({
fn: "onSkip",
e: { nos: nos }
});
return this;
},
select: function (fieldNames) {
if (typeof fieldNames === "string")
fieldNames = [].slice.call(arguments, 0);
if (!(fieldNames instanceof Array)) {
throwError("Query() - Select : Argument type should be String or Array");
}
this.queries.push({
fn: "onSelect",
e: { fieldNames: fieldNames }
});
return this;
},
hierarchy: function (query, selectorFn) {
if (!query || !(query instanceof ej.Query))
throwError("Query() - hierarchy : query must be instance of ej.Query");
if (typeof selectorFn === "function")
this._subQuerySelector = selectorFn;
this._subQuery = query;
return this;
},
foreignKey: function (key) {
if (typeof key === "string")
this._fKey = key;
return this;
},
requiresCount: function () {
this._requiresCount = true;
return this;
},
//type - sum, avg, min, max
aggregate: function (type, field) {
this.queries.push({
fn: "onAggregates",
e: { field: field, type: type }
});
}
};
ej.Adaptor = function (ds) {
this.dataSource = ds;
this.pvt = {};
this.init.apply(this, [].slice.call(arguments, 1));
};
ej.Adaptor.prototype = {
options: {
from: "table",
requestType: "json",
sortBy: "sorted",
select: "select",
skip: "skip",
group: "group",
take: "take",
search: "search",
count: "requiresCounts",
where: "where",
aggregates: "aggregates",
antiForgery: "antiForgery"
},
init: function () {
},
extend: function (overrides) {
var fn = function (ds) {
this.dataSource = ds;
if (this.options)
this.options = $.extend({}, this.options);
this.init.apply(this, [].slice.call(arguments, 0));
this.pvt = {};
};
fn.prototype = new this.type();
fn.prototype.type = fn;
var base = fn.prototype.base = {};
for (var p in overrides) {
if (fn.prototype[p])
base[p] = fn.prototype[p];
}
$.extend(true, fn.prototype, overrides);
return fn;
},
processQuery: function (dm, query) {
// this needs to be overridden
},
processResponse: function (data, ds, query, xhr) {
if (data.d)
return data.d;
return data;
},
convertToQueryString: function (req, query, dm) {
return $.param(req);
},
type: ej.Adaptor
};
ej.UrlAdaptor = new ej.Adaptor().extend({
processQuery: function (dm, query, hierarchyFilters) {
var sorted = filterQueries(query.queries, "onSortBy"),
grouped = filterQueries(query.queries, "onGroup"),
filters = filterQueries(query.queries, "onWhere"),
searchs = filterQueries(query.queries, "onSearch"),
aggregates = filterQueries(query.queries, "onAggregates"),
singles = filterQueryLists(query.queries, ["onSelect", "onPage", "onSkip", "onTake", "onRange"]),
params = query._params,
url = dm.dataSource.url, tmp, skip, take = null,
op = this.options;
var r = {
sorted: [],
grouped: [],
filters: [],
searches: [],
aggregates: []
};
// calc Paging & Range
if (singles["onPage"]) {
tmp = singles["onPage"];
skip = getValue(tmp.pageIndex, query);
take = getValue(tmp.pageSize, query);
skip = (skip - 1) * take;
} else if (singles["onRange"]) {
tmp = singles["onRange"];
skip = tmp.start;
take = tmp.end - tmp.start;
}
// Sorting
for (var i = 0; i < sorted.length; i++) {
tmp = getValue(sorted[i].e.fieldName, query);
r.sorted.push(callAdaptorFunc(this, "onEachSort", { name: tmp, direction: sorted[i].e.direction }, query));
}
// hierarchy
if (hierarchyFilters) {
tmp = this.getFiltersFrom(hierarchyFilters, query);
if (tmp)
r.filters.push(callAdaptorFunc(this, "onEachWhere", tmp.toJSON(), query));
}
// Filters
for (var i = 0; i < filters.length; i++) {
r.filters.push(callAdaptorFunc(this, "onEachWhere", filters[i].e.toJSON(), query));
for (var prop in r.filters[i]) {
if (isNull(r[prop]))
delete r[prop];
}
}
// Searches
for (var i = 0; i < searchs.length; i++) {
tmp = searchs[i].e;
r.searches.push(callAdaptorFunc(this, "onEachSearch", {
fields: tmp.fieldNames,
operator: tmp.operator,
key: tmp.searchKey,
ignoreCase: tmp.ignoreCase
}, query));
}
// Grouping
for (var i = 0; i < grouped.length; i++) {
r.grouped.push(getValue(grouped[i].e.fieldName, query));
}
// aggregates
for (var i = 0; i < aggregates.length; i++) {
tmp = aggregates[i].e;
r.aggregates.push({ type: tmp.type, field: getValue(tmp.field, query) });
}
var req = {};
req[op.from] = query._fromTable;
if (op.expand) req[op.expand] = query._expands;
req[op.select] = singles["onSelect"] ? callAdaptorFunc(this, "onSelect", getValue(singles["onSelect"].fieldNames, query), query) : "";
req[op.count] = query._requiresCount ? callAdaptorFunc(this, "onCount", query._requiresCount, query) : "";
req[op.search] = r.searches.length ? callAdaptorFunc(this, "onSearch", r.searches, query) : "";
req[op.skip] = singles["onSkip"] ? callAdaptorFunc(this, "onSkip", getValue(singles["onSkip"].nos, query), query) : "";
req[op.take] = singles["onTake"] ? callAdaptorFunc(this, "onTake", getValue(singles["onTake"].nos, query), query) : "";
req[op.antiForgery] = (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : "";
req[op.where] = r.filters.length || r.searches.length ? callAdaptorFunc(this, "onWhere", r.filters, query) : "";
req[op.sortBy] = r.sorted.length ? callAdaptorFunc(this, "onSortBy", r.sorted, query) : "";
req[op.group] = r.grouped.length ? callAdaptorFunc(this, "onGroup", r.grouped, query) : "";
req[op.aggregates] = r.aggregates.length ? callAdaptorFunc(this, "onAggregates", r.aggregates, query) : "";
req["param"] = [];
// Params
callAdaptorFunc(this, "addParams", { dm: dm, query: query, params: params, reqParams: req });
// cleanup
for (var prop in req) {
if (isNull(req[prop]) || req[prop] === "" || req[prop].length === 0 || prop === "params")
delete req[prop];
}
if (!(op.skip in req && op.take in req) && take !== null) {
req[op.skip] = callAdaptorFunc(this, "onSkip", skip, query);
req[op.take] = callAdaptorFunc(this, "onTake", take, query);
}
var p = this.pvt;
this.pvt = {};
if (this.options.requestType === "json") {
return {
data: JSON.stringify(req),
url: url,
ejPvtData: p,
type: "POST",
contentType: "application/json; charset=utf-8"
}
}
tmp = this.convertToQueryString(req, query, dm);
tmp = (dm.dataSource.url.indexOf("?")!== -1 ? "&" : "/") + tmp;
return {
type: "GET",
url: tmp.length ? url.replace(/\/*$/, tmp) : url,
ejPvtData: p
};
},
convertToQueryString: function (req, query, dm) {
if (dm.dataSource.url && dm.dataSource.url.indexOf("?") !== -1)
return $.param(req);
return "?" + $.param(req);
},
processResponse: function (data, ds, query, xhr, request, changes) {
var pvt = request.ejPvtData || {};
var groupDs= data.groupDs;
if (xhr && xhr.getResponseHeader("Content-Type") && xhr.getResponseHeader("Content-Type").indexOf("xml") != -1 && data.nodeType == 9)
return query._requiresCount ? { result: [], count: 0 } : [];
var d = JSON.parse(request.data);
if (d && d.action === "batch" && data.added) {
changes.added = data.added;
return changes;
}
if (data.d)
data = data.d;
if (pvt && pvt.aggregates && pvt.aggregates.length) {
var agg = pvt.aggregates, args = {}, fn, res = {};
if ('count' in data) args.count = data.count;
if (data["result"]) args.result = data.result;
if (data["aggregate"]) data = data.aggregate;
for (var i = 0; i < agg.length; i++) {
fn = ej.aggregates[agg[i].type];
if (fn)
res[agg[i].field + " - " + agg[i].type] = fn(data, agg[i].field);
}
args["aggregates"] = res;
data = args;
}
if (pvt && pvt.groups && pvt.groups.length) {
var groups = pvt.groups, args = {};
if ('count' in data) args.count = data.count;
if (data["aggregates"]) args.aggregates = data.aggregates;
if (data["result"]) data = data.result;
for (var i = 0; i < groups.length; i++){
var level = null;
var format = getColFormat(groups[i], query.queries);
if (!ej.isNullOrUndefined(groupDs))
groupDs = ej.group(groupDs, groups[i], null, format);
data = ej.group(data, groups[i], pvt.aggregates, format, level, groupDs);
}
if (args.count != undefined)
args.result = data;
else
args = data;
return args;
}
return data;
},
onGroup: function (e) {
this.pvt.groups = e;
},
onAggregates: function (e) {
this.pvt.aggregates = e;
},
batchRequest: function (dm, changes, e, query) {
var res = {
changed: changes.changed,
added: changes.added,
deleted: changes.deleted,
action: "batch",
table: e.url,
key: e.key,
antiForgery: (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : ""
};
if (query)
this.addParams({ dm: dm, query: query, params: query._params, reqParams: res });
return {
type: "POST",
url: dm.dataSource.batchUrl || dm.dataSource.crudUrl || dm.dataSource.removeUrl || dm.dataSource.url,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(res)
};
},
beforeSend: function (dm, request) {
},
insert: function (dm, data, tableName, query) {
var res = {
value: data,
table: tableName,
action: "insert",
antiForgery: (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : ""
};
if (query)
this.addParams({ dm: dm, query: query, params: query._params, reqParams: res });
return {
url: dm.dataSource.insertUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: JSON.stringify(res)
};
},
remove: function (dm, keyField, value, tableName, query) {
var res = {
key: value,
keyColumn: keyField,
table: tableName,
action: "remove",
antiForgery: (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : ""
};
if (query)
this.addParams({ dm: dm, query: query, params: query._params, reqParams: res });
return {
type: "POST",
url: dm.dataSource.removeUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: JSON.stringify(res)
};
},
update: function (dm, keyField, value, tableName, query) {
var res = {
value: value,
action: "update",
keyColumn: keyField,
key: value[keyField],
table: tableName,
antiForgery: (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : ""
};
if (query)
this.addParams({ dm: dm, query: query, params: query._params, reqParams: res });
return {
type: "POST",
url: dm.dataSource.updateUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: JSON.stringify(res)
};
},
getFiltersFrom: function (data, query) {
if (!(data instanceof Array) || !data.length)
throwError("ej.SubQuery: Array of key values required");
var key = query._fKey, value, prop = key, pKey = query._key, predicats = [],
isValues = typeof data[0] !== "object";
if (typeof data[0] !== "object") prop = null;
for (var i = 0; i < data.length; i++) {
value = !isValues ? ej.pvt.getObject(pKey || prop, data[i]) : data[i];
predicats.push(new ej.Predicate(key, "==", value));
}
return ej.Predicate.or(predicats);
},
addParams: function (options) {
var dm = options.dm, query = options.query, params = options.params, req = options.reqParams; req["params"] = {};
for (var i = 0, tmp; tmp = params[i]; i++) {
if (req[tmp.key]) throwError("ej.Query: Custom Param is conflicting other request arguments");
req[tmp.key] = tmp.value;
if (tmp.fn)
req[tmp.key] = tmp.fn.call(query, tmp.key, query, dm);
req["params"][tmp.key] = req[tmp.key];
}
}
});
ej.WebMethodAdaptor = new ej.UrlAdaptor().extend({
processQuery: function (dm, query, hierarchyFilters) {
var obj = ej.UrlAdaptor.prototype.processQuery(dm, query, hierarchyFilters);
var data = ej.parseJSON(obj.data), result = {};
result["value"] = data;
//Params
callAdaptorFunc(this, "addParams", { dm: dm, query: query, params: query._params, reqParams: result });
return {
data: JSON.stringify(result),
url: obj.url,
ejPvtData: obj.ejPvtData,
type: "POST",
contentType: "application/json; charset=utf-8"
}
},
addParams: function (options) {
var dm = options.dm, query = options.query, params = options.params, req = options.reqParams; req["params"] = {};
for (var i = 0, tmp; tmp = params[i]; i++) {
if (req[tmp.key]) throwError("ej.Query: Custom Param is conflicting other request arguments");
var webkey = tmp.key, webvalue = tmp.value;
if (tmp.fn)
webvalue = tmp.fn.call(query, tmp.key, query, dm);
req[webkey] = webvalue;
req["params"][webkey] = req[webkey];
}
}
});
ej.CacheAdaptor = new ej.UrlAdaptor().extend({
init: function (adaptor, timeStamp, pageSize) {
if (!ej.isNullOrUndefined(adaptor)) {
this.cacheAdaptor = adaptor;
}
this.pageSize = pageSize;
this.guidId = ej.getGuid("cacheAdaptor");
var obj = { keys: [], results: [] };
if (window.localStorage)
window.localStorage.setItem(this.guidId, JSON.stringify(obj));
var guid = this.guidId;
if (!ej.isNullOrUndefined(timeStamp)) {
setInterval(function () {
var data = ej.parseJSON(window.localStorage.getItem(guid));
var forDel = [];
for (var i = 0; i < data.results.length; i++) {
data.results[i].timeStamp = new Date() - new Date(data.results[i].timeStamp)
if (new Date() - new Date(data.results[i].timeStamp) > timeStamp)
forDel.push(i);
}
var d = forDel;
for (var i = 0; i < forDel.length; i++) {
data.results.splice(forDel[i], 1);
data.keys.splice(forDel[i], 1);
}
window.localStorage.removeItem(guid);
window.localStorage.setItem(guid, JSON.stringify(data));
}, timeStamp);
}
},
generateKey: function (url, query) {
var sorted = filterQueries(query.queries, "onSortBy"),
grouped = filterQueries(query.queries, "onGroup"),
filters = filterQueries(query.queries, "onWhere"),
searchs = filterQueries(query.queries, "onSearch"),
pageQuery = filterQueries(query.queries, "onPage"),
singles = filterQueryLists(query.queries, ["onSelect", "onPage", "onSkip", "onTake", "onRange"]),
params = query._params;
var key = url;
if (singles["onPage"])
key += singles["onPage"].pageIndex;
sorted.forEach(function (obj) {
key += obj.e.direction + obj.e.fieldName;
});
grouped.forEach(function (obj) {
key += obj.e.fieldName;
});
searchs.forEach(function (obj) {
key += obj.e.searchKey;
});
for (var filter = 0; filter < filters.length; filter++) {
var currentFilter = filters[filter];
if (currentFilter.e.isComplex) {
var newQuery = query.clone();
newQuery.queries = [];
for (var i = 0; i < currentFilter.e.predicates.length; i++) {
newQuery.queries.push({ fn: "onWhere", e: currentFilter.e.predicates[i], filter: query.queries.filter });
}
key += currentFilter.e.condition + this.generateKey(url, newQuery);
}
else
key += currentFilter.e.field + currentFilter.e.operator + currentFilter.e.value
}
return key;
},
processQuery: function (dm, query, hierarchyFilters) {
var key = this.generateKey(dm.dataSource.url, query);
var cachedItems;
if (window.localStorage)
cachedItems = ej.parseJSON(window.localStorage.getItem(this.guidId));
var data = cachedItems ? cachedItems.results[cachedItems.keys.indexOf(key)] : null;
if (data != null && !this._crudAction && !this._insertAction) {
return data;
}
this._crudAction = null; this._insertAction = null;
return this.cacheAdaptor.processQuery.apply(this.cacheAdaptor, [].slice.call(arguments, 0))
},
processResponse: function (data, ds, query, xhr, request, changes) {
if (this._insertAction || (request && this.cacheAdaptor.options.batch && request.url.endsWith(this.cacheAdaptor.options.batch) && request.type.toLowerCase() === "post")) {
return this.cacheAdaptor.processResponse(data, ds, query, xhr, request, changes);
}
var data = this.cacheAdaptor.processResponse.apply(this, [].slice.call(arguments, 0));
var key = this.generateKey(ds.dataSource.url, query)
var obj = {};
if (window.localStorage)
obj = ej.parseJSON(window.localStorage.getItem(this.guidId));
var index = $.inArray(key, obj.keys);
if (index != -1) {
obj.results.splice(index, 1);
obj.keys.splice(index, 1);
}
obj.results[obj.keys.push(key) - 1] = { keys: key, result: data.result, timeStamp: new Date(), count: data.count }
while (obj.results.length > this.pageSize) {
obj.results.splice(0, 1);
obj.keys.splice(0, 1);
}
window.localStorage.setItem(this.guidId, JSON.stringify(obj));
return data;
},
update: function (dm, keyField, value, tableName) {
this._crudAction = true;
return this.cacheAdaptor.update(dm, keyField, value, tableName);
},
insert: function (dm, data, tableName) {
this._insertAction = true;
return this.cacheAdaptor.insert(dm, data, tableName);
},
remove: function (dm, keyField, value, tableName) {
this._crudAction = true;
return this.cacheAdaptor.remove(dm, keyField, value, tableName);
},
batchRequest: function (dm, changes, e) {
return this.cacheAdaptor.batchRequest(dm, changes, e);
}
});
var filterQueries = function (queries, name) {
return queries.filter(function (q) {
return q.fn === name;
}) || [];
};
var filterQueryLists = function (queries, singles) {
var filtered = queries.filter(function (q) {
return singles.indexOf(q.fn) !== -1;
}), res = {};
for (var i = 0; i < filtered.length; i++) {
if (!res[filtered[i].fn])
res[filtered[i].fn] = filtered[i].e;
}
return res;
};
var callAdaptorFunc = function (obj, fnName, param, param1) {
if (obj[fnName]) {
var res = obj[fnName](param, param1);
if (!isNull(res)) param = res;
}
return param;
};
ej.ODataAdaptor = new ej.UrlAdaptor().extend({
options: {
requestType: "get",
accept: "application/json;odata=light;q=1,application/json;odata=verbose;q=0.5",
multipartAccept: "multipart/mixed",
sortBy: "$orderby",
select: "$select",
skip: "$skip",
take: "$top",
count: "$inlinecount",
where: "$filter",
expand: "$expand",
batch: "$batch",
changeSet: "--changeset_",
batchPre: "batch_",
contentId: "Content-Id: ",
batchContent: "Content-Type: multipart/mixed; boundary=",
changeSetContent: "Content-Type: application/http\nContent-Transfer-Encoding: binary ",
batchChangeSetContentType: "Content-Type: application/json; charset=utf-8 "
},
onEachWhere: function (filter, requiresCast) {
return filter.isComplex ? this.onComplexPredicate(filter, requiresCast) : this.onPredicate(filter, requiresCast);
},
_typeStringQuery: function (pred, requiresCast,val,field,guid) {
if(val.indexOf("'") != -1)
val = val.replace(new RegExp(/'/g), "''");
var specialCharFormat = /[ !@@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/;
if (specialCharFormat.test(val)) {
val = encodeURIComponent(val)
}
val = "'" + val + "'";
if (requiresCast) {
field = "cast(" + field + ", 'Edm.String')";
}
if (ej.isGUID(val))
guid = 'guid';
if (pred.ignoreCase) {
!guid ? field = "tolower(" + field + ")" : field;
val = val.toLowerCase();
}
return {"val":val,"guid":guid ,"field":field};
},
onPredicate: function (pred, query, requiresCast) {
var returnValue = "",
operator,guid,
val = pred.value,
type = typeof val,
field = this._p(pred.field);
if (val instanceof Date)
val = "datetime'" + p.replacer(val).toJSON() + "'";
if (type === "string") {
var args = this._typeStringQuery(pred,requiresCast,val,field , guid);
val = args["val"]; field = args["field"]; guid = args["guid"];
}
operator = ej.data.odBiOperator[pred.operator];
if(pred.anyCondition != "" && operator) {
returnValue += val["table"];
returnValue += ("/"+pred.anyCondition);
returnValue += "(d:d/";
returnValue += field;
returnValue += operator;
returnValue += val["value"];
returnValue += ")";
return returnValue;
}
if( pred.operator == "in" || pred.operator == "notin" ) {
returnValue += "(";
for(var index = 0; index < val.length; index++ ) {
if (val[index] instanceof Date)
val[index] = "datetime'" + p.replacer(val[index]).toJSON() + "'";
if (typeof val[index] === "string") {
var args = this._typeStringQuery(pred,requiresCast,val[index],field , guid);
val[index] = args["val"]; field = args["field"]; guid = args["guid"];
}
returnValue += field;
returnValue += operator;
returnValue += val[index];
if( index != val.length -1 ) returnValue += ( pred.operator == "in") ? " or " : " and ";
}
returnValue += ")";
return returnValue;
}
if (operator) {
return this.onOperation(returnValue, operator, field, val, guid);
}
operator = ej.data.odUniOperator[pred.operator];
if (!operator || type !== "string") return "";
if (operator === "substringof") {
var t = val;
val = field;
field = t;
}
returnValue += operator + "(";
returnValue += field + ",";
if (guid) returnValue += guid;
returnValue += val + ")";
if( pred.operator == "notcontains" ) {
returnValue += " eq false"
}
if(pred.anyCondition != "" && operator) {
var returnValue1;
returnValue1 += val["table"];
returnValue1 += ("/"+pred.anyCondition);
returnValue1 += "(d:d/";
returnValue += returnValue;
returnValue1 += ")";
return returnValue1;
}
return returnValue;
},
onOperation: function (returnValue, operator, field, val, guid) {
returnValue += field;
returnValue += operator;
if (guid)
returnValue += guid;
return returnValue + val;
},
onComplexPredicate: function (pred, requiresCast) {
var res = [];
for (var i = 0; i < pred.predicates.length; i++) {
res.push("(" + this.onEachWhere(pred.predicates[i], requiresCast) + ")");
}
return res.join(" " + pred.condition + " ");
},
onWhere: function (filters) {
if (this.pvt.searches)
filters.push(this.onEachWhere(this.pvt.searches, null, true));
return filters.join(" and ");
},
onEachSearch: function (e) {
if (e.fields.length === 0)
throwError("Query() - Search : oData search requires list of field names to search");
var filter = this.pvt.searches || [];
for (var i = 0; i < e.fields.length; i++) {
filter.push(new ej.Predicate(e.fields[i], e.operator, e.key, e.ignoreCase));
}
this.pvt.searches = filter;
},
onSearch: function (e) {
this.pvt.searches = ej.Predicate.or(this.pvt.searches);
return "";
},
onEachSort: function (e) {
var res = [];
if (e.name instanceof Array) {
for (var i = 0; i < e.name.length; i++)
res.push(this._p(e.name[i]));
} else {
res.push(this._p(e.name) + (e.direction === "descending" ? " desc" : ""));
}
return res.join(",");
},
onSortBy: function (e) {
return e.reverse().join(",");
},
onGroup: function (e) {
this.pvt.groups = e;
return "";
},
onSelect: function (e) {
for (var i = 0; i < e.length; i++)
e[i] = this._p(e[i]);
return e.join(',');
},
onAggregates: function(e){
this.pvt.aggregates = e;
return "";
},
onCount: function (e) {
return e === true ? "allpages" : "";
},
beforeSend: function (dm, request, settings) {
if (settings.url.endsWith(this.options.batch) && settings.type.toLowerCase() === "post") {
request.setRequestHeader("Accept", oData.multipartAccept);
request.setRequestHeader("DataServiceVersion", "2.0");
request.overrideMimeType("text/plain; charset=x-user-defined");
}
if (!dm.dataSource.crossDomain) {
request.setRequestHeader("DataServiceVersion", "2.0");
request.setRequestHeader("MaxDataServiceVersion", "2.0");
}
},
processResponse: function (data, ds, query, xhr, request, changes) {
if (!ej.isNullOrUndefined(data.d)) {
var dataCopy = (query && query._requiresCount) ? data.d.results : data.d;
if (!ej.isNullOrUndefined(dataCopy))
for (var i = 0; i < dataCopy.length; i++) {
!ej.isNullOrUndefined(dataCopy[i].__metadata) && delete dataCopy[i].__metadata;
}
}
var pvt = request && request.ejPvtData;
if (xhr && xhr.getResponseHeader("Content-Type") && xhr.getResponseHeader("Content-Type").indexOf("xml") != -1 && data.nodeType == 9)
return query._requiresCount ? { result: [], count: 0 } : [];
if (request && this.options.batch && request.url.endsWith(this.options.batch) && request.type.toLowerCase() === "post") {
var guid = xhr.getResponseHeader("Content-Type"), cIdx, jsonObj;
guid = guid.substring(guid.indexOf("=batchresponse") + 1);
data = data.split(guid);
if (data.length < 2) return;
data = data[1];
var exVal = /(?:\bContent-Type.+boundary=)(changesetresponse.+)/i.exec(data);
data.replace(exVal[0], "");
var changeGuid = exVal[1];
data = data.split(changeGuid);
for (var i = data.length; i > -1; i--) {
if (!/\bContent-ID:/i.test(data[i]) || !/\bHTTP.+201/.test(data[i]))
continue;
cIdx = parseInt(/\bContent-ID: (\d+)/i.exec(data[i])[1]);
if (changes.added[cIdx]) {
jsonObj = p.parseJson(/^\{.+\}/m.exec(data[i])[0]);
$.extend(changes.added[cIdx], this.processResponse(jsonObj));
}
}
return changes;
}
var version = xhr && xhr.getResponseHeader("DataServiceVersion"), count = null, aggregateResult = {};
version = (version && parseInt(version, 10)) || 2;
if (query && query._requiresCount) {
if (data.__count || data['odata.count']) count = data.__count || data['odata.count'];
if (data.d) data = data.d;
if (data.__count || data['odata.count']) count = data.__count || data['odata.count'];
}
if (version === 3 && data.value) data = data.value;
if (data.d) data = data.d;
if (version < 3 && data.results) data = data.results;
if (pvt && pvt.aggregates && pvt.aggregates.length) {
var agg = pvt.aggregates, args = {}, fn, res = {};
for (var i = 0; i < agg.length; i++) {
fn = ej.aggregates[agg[i].type];
if (fn)
res[agg[i].field + " - " + agg[i].type] = fn(data, agg[i].field);
}
aggregateResult = res;
}
if (pvt && pvt.groups && pvt.groups.length) {
var groups = pvt.groups;
for (var i = 0; i < groups.length; i++) {
var format = getColFormat(groups[i], query.queries)
data = ej.group(data, groups[i], pvt.aggregates, format);
}
}
return isNull(count) ? data : { result: data, count: count, aggregates: aggregateResult };
},
convertToQueryString: function (req, query, dm) {
var res = [], tableName = req.table || "";
delete req.table;
if (dm.dataSource.requiresFormat)
req["$format"] = "json";
for (var prop in req)
res.push(prop + "=" + req[prop]);
res = res.join("&");
if (dm.dataSource.url && dm.dataSource.url.indexOf("?") !== -1 && !tableName)
return res;
return res.length ? tableName + "?" + res : tableName || "";
},
insert: function (dm, data, tableName) {
return {
url: dm.dataSource.url.replace(/\/*$/, tableName ? '/' + tableName : ''),
data: JSON.stringify(data)
}
},
remove: function (dm, keyField, value, tableName) {
if(typeof(value) == "string"){
return {
type: "DELETE",
url: ej.isGUID(value) ? dm.dataSource.url.replace(/\/*$/, tableName ? '/' + tableName : '') + "(" + value + ")" : dm.dataSource.url.replace(/\/*$/, tableName ? '/' + tableName : '') + "('" + value + "')"
};
}
return {
type: "DELETE",
url: dm.dataSource.url.replace(/\/*$/, tableName ? '/' + tableName : '') + '(' + value + ')'
};
},
update: function (dm, keyField, value, tableName) {
var url;
if(typeof value[keyField] === "string")
url = ej.isGUID(value[keyField]) ? dm.dataSource.url.replace(/\/*$/, tableName ? '/' + tableName : '') + "(" + value[keyField] + ")" : dm.dataSource.url.replace(/\/*$/, tableName ? '/' + tableName : '') + "('" + value[keyField] + "')";
else
url = dm.dataSource.url.replace(/\/*$/, tableName ? '/' + tableName : '') + '(' + value[keyField] + ')';
return {
type: "PUT",
url: url,
data: JSON.stringify(value),
accept: this.options.accept
};
},
batchRequest: function (dm, changes, e) {
var initialGuid = e.guid = ej.getGuid(oData.batchPre);
var url = dm.dataSource.url.replace(/\/*$/, '/' + this.options.batch);
var args = {
url: e.url,
key: e.key,
cid: 1,
cSet: ej.getGuid(oData.changeSet)
};
var req = "--" + initialGuid + "\n";
req += "Content-Type: multipart/mixed; boundary=" + args.cSet.replace("--", "") + "\n";
this.pvt.changeSet = 0;
req += this.generateInsertRequest(changes.added, args);
req += this.generateUpdateRequest(changes.changed, args);
req += this.generateDeleteRequest(changes.deleted, args);
req += args.cSet + "--\n";
req += "--" + initialGuid + "--";
return {
type: "POST",
url: url,
contentType: "multipart/mixed; charset=UTF-8;boundary=" + initialGuid,
data: req
};
},
generateDeleteRequest: function (arr, e) {
if (!arr) return "";
var req = "", val;
for (var i = 0; i < arr.length; i++) {
req += "\n" + e.cSet + "\n";
req += oData.changeSetContent + "\n\n";
req += "DELETE ";
val = typeof arr[i][e.key] == "string" ? "'" + arr[i][e.key] + "'" : arr[i][e.key];
req += e.url + "(" + val + ") HTTP/1.1\n";
req += "If-Match : * \n"
req += "Accept: " + oData.accept + "\n";
req += "Content-Id: " + this.pvt.changeSet++ + "\n";
req += oData.batchChangeSetContentType + "\n";
}
return req + "\n";
},
generateInsertRequest: function (arr, e) {
if (!arr) return "";
var req = "";
for (var i = 0; i < arr.length; i++) {
req += "\n" + e.cSet + "\n";
req += oData.changeSetContent + "\n\n";
req += "POST ";
req += e.url + " HTTP/1.1\n";
req += "Accept: " + oData.accept + "\n";
req += "Content-Id: " + this.pvt.changeSet++ + "\n";
req += oData.batchChangeSetContentType + "\n\n";
req += JSON.stringify(arr[i]) + "\n";
}
return req;
},
generateUpdateRequest: function (arr, e) {
if (!arr) return "";
var req = "", val;
for (var i = 0; i < arr.length; i++) {
req += "\n" + e.cSet + "\n";
req += oData.changeSetContent + "\n\n";
req += "PUT ";
val = typeof arr[i][e.key] == "string" ? "'" + arr[i][e.key] + "'" : arr[i][e.key];
req += e.url + "(" + val + ")" + " HTTP/1.1\n";
req += "If-Match : * \n"
req += "Accept: " + oData.accept + "\n";
req += "Content-Id: " + this.pvt.changeSet++ + "\n";
req += oData.batchChangeSetContentType + "\n\n";
req += JSON.stringify(arr[i]) + "\n\n";
}
return req;
},
_p: function (prop) {
return prop.replace(/\./g, "/");
}
});
ej.ODataV4Adaptor = new ej.ODataAdaptor().extend({
options: {
requestType: "get",
accept: "application/json;odata=light;q=1,application/json;odata=verbose;q=0.5",
multipartAccept: "multipart/mixed",
sortBy: "$orderby",
select: "$select",
skip: "$skip",
take: "$top",
count: "$count",
search: "$search",
where: "$filter",
expand: "$expand",
batch: "$batch",
changeSet: "--changeset_",
batchPre: "batch_",
contentId: "Content-Id: ",
batchContent: "Content-Type: multipart/mixed; boundary=",
changeSetContent: "Content-Type: application/http\nContent-Transfer-Encoding: binary ",
batchChangeSetContentType: "Content-Type: application/json; charset=utf-8 "
},
onCount: function (e) {
return e === true ? "true" : "";
},
onPredicate: function (pred, query, requiresCast) {
var returnValue = "",
val = pred.value,
isDate = val instanceof Date;
ej.data.odUniOperator["contains"] = "contains";
returnValue = ej.ODataAdaptor.prototype.onPredicate.call(this, pred, query, requiresCast);
ej.data.odUniOperator["contains"] = "substringof";
if (isDate)
returnValue = returnValue.replace(/datetime'(.*)'$/, "$1");
return returnValue;
},
onOperation: function (returnValue, operator, field, val, guid) {
if (guid) {
returnValue += "(" + field;
returnValue += operator;
returnValue += val.replace(/["']/g, "") + ")";
} else {
returnValue += field;
returnValue += operator;
returnValue += val;
}
return returnValue;
},
onEachSearch: function (e) {
var search = this.pvt.search || [];
search.push(e.key);
this.pvt.search = search;
},
onSearch: function (e) {
return this.pvt.search.join(" OR ");
},
beforeSend: function (dm, request, settings) {
},
processQuery: function (ds, query) {
var digitsWithSlashesExp = /\/[\d*\/]*/g;
var poppedExpand = "";
for (var i = query._expands.length - 1; i > 0; i--) {
if (poppedExpand.indexOf(query._expands[i]) >= 0) { // If current expand is child of previous
query._expands.pop(); // Just remove it because its in the expand already
}
else {
if (digitsWithSlashesExp.test(query._expands[i])) { //If expanded to subentities
poppedExpand = query._expands.pop();
var r = poppedExpand.replace(digitsWithSlashesExp, "($expand="); //Rewrite into odata v4 expand
for (var j = 0; j < poppedExpand.split(digitsWithSlashesExp).length - 1; j++) {
r = r + ")"; // Add closing brackets
}
query._expands.unshift(r); // Add to the front of the array
i++;
}
}
}
return ej.ODataAdaptor.prototype.processQuery.apply(this, [ds, query]);
},
processResponse: function (data, ds, query, xhr, request, changes) {
var pvt = request && request.ejPvtData;
if (xhr && xhr.getResponseHeader("Content-Type") && xhr.getResponseHeader("Content-Type").indexOf("xml") != -1 && data.nodeType == 9)
return query._requiresCount ? { result: [], count: 0 } : [];
if (request && this.options.batch && request.url.endsWith(this.options.batch) && request.type.toLowerCase() === "post") {
var guid = xhr.getResponseHeader("Content-Type"), cIdx, jsonObj;
guid = guid.substring(guid.indexOf("=batchresponse") + 1);
data = data.split(guid);
if (data.length < 2) return;
data = data[1];
var exVal = /(?:\bContent-Type.+boundary=)(changesetresponse.+)/i.exec(data);
data.replace(exVal[0], "");
var changeGuid = exVal[1];
data = data.split(changeGuid);
for (var i = data.length; i > -1; i--) {
if (!/\bContent-ID:/i.test(data[i]) || !/\bHTTP.+201/.test(data[i]))
continue;
cIdx = parseInt(/\bContent-ID: (\d+)/i.exec(data[i])[1]);
if (changes.added[cIdx]) {
jsonObj = p.parseJson(/^\{.+\}/m.exec(data[i])[0]);
$.extend(changes.added[cIdx], this.processResponse(jsonObj));
}
}
return changes;
}
var count = null, aggregateResult = {};
if (query && query._requiresCount)
if ('@odata.count' in data) count = data['@odata.count'];
data = ej.isNullOrUndefined(data.value) ? data : data.value;
if (pvt && pvt.aggregates && pvt.aggregates.length) {
var agg = pvt.aggregates, args = {}, fn, res = {};
for (var i = 0; i < agg.length; i++) {
fn = ej.aggregates[agg[i].type];
if (fn)
res[agg[i].field + " - " + agg[i].type] = fn(data, agg[i].field);
}
aggregateResult = res;
}
if (pvt && pvt.groups && pvt.groups.length) {
var groups = pvt.groups;
for (var i = 0; i < groups.length; i++) {
var format = getColFormat(groups[i], query.queries);
data = ej.group(data, groups[i], pvt.aggregates, format);
}
}
return isNull(count) ? data : { result: data, count: count, aggregates: aggregateResult };
},
});
ej.JsonAdaptor = new ej.Adaptor().extend({
processQuery: function (ds, query) {
var result = ds.dataSource.json.slice(0), count = result.length, cntFlg = true, ret, key, agg = {};
for (var i = 0; i < query.queries.length; i++) {
key = query.queries[i];
ret = this[key.fn].call(this, result, key.e, query);
if (key.fn == "onAggregates")
agg[key.e.field + " - " + key.e.type] = ret;
else
result = ret !== undefined ? ret : result;
if (key.fn === "onPage" || key.fn === "onSkip" || key.fn === "onTake" || key.fn === "onRange") cntFlg = false;
if (cntFlg) count = result.length;
}
if (query._requiresCount) {
result = {
result: result,
count: count,
aggregates: agg
};
}
return result;
},
batchRequest: function (dm, changes, e) {
var i;
for (i = 0; i < changes.added.length; i++)
this.insert(dm, changes.added[i]);
for (i = 0; i < changes.changed.length; i++)
this.update(dm, e.key, changes.changed[i]);
for (i = 0; i < changes.deleted.length; i++)
this.remove(dm, e.key, changes.deleted[i]);
return changes;
},
onWhere: function (ds, e) {
if (!ds) return ds;
return ds.filter(function (obj) {
return e.validate(obj);
});
},
onAggregates: function(ds, e){
var fn = ej.aggregates[e.type];
if (!ds || !fn || ds.length == 0) return null;
return fn(ds, e.field);
},
onSearch: function (ds, e) {
if (!ds || !ds.length) return ds;
if (e.fieldNames.length === 0) {
ej.pvt.getFieldList(ds[0], e.fieldNames);
}
return ds.filter(function (obj) {
for (var j = 0; j < e.fieldNames.length; j++) {
if (e.comparer.call(obj, ej.pvt.getObject(e.fieldNames[j], obj), e.searchKey, e.ignoreCase))
return true;
}
return false;
});
},
onSortBy: function (ds, e, query) {
if (!ds) return ds;
var fnCompare, field = getValue(e.fieldName, query);
if (!field)
return ds.sort(e.comparer);
if (field instanceof Array) {
field = field.slice(0);
for (var i = field.length - 1; i >= 0; i--) {
if (!field[i]) continue;
fnCompare = e.comparer;
if (field[i].endsWith(" desc")) {
fnCompare = ej.pvt.fnSort(ej.sortOrder.Descending);
field[i] = field[i].replace(" desc", "");
}
ds = stableSort(ds, field[i], fnCompare, []);
}
return ds;
}
return stableSort(ds, field, e.comparer, query ? query.queries : []);
},
onGroup: function (ds, e, query) {
if (!ds) return ds;
var aggQuery = filterQueries(query.queries, "onAggregates"), agg = [];
if (aggQuery.length) {
var tmp;
for (var i = 0; i < aggQuery.length; i++) {
tmp = aggQuery[i].e;
agg.push({ type: tmp.type, field: getValue(tmp.field, query) });
}
}
var format = getColFormat(e.fieldName, query.queries);
return ej.group(ds, getValue(e.fieldName, query), agg, format);
},
onPage: function (ds, e, query) {
var size = getValue(e.pageSize, query),
start = (getValue(e.pageIndex, query) - 1) * size, end = start + size;
if (!ds) return ds;
return ds.slice(start, end);
},
onRange: function (ds, e) {
if (!ds) return ds;
return ds.slice(getValue(e.start), getValue(e.end));
},
onTake: function (ds, e) {
if (!ds) return ds;
return ds.slice(0, getValue(e.nos));
},
onSkip: function (ds, e) {
if (!ds) return ds;
return ds.slice(getValue(e.nos));
},
onSelect: function (ds, e) {
if (!ds) return ds;
return ej.select(ds, getValue(e.fieldNames));
},
insert: function (dm, data) {
return dm.dataSource.json.push(data);
},
remove: function (dm, keyField, value, tableName) {
var ds = dm.dataSource.json, i;
if (typeof value === "object")
value = ej.getObject(keyField, value);
for (i = 0; i < ds.length; i++) {
if (ej.getObject(keyField, ds[i]) === value) break;
}
return i !== ds.length ? ds.splice(i, 1) : null;
},
update: function (dm, keyField, value, tableName) {
var ds = dm.dataSource.json, i, key = ej.getObject(keyField, value);
for (i = 0; i < ds.length; i++) {
if (ej.getObject(keyField, ds[i]) === key) break;
}
return i < ds.length ? $.extend(ds[i], value) : null;
}
});
ej.ForeignKeyAdaptor = function (data, type) {
var foreignObj = new ej[type || "JsonAdaptor"]().extend({
init: function () {
this.foreignData = [];
this.key = [];
this.adaptorType = type;
this.value = [];
this.fValue = [];
this.keyField = [];
var dataObj = data;
for (var i = 0; i < dataObj.length; i++) {
this.foreignData[i] = dataObj[i].dataSource;
this.key[i] = dataObj[i].foreignKeyField;
this.fValue[i] = ej.isNullOrUndefined(dataObj[i].field)? dataObj[i].foreignKeyValue : dataObj[i].field + "_" + dataObj[i].foreignKeyValue;
this.value[i] = dataObj[i].foreignKeyValue;
this.keyField[i] = dataObj[i].field || dataObj[i].foreignKeyField;
this.initial = true;
}
},
processQuery: function (ds, query) {
var data = ds.dataSource.json;
if (this.initial) {
for (var i = 0; i < data.length; i++) {
var proxy = this;
for (var j = 0; j < this.foreignData.length; j++) {
this.foreignData[j].filter(function (col) { //filtering the foreignKey dataSource
if (ej.getObject(proxy.key[j], col) == ej.getObject(proxy.keyField[j], data[i]))
data[i][proxy.fValue[j]] = ej.getObject(proxy.value[j], col);
});
}
}
this.initial = false;
}
return this.base.processQuery.apply(this, [ds, query]);
},
setValue: function (value) {
for (var i = 0; i < this.foreignData.length; i++) {
var proxy = this;
var keyValue = value[this.fValue[i]];
if (typeof keyValue == "string" && !isNaN(keyValue))
keyValue = ej.parseFloat(keyValue);
var data = $.grep(proxy.foreignData[i], function (e) {
return e[proxy.value[i]] == keyValue;
})[0];
if (ej.isNullOrUndefined(data)) {
data = $.grep(proxy.foreignData[i], function (e) {
return e[proxy.key[i]] == keyValue;
})[0];
if (ej.getObject(this.value[i], data) != undefined)
ej.createObject(proxy.value[i], ej.getObject(this.value[i], data), value);
}
if (ej.getObject(this.value[i], data) != undefined)
ej.createObject(this.keyField[i], ej.getObject(this.key[i], data), value);
}
},
insert: function (dm, data, tableName) {
this.setValue(data);
return {
url: dm.dataSource.insertUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: JSON.stringify({
value: data,
table: tableName,
action: "insert",
antiForgery: (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : ""
})
};
},
update: function (dm, keyField, value, tableName) {
this.setValue(value);
ej.JsonAdaptor.prototype.update(dm, keyField, value, tableName);
return {
type: "POST",
url: dm.dataSource.updateUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: JSON.stringify({
value: value,
action: "update",
keyColumn: keyField,
key: value[keyField],
table: tableName,
antiForgery: (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : ""
})
};
}
});
$.extend(this, new foreignObj());
return this;
}
ej.remoteSaveAdaptor = new ej.JsonAdaptor().extend({
beforeSend: ej.UrlAdaptor.prototype.beforeSend,
insert: ej.UrlAdaptor.prototype.insert,
update: ej.UrlAdaptor.prototype.update,
remove: ej.UrlAdaptor.prototype.remove,
addParams: ej.UrlAdaptor.prototype.addParams,
batchRequest: function (dm, changes, e, query) {
var res = {
changed: changes.changed,
added: changes.added,
deleted: changes.deleted,
action: "batch",
table: e.url,
key: e.key,
antiForgery: (dm.dataSource.antiForgery) ? dm.antiForgeryToken().value : ""
};
if (query)
this.addParams({ dm: dm, query: query, params: query._params, reqParams: res });
return {
type: "POST",
url: dm.dataSource.batchUrl || dm.dataSource.crudUrl || dm.dataSource.url,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(res)
};
},
processResponse: function (data, ds, query, xhr, request, changes, key) {
if(!ej.isNullOrUndefined(changes)){
if (data.d)
data = data.d;
if(data.added)changes.added = ej.parseJSON(data.added);
if(data.changed)changes.changed = ej.parseJSON(data.changed);
if(data.deleted)changes.deleted = ej.parseJSON(data.deleted);
var i;
for (i = 0; i < changes.added.length; i++)
ej.JsonAdaptor.prototype.insert(ds, changes.added[i]);
for (i = 0; i < changes.changed.length; i++)
ej.JsonAdaptor.prototype.update(ds, key, changes.changed[i]);
for (i = 0; i < changes.deleted.length; i++)
ej.JsonAdaptor.prototype.remove(ds, key, changes.deleted[i]);
return data;
}
else{
if (data.d)
return data.d;
return data;
}
}
});
ej.WebApiAdaptor = new ej.ODataAdaptor().extend({
insert: function (dm, data, tableName) {
return {
type: "POST",
url: dm.dataSource.url,
data: JSON.stringify(data)
};
},
remove: function (dm, keyField, value, tableName) {
return {
type: "DELETE",
url: dm.dataSource.url + "/" + value,
data: JSON.stringify(value)
};
},
update: function (dm, keyField, value, tableName) {
return {
type: "PUT",
url: dm.dataSource.url,
data: JSON.stringify(value)
};
},
batchRequest: function (dm, changes, e) {
var initialGuid = e.guid = ej.getGuid(oData.batchPre);
var req = [];
//insertion
$.each(changes.added, function (i, d) {
req.push('--' + initialGuid);
req.push('Content-Type: application/http; msgtype=request', '');
req.push('POST' + ' ' + dm.dataSource.insertUrl + ' HTTP/1.1');
req.push('Content-Type: ' + 'application/json; charset=utf-8');
req.push('Host: ' + location.host);
req.push('', d ? JSON.stringify(d) : '');
});
//updation
$.each(changes.changed, function (i, d) {
req.push('--' + initialGuid);
req.push('Content-Type: application/http; msgtype=request', '');
req.push('PUT' + ' ' + dm.dataSource.updateUrl + ' HTTP/1.1');
req.push('Content-Type: ' + 'application/json; charset=utf-8');
req.push('Host: ' + location.host);
req.push('', d ? JSON.stringify(d) : '');
});
//deletion
$.each(changes.deleted, function (i, d) {
req.push('--' + initialGuid);
req.push('Content-Type: application/http; msgtype=request', '');
req.push('DELETE' + ' ' + dm.dataSource.removeUrl +"/"+ d[e.key] + ' HTTP/1.1');
req.push('Content-Type: ' + 'application/json; charset=utf-8');
req.push('Host: ' + location.host);
req.push('', d ? JSON.stringify(d) : '');
});
req.push('--' + initialGuid + '--', '');
return {
type: 'POST',
url: dm.dataSource.batchUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: req.join('\r\n'),
contentType: 'multipart/mixed; boundary="' + initialGuid + '"',
};
},
processResponse: function (data, ds, query, xhr, request, changes) {
var pvt = request && request.ejPvtData;
if (request && request.type.toLowerCase() != "post") {
var version = xhr && xhr.getResponseHeader("DataServiceVersion"), count = null, aggregateResult = {};
version = (version && parseInt(version, 10)) || 2;
if (query && query._requiresCount) {
if (!isNull(data.Count)) count = data.Count;
}
if (version < 3 && data.Items) data = data.Items;
if (pvt && pvt.aggregates && pvt.aggregates.length) {
var agg = pvt.aggregates, args = {}, fn, res = {};
for (var i = 0; i < agg.length; i++) {
fn = ej.aggregates[agg[i].type];
if (fn)
res[agg[i].field + " - " + agg[i].type] = fn(data, agg[i].field);
}
aggregateResult = res;
}
if (pvt && pvt.groups && pvt.groups.length) {
var groups = pvt.groups;
for (var i = 0; i < groups.length; i++) {
var format = getColFormat(groups[i], query.queries);
data = ej.group(data, groups[i], pvt.aggregates, format);
}
}
return isNull(count) ? data : { result: data, count: count, aggregates: aggregateResult };
}
}
});
var getValue = function (value, inst) {
if (typeof value === "function")
return value.call(inst || {});
return value;
}
ej.TableModel = function (name, jsonArray, dataManager, modelComputed) {
if (!instance(this, ej.TableModel))
return new ej.TableModel(jsonArray);
if (!instance(jsonArray, Array))
throwError("ej.TableModel - Json Array is required");
var rows = [], model, dirtyFn = $proxy(setDirty, this);
for (var i = 0; i < jsonArray.length; i++) {
model = new ej.Model(jsonArray[i], this);
model.state = "unchanged";
model.on("stateChange", dirtyFn);
if (modelComputed)
model.computes(modelComputed);
rows.push(model);
}
this.name = name || "table1";
this.rows = ej.NotifierArray(rows);
this._deleted = [];
this._events = $({});
this.dataManager = dataManager;
this._isDirty = false;
return this;
};
ej.TableModel.prototype = {
on: function (eventName, handler) {
this._events.on(eventName, handler);
},
off: function (eventName, handler) {
this._events.off(eventName, handler);
},
setDataManager: function (dataManager) {
this.dataManagar = dataManager;
},
saveChanges: function () {
if (!this.dataManager || !instance(this.dataManager, ej.DataManager))
throwError("ej.TableModel - saveChanges : Set the dataManager using setDataManager function");
if (!this.isDirty())
return;
var promise = this.dataManager.saveChanges(this.getChanges(), this.key, this.name);
promise.done($proxy(function (changes) {
var rows = this.toArray();
for (var i = 0; i < rows.length; i++) {
if (rows.state === "added") {
rows.set(this.key, changes.added.filter(function (e) {
return e[this.key] === rows.get(this.key);
})[0][this.key]);
}
rows[i].markCommit();
}
this._events.triggerHandler({ type: "save", table: this });
}, this));
promise.fail($proxy(function (e) {
this.rejectChanges();
this._events.triggerHandler({ type: "reject", table: this, error: e });
}, this));
this._isDirty = false;
},
rejectChanges: function () {
var rows = this.toArray();
for (var i = 0; i < rows.length; i++)
rows[i].revert(true);
this._isDirty = false;
this._events.triggerHandler({ type: "reject", table: this });
},
insert: function (json) {
var model = new ej.Model(json);
model._isDirty = this._isDirty = true;
this.rows.push(model);
this._events.triggerHandler({ type: "insert", model: model, table: this });
},
update: function (value) {
if (!this.key)
throwError("TableModel - update : Primary key should be assigned to TableModel.key");
var row = value, model, key = this.key, keyValue = row[key];
model = this.rows.array.filter(function (obj) {
return obj.get(key) === keyValue;
});
model = model[0];
for (var col in row) {
model.set(col, row[col]);
}
this._isDirty = true;
this._events.triggerHandler({ type: "update", model: model, table: this });
},
remove: function (key) {
if (!this.key)
throwError("TableModel - update : Primary key should be assigned to TableModel.key");
var field = this.key;
var index = -1, model;
if (key && typeof key === "object") {
key = key[field] !== undefined ? key[field] : key.get(field);
}
for (var i = 0; i < this.rows.length() ; i++) {
if (this.rows.array[i].get(field) === key) {
index = i;
break;
}
}
if (index > -1) {
model = this.rows.removeAt(index);
model.markDelete();
this._deleted.push({ model: model, position: index });
this._isDirty = true;
this._events.triggerHandler({ type: "remove", model: model, table: this });
}
},
isDirty: function () {
return this._isDirty;
},
getChanges: function () {
var changes = {
added: [],
changed: []
};
var rows = this.toArray();
for (var i = 0; i < rows.length; i++) {
if (changes[rows[i].state])
changes[rows[i].state].push(rows[i].json);
}
changes.deleted = ej.select(this._deleted, ["model"]);
return changes;
},
toArray: function () {
return this.rows.toArray();
},
setDirty: function (dirty, model) {
if (this._isDirty === !!dirty) return;
this._isDirty = !!dirty;
this._events.triggerHandler({ type: "dirty", table: this, model: model });
},
get: function (index) {
return this.rows.array[index];
},
length: function () {
return this.rows.array.length;
},
bindTo: function (element) {
var marker = tDiv, template = $(element.html()), rows = this.toArray(), cur;
if ($.inArray(element.prop("tagName").toLowerCase(), ["table", "tbody"]))
marker = tTR;
marker.insertBefore(element);
element.detach().empty();
for (var i = 0; i < rows.length; i++) {
cur = template.clone();
rows[i].bindTo(cur);
element.append(cur);
}
element.insertAfter(marker);
marker.remove();
}
};
var tDiv = doc ? $(document.createElement("div")) : {},
tTR = doc ? $(document.createElement("tr")) : {};
ej.Model = function (json, table, name) {
if (typeof table === "string") {
name = table;
table = null;
}
this.$id = getUid("m");
this.json = json;
this.table = table instanceof ej.TableModel ? table : null;
this.name = name || (this.table && this.table.name);
this.dataManager = (table instanceof ej.DataManager) ? table : table.dataManagar;
this.actual = {};
this._events = $({});
this.isDirty = false;
this.state = "added";
this._props = [];
this._computeEls = {};
this._fields = {};
this._attrEls = {};
this._updates = {};
this.computed = {};
};
ej.Model.prototype = {
computes: function (value) {
$.extend(this.computed, value);
},
on: function (eventName, handler) {
this._events.on(eventName, handler);
},
off: function (eventName, handler) {
this._events.off(eventName, handler);
},
set: function (field, value) {
var obj = this.json, actual = field, prev;
field = field.split('.');
for (var i = 0; i < field.length - 1; i++) {
field = field[0];
obj = obj[field[0]];
}
this.isDirty = true;
this.changeState("changed", { from: "set" });
prev = obj[field];
if (this.actual[field] === undefined && !(field in this.actual))
this.actual[field] = value; // Complex property ?
obj[field] = value;
this._updateValues(field, value);
this._events.triggerHandler({ type: actual, current: value, previous: prev, model: this });
},
get: function (field) {
return ej.pvt.getObject(field, this.json);
},
revert: function (suspendEvent) {
for (var prop in this.actual) {
this.json[prop] = this.actual[prop];
}
this.isDirty = false;
if (suspendEvent)
this.state = "unchanged";
else
this.changeState("unchanged", { from: "revert" });
},
save: function (dm, key) {
dm = dm || this.dataManagar;
key = key || dm.dataSource.key;
if (!dm) throwError("ej.Model - DataManager is required to commit the changes");
if (this.state === "added") {
return dm.insert(this.json, this.name).done(ej.proxy(function (e) {
$.extend(this.json, e.record);
}, this));
}
else if (this.state === "changed") {
return dm.update(key, this.json, this.name);
}
else if (this.state === "deleted") {
return dm.remove(key, this.json, this.name);
}
},
markCommit: function () {
this.isDirty = false;
this.changeState("unchanged", { from: "commit" });
},
markDelete: function () {
this.changeState("deleted", { from: "delete" });
},
changeState: function (state, args) {
if (this.state === state) return;
if (this.state === "added") {
if (state === "deleted")
state = "unchanged";
else return;
}
var prev = state;
args = args || {};
this.state = state;
this._events.triggerHandler($.extend({ type: "stateChange", current: state, previous: prev, model: this }, args));
},
properties: function () {
if (this._props.length)
return this._props;
for (var pr in this.json) {
this._props.push(pr);
this._updates[pr] = { read: [], input: [] };
}
return this._props;
},
bindTo: function (element) {
var el = $(element), ctl, field,
elements = el.find("[ej-observe], [ej-computed], [ej-prop]"), len = elements.length;
el.data("ejModel", this);
var unbindData = { fields: [], props: [], computes: [] };
for (var i = 0; i < len; i++) {
ctl = elements.eq(i);
field = ctl.attr("ej-prop");
if (field) {
this._processAttrib(field, ctl, unbindData);
}
field = ctl.attr("ej-observe");
if (field && this._props.indexOf(field) !== -1) {
this._processField(ctl, field, unbindData);
continue;
}
field = ctl.attr("ej-computed");
if (field) {
this._processComputed(field, ctl, unbindData);
continue;
}
}
el.data("ejModelBinding" + this.$id, unbindData);
},
unbind: function (element) {
var tmp, data = {
props: this._attrEls,
computes: this._computeEls
}, isCustom = false;
if (element) {
data = $(element).removeData("ejModel").data("ejModelBinding" + this.$id) || data;
isCustom = true;
}
for (var p in this.computed) {
tmp = data.computes[p], p = this.computed[p];
if (tmp && p.deps) {
this.off(p.deps.join(' '), tmp.handle);
if (isCustom)
delete this._computeEls[p];
}
}
if (!isCustom)
this._computeEls = {};
for (var p in data.props) {
tmp = data.props[p];
if (tmp) {
this.off(tmp.deps.join(' '), tmp.handle);
delete data.props[p];
if (isCustom)
delete this._attrEls[p];
}
}
if (!isCustom)
this._attrEls = {};
if (data.fields && data.fields.length) {
var len = data.fields.length, ctl, idx, ty;
for (var i = 0; i < len; i++) {
ctl = data.fields[i];
$(ctl).off("change", null, this._changeHandler);
ty = this.formElements.indexOf(ctl.tagName.toLowerCase()) !== -1 ? "input" : "read";
idx = this._updates[ty].indexOf(ctl);
if (idx !== -1)
this._updates[ty].splice(idx, 1);
}
}
},
_processComputed: function (value, element, data) {
if (!value) return;
var val, deps, safeVal = safeStr(value),
type = this.formElements.indexOf(element[0].tagName.toLowerCase()) !== -1 ? "val" : "html";
if (!this.computed[value] || !this.computed[safeVal]) {
this.computed[safeVal] = {
value: new Function("var e = this; return " + value),
deps: this._generateDeps(value)
}
value = safeVal;
}
val = this.computed[value];
if (!val.get) {
val.get = function () {
val.value.call(this.json);
}
}
deps = val.deps;
val = val.value;
this._updateDeps(deps);
this._updateElement(element, type, val);
val = { el: element, handle: $proxy(this._computeHandle, this, { value: value, type: type }) };
this._computeEls[value] = val;
data.computes[value] = val;
this.on(deps.join(' '), val.handle);
},
_computeHandle: function (e) {
var el = this._computeEls[e.value];
if (el && this.computed[e.value])
this._updateElement(el.el, e.type, this.computed[e.value].value);
},
_updateElement: function (el, type, val) {
el[type](val.call($.extend({}, this.json, this.computed)));
},
_updateDeps: function (deps) {
for (var i = 0; i < deps.length; i++) {
if (!(deps[i] in this.json) && deps[i] in this.computed)
ej.merge(deps, this.computed[deps[i]].deps);
}
},
_generateDeps: function (value) {
var splits = value.replace(/(^e\.)|( e\.)/g, '#%^*##ej.#').split("#%^*#"),
field, deps = [];
for (var i = 0; i < splits.length; i++) {
if (splits[i].startsWith("#ej.#")) {
field = splits[i].replace("#ej.#", "").split(' ')[0];
if (field && this._props.indexOf(field) !== -1)
deps.push(field);
}
}
return deps;
},
_processAttrib: function (value, el, data) {
var prop, val, res = {};
value = value.replace(/^ +| +$/g, "").split(";");
for (var i = 0; i < value.length; i++) {
value[i] = value[i].split(":");
if (value[i].length < 2) continue;
prop = value[i][0].replace(/^ +| +$/g, "").replace(/^'|^"|'$|"$/g, "");
res[prop] = value[i][1].replace(/^ +| +$/g, "").replace(/^'|^"|'$|"$/g, "");
}
value = res;
var deps = [];
for (prop in value)
deps.push(value[prop]);
this._updateDeps(deps);
this._updateProps(el, value);
res = getUid("emak");
val = { el: el, handle: $proxy(this._attrHandle, this, res), value: value, deps: deps };
el.prop("ejmodelattrkey", res);
data.props[res] = val;
this._attrEls[res] = val;
this.on(deps.join(' '), val.handle);
},
_attrHandle: function (res) {
var el = this._attrEls[res];
if (el)
this._updateProps(el.el, el.value);
},
_updateProps: function (element, value) {
var json = this.json, t, c = this.computed;
for (var prop in value) {
t = value[prop];
if (t in json)
t = json[t];
else if (t in c) {
t = c[t];
if (t) {
t = t.value.call($.extend({}, this.json, c));
}
}
if (!isNull(t)) {
element.prop(prop, t);
}
}
},
_updateValues: function (prop, value) {
var arr = this._updates[prop];
if (!arr || (!arr.read && !arr.input)) return;
this._ensureItems(arr.read, "html", value);
this._ensureItems(arr.input, "val", value);
},
_ensureItems: function (a, type, value) {
if (!a) return;
for (var i = a.length - 1; i > -1; i--) {
if (!a[i].offsetParent) {
a.splice(i, 1);
continue;
}
$(a[i])[type](value);
}
},
_changeHandler: function (e) {
e.data.self.set(e.data.prop, $(this).val());
},
_processField: function (ctl, field, data) {
var e = { self: this, prop: field }, val = this.get(field);
data.fields.push(ctl[0]);
if (this.formElements.indexOf(ctl[0].tagName.toLowerCase()) === -1) {
ctl.html(val);
return this._updates[field].read.push(ctl[0]);
}
ctl.val(val)
.off("change", null, this._changeHandler)
.on("change", null, e, this._changeHandler);
return this._updates[field].input.push(ctl[0]);
},
formElements: ["input", "select", "textarea"]
};
var safeReg = /[^\w]+/g;
var safeStr = function (value) {
return value.replace(safeReg, "_");
};
var setDirty = function (e) {
this.setDirty(true, e.model);
};
ej.Predicate = function (field, operator, value, ignoreCase) {
if (!(this instanceof ej.Predicate))
return new ej.Predicate(field, operator, value, ignoreCase);
if (typeof field === "string") {
var checkAny = "";
if(operator.toLowerCase().indexOf(" any") != -1) {
operator = operator.replace(" any","");
checkAny = "any";
}
else if(operator.toLowerCase().indexOf(" all") != -1) {
operator = operator.replace(" all","");
checkAny = "all";
}
this.field = field;
this.operator = operator;
this.value = value;
this.ignoreCase = ignoreCase;
this.isComplex = false;
this.anyCondition = checkAny;
this._comparer = ej.data.fnOperators.processOperator(checkAny != "" ? checkAny:this.operator);
} else if (field instanceof ej.Predicate && value instanceof ej.Predicate || value instanceof Array) {
this.isComplex = true;
this.condition = operator.toLowerCase();
this.predicates = [field];
if (value instanceof Array)
[].push.apply(this.predicates, value);
else
this.predicates.push(value);
}
return this;
};
ej.Predicate.and = function () {
return pvtPredicate._combinePredicates([].slice.call(arguments, 0), "and");
};
ej.Predicate.or = function () {
return pvtPredicate._combinePredicates([].slice.call(arguments, 0), "or");
};
ej.Predicate.fromJSON = function (json) {
if (instance(json, Array)) {
var res = [];
for (var i = 0, len = json.length; i < len; i++)
res.push(pvtPredicate._fromJSON(json[i]));
return res;
}
return pvtPredicate._fromJSON(json);
};
// Private fn
var pvtPredicate = {
_combinePredicates: function (predicates, operator) {
if (!predicates.length) return undefined;
if (predicates.length === 1) {
if (!instance(predicates[0], Array))
return predicates[0];
predicates = predicates[0];
}
return new ej.Predicate(predicates[0], operator, predicates.slice(1));
},
_combine: function (pred, field, operator, value, condition, ignoreCase) {
if (field instanceof ej.Predicate)
return ej.Predicate[condition](pred, field);
if (typeof field === "string")
return ej.Predicate[condition](pred, new ej.Predicate(field, operator, value, ignoreCase));
return throwError("Predicate - " + condition + " : invalid arguments");
},
_fromJSON: function (json) {
if (!json || instance(json, ej.Predicate))
return json;
var preds = json.predicates || [], len = preds.length, predicates = [], result;
for (var i = 0; i < len; i++)
predicates.push(pvtPredicate._fromJSON(preds[i]));
if(!json.isComplex)
result = new ej.Predicate(json.field, json.operator, ej.parseJSON({ val: json.value }).val, json.ignoreCase);
else
result = new ej.Predicate(predicates[0], json.condition, predicates.slice(1));
return result;
}
};
ej.Predicate.prototype = {
and: function (field, operator, value, ignoreCase) {
return pvtPredicate._combine(this, field, operator, value, "and", ignoreCase);
},
or: function (field, operator, value, ignoreCase) {
return pvtPredicate._combine(this, field, operator, value, "or", ignoreCase);
},
validate: function (record) {
var p = this.predicates, isAnd, ret;
if (!this.isComplex) {
return this._comparer.call(this, ej.pvt.getObject(this.field, record), this.value, this.ignoreCase);
}
isAnd = this.condition === "and";
for (var i = 0; i < p.length; i++) {
ret = p[i].validate(record);
if (isAnd) {
if (!ret) return false;
} else {
if (ret) return true;
}
}
return isAnd;
},
toJSON: function () {
var predicates, p;
if (this.isComplex) {
predicates = [], p = this.predicates;
for (var i = 0; i < p.length; i++)
predicates.push(p[i].toJSON());
}
return {
isComplex: this.isComplex,
field: this.field,
operator: this.operator,
value: this.value,
ignoreCase: this.ignoreCase,
condition: this.condition,
predicates: predicates,
anyCondition: this.anyCondition
}
}
};
ej.dataUtil = {
swap: function (array, x, y) {
if (x == y) return;
var tmp = array[x];
array[x] = array[y];
array[y] = tmp;
},
mergeSort: function (jsonArray, fieldName, comparer) {
if (!comparer || typeof comparer === "string")
comparer = ej.pvt.fnSort(comparer, true);
if (typeof fieldName === "function") {
comparer = fieldName;
fieldName = null;
}
return ej.pvt.mergeSort(jsonArray, fieldName, comparer);
},
max: function (jsonArray, fieldName, comparer) {
if (typeof fieldName === "function") {
comparer = fieldName;
fieldName = null;
}
return ej.pvt.getItemFromComparer(jsonArray, fieldName, comparer || ej.pvt.fnDescending);
},
min: function (jsonArray, fieldName, comparer) {
if (typeof fieldName === "function") {
comparer = fieldName;
fieldName = null;
}
return ej.pvt.getItemFromComparer(jsonArray, fieldName, comparer || ej.pvt.fnAscending);
},
distinct: function (json, fieldName, requiresCompleteRecord) {
var result = [], val, tmp = {};
for (var i = 0; i < json.length; i++) {
val = getVal(json, fieldName, i);
if (!(val in tmp)) {
result.push(!requiresCompleteRecord ? val : json[i]);
tmp[val] = 1;
}
}
return result;
},
sum: function (json, fieldName) {
var result = 0, val, castRequired = typeof getVal(json, fieldName, 0) !== "number";
for (var i = 0; i < json.length; i++) {
val = getVal(json, fieldName, i);
if (!isNaN(val) && val !== null) {
if (castRequired)
val = +val;
result += val;
}
}
return result;
},
avg: function (json, fieldName) {
return ej.sum(json, fieldName) / json.length;
},
select: function (jsonArray, fields) {
var newData = [];
for (var i = 0; i < jsonArray.length; i++) {
newData.push(ej.pvt.extractFields(jsonArray[i], fields));
}
return newData;
},
group: function (jsonArray, field, agg, format,/* internal */ level,groupDs) {
level = level || 1;
if (jsonArray.GROUPGUID == ej.pvt.consts.GROUPGUID) {
for (var j = 0; j < jsonArray.length; j++) {
if(!ej.isNullOrUndefined(groupDs)){
var indx = -1;
var temp = $.grep(groupDs,function(e){return e.key==jsonArray[j].key});
indx = groupDs.indexOf(temp[0]);
jsonArray[j].items = ej.group(jsonArray[j].items, field, agg, format, jsonArray.level + 1, groupDs[indx].items);
jsonArray[j].count = groupDs[indx].count;
}
else{
jsonArray[j].items = ej.group(jsonArray[j].items, field, agg, format, jsonArray.level + 1);
jsonArray[j].count = jsonArray[j].items.length;
}
}
jsonArray.childLevels += 1;
return jsonArray;
}
var grouped = {}, groupedArray = [];
groupedArray.GROUPGUID = ej.pvt.consts.GROUPGUID;
groupedArray.level = level;
groupedArray.childLevels = 0;
groupedArray.records = jsonArray;
for (var i = 0; i < jsonArray.length; i++) {
var val = getVal(jsonArray, field, i);
if (!ej.isNullOrUndefined(format)) val = format(val, field);
if (!grouped[val]) {
grouped[val] = {
key: val,
count: 0,
items: [],
aggregates: {},
field: field
};
groupedArray.push(grouped[val]);
if(!ej.isNullOrUndefined(groupDs)) {
var tempObj = $.grep(groupDs,function(e){return e.key==grouped[val].key});
grouped[val].count = tempObj[0].count
}
}
grouped[val].count = !ej.isNullOrUndefined(groupDs) ? grouped[val].count : grouped[val].count += 1;
grouped[val].items.push(jsonArray[i]);
}
if (agg && agg.length) {
for (var i = 0; i < groupedArray.length; i++) {
var res = {}, fn;
for (var j = 0; j < agg.length; j++) {
fn = ej.aggregates[agg[j].type];
if(!ej.isNullOrUndefined(groupDs)) {
var temp = $.grep(groupDs,function(e){return e.key==groupedArray[i].key});
if(fn)
res[agg[j].field + " - " + agg[j].type] = fn(temp[0].items, agg[j].field);
}
else{
if (fn)
res[agg[j].field + " - " + agg[j].type] = fn(groupedArray[i].items, agg[j].field);
}
}
groupedArray[i]["aggregates"] = res;
}
}
return groupedArray;
},
parseTable: function (table, headerOption, headerRowIndex) {
var tr = table.rows, headerRow, headerTds = [], data = [], i;
if (!tr.length) return [];
headerRowIndex = headerRowIndex || 0;
switch ((headerOption || "").toLowerCase()) {
case ej.headerOption.tHead:
headerRow = table.tHead.rows[headerRowIndex];
break;
case ej.headerOption.row:
default:
headerRow = table.rows[headerRowIndex];
break;
}
var hTd = headerRow.cells;
for (i = 0; i < hTd.length; i++)
headerTds.push($.trim(hTd[i].innerHTML));
for (i = headerRowIndex + 1; i < tr.length; i++) {
var json = {}, td = tr[i].cells;
for (var j = 0; j < td.length; j++) {
var temp = td[j].innerHTML;
if (typeof temp == "string" && $.isNumeric(temp))
json[headerTds[j]] = Number(temp);
else
json[headerTds[j]] = temp;
}
data.push(json);
}
return data;
}
};
ej.headerOption = {
tHead: "thead",
row: "row"
};
ej.aggregates = {
sum: function (ds, field) {
return ej.sum(ds, field);
},
average: function (ds, field) {
return ej.avg(ds, field);
},
minimum: function (ds, field) {
return ej.getObject(field, ej.min(ds, field));
},
maximum: function (ds, field) {
return ej.getObject(field, ej.max(ds, field));
},
truecount: function (ds, field){
var predicate = ej.Predicate(field, "equal", true);
return ej.DataManager(ds).executeLocal(ej.Query().where(predicate)).length;
},
falsecount: function (ds, field) {
var predicate = ej.Predicate(field, "equal", false);
return ej.DataManager(ds).executeLocal(ej.Query().where(predicate)).length;
},
count: function (ds, field) {
return ds.length;
}
};
ej.pvt = {
filterQueries: filterQueries,
mergeSort: function (jsonArray, fieldName, comparer) {
if (jsonArray.length <= 1)
return jsonArray;
// else list size is > 1, so split the list into two sublists
var middle = parseInt(jsonArray.length / 2, 10);
var left = jsonArray.slice(0, middle),
right = jsonArray.slice(middle);
left = ej.pvt.mergeSort(left, fieldName, comparer);
right = ej.pvt.mergeSort(right, fieldName, comparer);
return ej.pvt.merge(left, right, fieldName, comparer);
},
getItemFromComparer: function (array, field, comparer) {
var keyVal, current, key, i = 0,castRequired = typeof getVal(array, field, 0) == "string";
if (array.length)
while (ej.isNullOrUndefined(keyVal) && i < array.length) {
keyVal = getVal(array, field, i);
key = array[i++];
}
for (; i < array.length; i++) {
current = getVal(array, field, i);
if (ej.isNullOrUndefined(current))
continue;
if (castRequired) {
keyVal = +keyVal;
current = +current;
}
if (comparer(keyVal, current) > 0) {
keyVal = current;
key = array[i];
}
}
return key;
},
quickSelect: function (array, fieldName, left, right, k, comparer) {
if (left == right)
return array[left];
var pivotNewIndex = ej.pvt.partition(array, fieldName, left, right, comparer);
var pivotDist = pivotNewIndex - left + 1;
if (pivotDist == k)
return array[pivotNewIndex];
else if (k < pivotDist)
return ej.pvt.quickSelect(array, fieldName, left, pivotNewIndex - 1, k, comparer);
else
return ej.pvt.quickSelect(array, fieldName, pivotNewIndex + 1, right, k - pivotDist, comparer);
},
extractFields: function (obj, fields) {
var newObj = {};
if (fields.length == 1)
return ej.pvt.getObject(fields[0], obj);
for (var i = 0; i < fields.length; i++) {
newObj[fields[i].replace('.', ej.pvt.consts.complexPropertyMerge)] = ej.pvt.getObject(fields[i], obj);
}
return newObj;
},
partition: function (array, field, left, right, comparer) {
var pivotIndex = parseInt((left + right) / 2, 10),
pivot = getVal(array, field, pivotIndex);
ej.swap(array, pivotIndex, right);
pivotIndex = left;
for (var i = left; i < right; i++) {
if (comparer(getVal(array, field, i), pivot)) {
ej.swap(array, i, pivotIndex);
pivotIndex++;
}
}
ej.swap(array, pivotIndex, right);
return pivotIndex;
},
fnSort: function (order) {
order = order ? order.toLowerCase() : ej.sortOrder.Ascending;
if (order == ej.sortOrder.Ascending)
return ej.pvt.fnAscending;
return ej.pvt.fnDescending;
},
fnGetComparer: function (field, fn) {
return function (x, y) {
return fn(ej.pvt.getObject(field, x), ej.pvt.getObject(field, y));
}
},
fnAscending: function (x, y) {
if(ej.isNullOrUndefined(y) && ej.isNullOrUndefined(x))
return -1;
if (y === null || y === undefined)
return -1;
if (typeof x === "string")
return x.localeCompare(y);
if (x === null || x === undefined)
return 1;
return x - y;
},
fnDescending: function (x, y) {
if(ej.isNullOrUndefined(y) && ej.isNullOrUndefined(x))
return -1;
if (y === null || y === undefined)
return 1;
if (typeof x === "string")
return x.localeCompare(y) * -1;
if (x === null || x === undefined)
return -1;
return y - x;
},
merge: function (left, right, fieldName, comparer) {
var result = [], current;
while (left.length > 0 || right.length > 0) {
if (left.length > 0 && right.length > 0) {
if (comparer)
current = comparer(getVal(left, fieldName, 0), getVal(right, fieldName, 0)) <= 0 ? left : right;
else
current = left[0][fieldName] < left[0][fieldName] ? left : right;
} else {
current = left.length > 0 ? left : right;
}
result.push(current.shift());
}
return result;
},
getObject: function (nameSpace, from) {
if (!from) return undefined;
if (!nameSpace) return from;
if (nameSpace.indexOf('.') === -1) return from[nameSpace];
var value = from, splits = nameSpace.split('.');
for (var i = 0; i < splits.length; i++) {
if (value == null) break;
value = value[splits[i]];
}
return value;
},
createObject: function (nameSpace, value, initIn) {
var splits = nameSpace.split('.'), start = initIn || window, from = start, i;
for (i = 0; i < splits.length; i++) {
if (i + 1 == splits.length)
from[splits[i]] = value === undefined ? {} : value;
else if (from[splits[i]] == null)
from[splits[i]] = {};
from = from[splits[i]];
}
return start;
},
getFieldList: function (obj, fields, prefix) {
if (prefix === undefined)
prefix = "";
if (fields === undefined || fields === null)
return ej.pvt.getFieldList(obj, [], prefix);
for (var prop in obj) {
if (typeof obj[prop] === "object" && !(obj[prop] instanceof Array))
ej.pvt.getFieldList(obj[prop], fields, prefix + prop + ".");
else
fields.push(prefix + prop);
}
return fields;
}
};
ej.FilterOperators = {
lessThan: "lessthan",
greaterThan: "greaterthan",
lessThanOrEqual: "lessthanorequal",
greaterThanOrEqual: "greaterthanorequal",
equal: "equal",
contains: "contains",
startsWith: "startswith",
endsWith: "endswith",
notEqual: "notequal"
};
ej.data = {};
ej.data.operatorSymbols = {
"<": "lessthan",
">": "greaterthan",
"<=": "lessthanorequal",
">=": "greaterthanorequal",
"==": "equal",
"!=": "notequal",
"*=": "contains",
"$=": "endswith",
"^=": "startswith"
};
ej.data.odBiOperator = {
"<": " lt ",
">": " gt ",
"<=": " le ",
">=": " ge ",
"==": " eq ",
"!=": " ne ",
"lessthan": " lt ",
"lessthanorequal": " le ",
"greaterthan": " gt ",
"greaterthanorequal": " ge ",
"equal": " eq ",
"notequal": " ne ",
"in":" eq ",
"notin": " ne "
};
ej.data.odUniOperator = {
"$=": "endswith",
"^=": "startswith",
"*=": "substringof",
"endswith": "endswith",
"startswith": "startswith",
"contains": "substringof",
"notcontains":"substringof"
};
ej.data.fnOperators = {
equal: function (actual, expected, ignoreCase) {
if (ignoreCase)
return toLowerCase(actual) == toLowerCase(expected);
return actual == expected;
},
notequal: function (actual, expected, ignoreCase) {
return !ej.data.fnOperators.equal(actual, expected, ignoreCase);
},
notin: function (actual, expected, ignoreCase) {
for(var i = 0; i < expected.length; i++)
if(ej.data.fnOperators.notequal(actual, expected[i], ignoreCase) == false) return false;
return true;
},
lessthan: function (actual, expected, ignoreCase) {
if (ignoreCase)
return toLowerCase(actual) < toLowerCase(expected);
return actual < expected;
},
greaterthan: function (actual, expected, ignoreCase) {
if (ignoreCase)
return toLowerCase(actual) > toLowerCase(expected);
return actual > expected;
},
lessthanorequal: function (actual, expected, ignoreCase) {
if (ignoreCase)
return toLowerCase(actual) <= toLowerCase(expected);
return actual <= expected;
},
greaterthanorequal: function (actual, expected, ignoreCase) {
if (ignoreCase)
return toLowerCase(actual) >= toLowerCase(expected);
return actual >= expected;
},
contains: function (actual, expected, ignoreCase) {
if (ignoreCase)
return !isNull(actual) && !isNull(expected) && toLowerCase(actual).indexOf(toLowerCase(expected)) != -1;
return !isNull(actual) && !isNull(expected) && actual.toString().indexOf(expected) != -1;
},
notcontains: function (actual, expected, ignoreCase) {
return !ej.data.fnOperators.contains(actual, expected, ignoreCase);
},
notnull: function (actual) {
return actual !== null;
},
isnull: function (actual) {
return actual === null;
},
startswith: function (actual, expected, ignoreCase) {
if (ignoreCase)
return actual && expected && toLowerCase(actual).startsWith(toLowerCase(expected));
return actual && expected && actual.startsWith(expected);
},
endswith: function (actual, expected, ignoreCase) {
if (ignoreCase)
return actual && expected && toLowerCase(actual).endsWith(toLowerCase(expected));
return actual && expected && actual.endsWith(expected);
},
all: function (actual, expected, ignoreCase ) {
for(var i = 0; i < expected.length; i++)
if (ej.data.fnOperators[this.operator](actual, expected[i], ignoreCase) == false) return false;
return true;
},
any: function (actual, expected, ignoreCase ) {
for(var i = 0; i < expected.length; i++)
if (ej.data.fnOperators[this.operator](actual, expected[i], ignoreCase) == true) return true;
return false;
},
processSymbols: function (operator) {
var fnName = ej.data.operatorSymbols[operator];
if (fnName) {
var fn = ej.data.fnOperators[fnName];
if (fn) return fn;
}
return throwError("Query - Process Operator : Invalid operator");
},
processOperator: function (operator) {
var fn = ej.data.fnOperators[operator];
if (fn) return fn;
return ej.data.fnOperators.processSymbols(operator);
}
};
ej.data.fnOperators["in"] = function (actual, expected, ignoreCase) {
for(var i = 0; i < expected.length; i++)
if (ej.data.fnOperators.equal(actual, expected[i], ignoreCase) == true) return true;
return false;
};
ej.NotifierArray = function (array) {
if (!instance(this, ej.NotifierArray))
return new ej.NotifierArray(array);
this.array = array;
this._events = $({});
this._isDirty = false;
return this;
};
ej.NotifierArray.prototype = {
on: function (eventName, handler) {
this._events.on(eventName, handler);
},
off: function (eventName, handler) {
this._events.off(eventName, handler);
},
push: function (item) {
var ret;
if (instance(item, Array))
ret = [].push.apply(this.array, item);
else
ret = this.array.push(item);
this._raise("add", { item: item, index: this.length() - 1 });
return ret;
},
pop: function () {
var ret = this.array.pop();
this._raise("remove", { item: ret, index: this.length() - 1 });
return ret;
},
addAt: function (index, item) {
this.array.splice(index, 0, item);
this._raise("add", { item: item, index: index });
return item;
},
removeAt: function (index) {
var ret = this.array.splice(index, 1)[0];
this._raise("remove", { item: ret, index: index });
return ret;
},
remove: function (item) {
var index = this.array.indexOf(item);
if (index > -1) {
this.array.splice(index, 1);
this._raise("remove", { item: item, index: index });
}
return index;
},
length: function () {
return this.array.length;
},
_raise: function (e, args) {
this._events.triggerHandler($.extend({ type: e }, args));
this._events.triggerHandler({ type: "all", name: e, args: args });
},
toArray: function () {
return this.array;
}
};
$.extend(ej, ej.dataUtil);
// For IE8
Array.prototype.forEach = Array.prototype.forEach || function (fn, scope) {
for (var i = 0, len = this.length; i < len; ++i) {
fn.call(scope, this[i], i, this);
}
};
Array.prototype.indexOf = Array.prototype.indexOf || function (searchElement) {
var len = this.length;
if (len === 0) return -1;
for (var i = 0; i < len; i++) {
if (i in this && this[i] === searchElement)
return i;
}
return -1;
};
Array.prototype.filter = Array.prototype.filter || function (fn) {
if (typeof fn != "function")
throw new TypeError();
var res = [];
var thisp = arguments[1] || this;
for (var i = 0; i < this.length; i++) {
var val = this[i]; // in case fun mutates this
if (fn.call(thisp, val, i, this))
res.push(val);
}
return res;
};
String.prototype.endsWith = String.prototype.endsWith || function (key) {
return this.slice(-key.length) === key;
};
String.prototype.startsWith = String.prototype.startsWith || function (key) {
return this.slice(0, key.length) === key;
};
if (!ej.support) ej.support = {};
ej.support.stableSort = function () {
var res = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].sort(function () { return 0; });
for(var i = 0; i < 17; i++){
if(i !== res[i]) return false;
}
return true;
}();
ej.support.cors = $.support.cors;
if (!$.support.cors && window.XDomainRequest) {
var httpRegEx = /^https?:\/\//i;
var getOrPostRegEx = /^get|post$/i;
var sameSchemeRegEx = new RegExp('^' + location.protocol, 'i');
var xmlRegEx = /\/xml/i;
// ajaxTransport exists in jQuery 1.5+
$.ajaxTransport('text html xml json', function (options, userOptions, jqXHR) {
// XDomainRequests must be: asynchronous, GET or POST methods, HTTP or HTTPS protocol, and same scheme as calling page
if (options.crossDomain && options.async && getOrPostRegEx.test(options.type) && httpRegEx.test(userOptions.url) && sameSchemeRegEx.test(userOptions.url)) {
var xdr = null;
var userType = (userOptions.dataType || '').toLowerCase();
return {
send: function (headers, complete) {
xdr = new XDomainRequest();
if (/^\d+$/.test(userOptions.timeout)) {
xdr.timeout = userOptions.timeout;
}
xdr.ontimeout = function () {
complete(500, 'timeout');
};
xdr.onload = function () {
var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
var status = {
code: 200,
message: 'success'
};
var responses = {
text: xdr.responseText
};
try {
if (userType === 'json') {
try {
responses.json = JSON.parse(xdr.responseText);
} catch (e) {
status.code = 500;
status.message = 'parseerror';
//throw 'Invalid JSON: ' + xdr.responseText;
}
} else if ((userType === 'xml') || ((userType !== 'text') && xmlRegEx.test(xdr.contentType))) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = false;
try {
doc.loadXML(xdr.responseText);
} catch (e) {
doc = undefined;
}
if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) {
status.code = 500;
status.message = 'parseerror';
throw 'Invalid XML: ' + xdr.responseText;
}
responses.xml = doc;
}
} catch (parseMessage) {
throw parseMessage;
} finally {
complete(status.code, status.message, responses, allResponseHeaders);
}
};
xdr.onerror = function () {
complete(500, 'error', {
text: xdr.responseText
});
};
if(navigator.userAgent.indexOf("MSIE 9.0") != -1)
xdr.onprogress = function() {};
xdr.open(options.type, options.url);
xdr.send(userOptions.data);
//xdr.send();
},
abort: function () {
if (xdr) {
xdr.abort();
}
}
};
}
});
}
$.support.cors = true;
ej.sortOrder = {
Ascending: "ascending",
Descending: "descending"
};
// privates
ej.pvt.consts = {
GROUPGUID: "{271bbba0-1ee7}",
complexPropertyMerge: "_"
};
// private utils
var nextTick = function (fn, context) {
if (context) fn = $proxy(fn, context);
(window.setImmediate || window.setTimeout)(fn, 0);
};
ej.support.enableLocalizedSort = false;
var stableSort = function (ds, field, comparer, queries) {
if (ej.support.stableSort) {
if(!ej.support.enableLocalizedSort && typeof ej.pvt.getObject(field, ds[0] || {}) == "string"
&& (comparer === ej.pvt.fnAscending || comparer === ej.pvt.fnDescending)
&& queries.filter(function(e){return e.fn === "onSortBy";}).length === 1)
return fastSort(ds, field, comparer === ej.pvt.fnDescending);
return ds.sort(ej.pvt.fnGetComparer(field, comparer));
}
return ej.mergeSort(ds, field, comparer);
};
var getColFormat = function (field, query) {
var grpQuery = $.grep(query, function (args) { return args.fn == "onGroup" });
for (var grp = 0; grp < grpQuery.length; grp++) {
if (ej.getObject("fieldName", grpQuery[grp].e) == field) {
return ej.getObject("fn", grpQuery[grp].e);
}
}
};
var fastSort = function(ds, field, isDesc){
var old = Object.prototype.toString;
Object.prototype.toString = (field.indexOf('.') === -1) ? function(){
return this[field];
}:function(){
return ej.pvt.getObject(field, this);
};
ds = ds.sort();
Object.prototype.toString = old;
if(isDesc)
ds.reverse();
}
var toLowerCase = function (val) {
return val ? val.toLowerCase ? val.toLowerCase() : val.toString().toLowerCase() : (val === 0 || val === false) ? val.toString() : "";
};
var getVal = function (array, field, index) {
return field ? ej.pvt.getObject(field, array[index]) : array[index];
};
var isHtmlElement = function (e) {
return typeof HTMLElement === "object" ? e instanceof HTMLElement :
e && e.nodeType === 1 && typeof e === "object" && typeof e.nodeName === "string";
};
var instance = function (obj, element) {
return obj instanceof element;
};
var getTableModel = function (name, result, dm, computed) {
return function (tName) {
if (typeof tName === "object") {
computed = tName;
tName = null;
}
return new ej.TableModel(tName || name, result, dm, computed);
};
};
var getKnockoutModel = function (result) {
return function (computedObservables, ko) {
ko = ko || window.ko;
if (!ko) throwError("Knockout is undefined");
var model, koModels = [], prop, ob;
for (var i = 0; i < result.length; i++) {
model = {};
for (prop in result[i]) {
if (!prop.startsWith("_"))
model[prop] = ko.observable(result[i][prop]);
}
for (prop in computedObservables) {
ob = computedObservables[prop];
if ($.isPlainObject(ob)) {
if (!ob.owner) ob.owner = model;
ob = ko.computed(ob);
} else
ob = ko.computed(ob, model);
model[prop] = ob;
}
koModels.push(model);
}
return ko.observableArray(koModels);
};
};
var uidIndex = 0;
var getUid = function (prefix) {
uidIndex += 1;
return prefix + uidIndex;
};
ej.getGuid = function (prefix) {
var hexs = '0123456789abcdef', rand;
return (prefix || "") + '00000000-0000-4000-0000-000000000000'.replace(/0/g, function (val, i) {
if ("crypto" in window && "getRandomValues" in crypto) {
var arr = new Uint8Array(1)
window.crypto.getRandomValues(arr);
rand = arr[0] % 16|0
}
else rand = Math.random() * 16 | 0;
return hexs[i === 19 ? rand & 0x3 | 0x8 : rand];
});
};
var proxy = function (fn, context) {
return function () {
var args = [].slice.call(arguments, 0);
args.push(this);
return fn.apply(context || this, args);
};
};
var $proxy = function (fn, context, arg) {
if ('bind' in fn)
return arg ? fn.bind(context, arg) : fn.bind(context);
return function () {
var args = arg ? [arg] : []; args.push.apply(args, arguments);
return fn.apply(context || this, args);
};
};
ej.merge = function (first, second) {
if (!first || !second) return;
Array.prototype.push.apply(first, second);
};
var isNull = function (val) {
return val === undefined || val === null;
};
var throwError = function (er) {
try {
throw new Error(er);
} catch (e) {
throw e.message + "\n" + e.stack;
}
};
})(window.jQuery, window.Syncfusion, window.document);