4063 строки
149 KiB
JavaScript
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); |