This question is locked. New answers and comments are not allowed.
I'm using sqlite + jaydata + kendo in Icenium. I also uses Required.js. I know jaydata 1.3.1 doesn't work well with required.js. But after commenting out the first two lines of code, everything seems working great. Then I found this issue: asKendoDataSource doesn't work on iPhone. The code is simple, it looks like this:
[code] dataSource = scmsDb.WorkOffers.asKendoDataSource();
$("#listview").kendoMobileListView({
dataSource: dataSource,
template: $("#listviewHeadersTemplate").text()
});
});[/code]
It works well in Icenium Graphite simulator and Android devices.
It's hard for me to provide more details because I don't get any error message. It's just that the listview not binding. I'm hoping someone experience the same problem and know the answer. I'll also try on jaydata forum.
Thanks in advance.
Richard
[code] dataSource = scmsDb.WorkOffers.asKendoDataSource();
$("#listview").kendoMobileListView({
dataSource: dataSource,
template: $("#listviewHeadersTemplate").text()
});
});[/code]
It works well in Icenium Graphite simulator and Android devices.
It's hard for me to provide more details because I don't get any error message. It's just that the listview not binding. I'm hoping someone experience the same problem and know the answer. I'll also try on jaydata forum.
Thanks in advance.
Richard
5 Answers, 1 is accepted
0
Blake
Top achievements
Rank 1
answered on 27 Jul 2013, 05:33 PM
Have you made any discoveries? I'm running into the same issue.
0
Richard
Top achievements
Rank 1
answered on 27 Jul 2013, 09:07 PM
No luck.
0
Blake
Top achievements
Rank 1
answered on 28 Jul 2013, 05:39 AM
Just solved this with a simple fix. Apparently ios doesn't like "console.dir" so I commented them all out in the kendo.js file for the jaydatamodule. Here's my file that works.
// JayData 1.2.7
// Dual licensed under MIT and GPL v2
// Copyright JayStack Technologies (http://jaydata.org/licensing)
//
// JayData is a standards-based, cross-platform Javascript library and a set of
// practices to access and manipulate data from various online and offline sources.
//
// Credits:
// Hajnalka Battancs, Dániel József, János Roden, László Horváth, Péter Nochta
// Péter Zentai, Róbert Bónay, Szabolcs Czinege, Viktor Borza, Viktor Lázár,
// Zoltán Gyebrovszki, Gábor Dolla
//
// More info: http://jaydata.org
(
function
($data) {
var
oldProcessor = $data.Entity.inheritedTypeProcessor;
$data.kendo = {};
$data.kendo.BaseModelType = kendo.data.Model.define({
init:
function
(data) {
kendo.data.Model.fn.init.call(
this
, data);
}
});
var
kendoTypeMap = {
"$data.Blob"
:
"string"
,
"$data.String"
:
"string"
,
"$data.Boolean"
:
"boolean"
,
"$data.Integer"
:
"number"
,
"$data.Number"
:
"number"
,
"$data.Date"
:
"date"
}
$data.Entity.inheritedTypeProcessor =
function
(type) {
var
memberDefinitions = type.memberDefinitions;
function
getKendoTypeName(canonicType, pd) {
return
kendoTypeMap[canonicType] ||
'object'
;
};
function
createKendoModel(options) {
///<param name="options">Contains options.owningContextType if initialized in a scope of a context</param>
var
memberDefinitions = type.memberDefinitions,
fields = {};
//debugger;
function
getNullable(canonicType, pd) {
if
(canonicType ===
"$data.Boolean"
) {
//grid validation errs on requied/nonnull bools
return
true
;
}
return
pd.required !==
true
;
};
function
getRequired(canonicType, pd) {
if
(
"$data.Boolean"
=== canonicType) {
return
false
;
}
return
pd.required ||
"nullable"
in
pd ? !(pd.nullable) :
false
;
}
memberDefinitions
.getPublicMappedProperties()
.forEach(
function
(pd) {
var
canonicType = $data.Container.resolveName(pd.type);
//if (pd.dataType !== "Array" && !(pd.inverseProperty)) {
fields[pd.name] = {
//TODO
type: getKendoTypeName(canonicType, pd),
nullable: getNullable(canonicType, pd),
defaultValue: pd.defaultValue,
//nullable: false,
//nullable: "nullable" in pd ? pd.nullable : true,
editable: !pd.computed,
//defaultValue: true,
//defaultValue: 'abc',
//defaultValue: pd.type === "Edm.Boolean" ? false : undefined,
validation: {
required: getRequired(canonicType, pd)
}
}
//};
});
function
setInitialValue(obj, memDef) {
return
;
//if (!obj[memDef.name]) {
// function getDefault() {
// switch ($data.Container.resolveType(memDef.type)) {
// case $data.Number: return 0.0;
// case $data.Integer: return 0;
// case $data.Date: return new Date();
// case $data.Boolean: return false;
// }
// }
// obj[memDef.name] = getDefault();
//}
}
//console.dir(memberDefinitions.getPublicMappedMethods());
var
modelDefinition = {
fields: fields,
init:
function
(data) {
//console.dir(arguments);
var
ctxType = options && options.owningContextType || undefined;
var
contextSetTypes = [];
if
(options && options.owningContextType) {
contextSetTypes = options.owningContextType
.memberDefinitions
.getPublicMappedProperties()
.filter(
function
(pd) {
return
$data.Container.resolveType(pd.type) === $data.EntitySet })
.map(
function
(pd) {
return
$data.Container.resolveType(pd.elementType) });
}
var
newInstanceOptions = {
entityBuilder:
function
(instance, members) {
members.forEach(
function
(memberInfo) {
if
(!(memberInfo.key ===
true
) && (memberInfo.required ===
true
|| memberInfo.nullable ===
false
)) {
var
memberType = $data.Container.resolveType(memberInfo.type);
if
(memberType.isAssignableTo && memberType.isAssignableTo($data.Entity) && contextSetTypes.indexOf(memberType) === -1) {
//it's a complex property
var
_data;
if
(data) {
_data = data[memberInfo.name];
};
instance[memberInfo.name] =
new
memberType(_data, newInstanceOptions);
}
else
{
setInitialValue(instance, memberInfo);
}
}
});
}
}
var
jayInstance = data
instanceof
type ? data :
new
type(data, newInstanceOptions);
var
seed = jayInstance.initData;
var
feed = {};
//TODO create precompiled strategy
for
(
var
j
in
seed) {
var
md = type.getMemberDefinition(j);
var
seedValue = seed[j];
if
(seedValue
instanceof
$data.Entity) {
var
kendoInstance = seedValue.asKendoObservable();
feed[j] = kendoInstance;
}
else
if
(md && md.type ===
"Array"
) {
var
jayType = $data.Container.resolveType(md.elementType);
var
kendoType = jayType.asKendoModel();
var
feedValue =
new
kendo.data.ObservableArray(seed[j], kendoType);
feed[j] = feedValue;
}
else
{
feed[j] = seedValue;
}
}
var
self =
this
;
this
.innerInstance =
function
() {
return
jayInstance }
//kendo.data.Model.fn.init.call(this, feed);
$data.kendo.BaseModelType.fn.init.call(
this
, feed);
jayInstance.propertyChanged.attach(
function
(obj, propinfo) {
var
jay =
this
;
var
newValue = propinfo.newValue;
if
(!jay.changeFromKendo) {
newValue = newValue ? (newValue.asKendoObservable ? newValue.asKendoObservable() : newValue) : newValue;
jayInstance.changeFromJay =
true
;
self.set(propinfo.propertyName, propinfo.newValue);
delete
jayInstance.changeFromJay;
}
});
this
.bind(
"set"
,
function
(e) {
var
propName = e.field;
var
propNameParts = propName.split(
"."
);
jayInstance.changeFromKendo =
true
;
if
(propNameParts.length == 1) {
var
propValue = e.value;
if
(!jayInstance.changeFromJay) {
propValue = propValue.innerInstance ? propValue.innerInstance() : propValue;
jayInstance[propName] = propValue;
if
(options && options.autoSave) {
jayInstance.save();
}
}
}
else
{
var
rootProp = jayInstance[propNameParts[0]];
if
(rootProp
instanceof
$data.Entity) {
jayInstance[propNameParts[0]] = rootProp;
}
}
delete
jayInstance.changeFromKendo;
});
if
(options && options.newInstanceCallback) {
options.newInstanceCallback(jayInstance);
}
},
save:
function
() {
//console.log("item.save", this, arguments);
return
this
.innerInstance().save();
},
remove:
function
() {
return
this
.innerInstance().remove();
}
};
var
keyProperties = memberDefinitions.getKeyProperties();
switch
(keyProperties.length) {
case
0:
break
;
case
1:
modelDefinition.id = keyProperties[0].name;
break
;
default
:
console.warn(
"entity with multiple keys not supported"
);
break
;
}
console.log(
"md"
, modelDefinition);
var
returnValue = kendo.data.Model.define($data.kendo.BaseModelType, modelDefinition);
//returnValue.readAll
//TODO align with kendoui concept
//for (var j in returnValue.prototype.defaults) {
// returnValue.prototype.defaults[j] = undefined;
//}
//console.log("default", returnValue.prototype.defaults)
return
returnValue;
}
function
asKendoModel(options) {
var
cacheObject = options || type;
return
cacheObject.kendoModelType || (cacheObject.kendoModelType = createKendoModel(options));
}
function
asKendoObservable(instance, options) {
var
kendoModel = type.asKendoModel(options);
return
new
kendoModel(instance);
}
type.asKendoModel = asKendoModel;
//type.asKendoModelType = asKendoModel;
type.prototype.asKendoObservable =
function
(options) {
var
self =
this
;
var
kendoObservable = asKendoObservable(
this
, options);
return
kendoObservable;
}
function
r(value){
return
value ||
''
;
}
function
registerStoreAlias(type, options) {
if
(!options.provider)
return
;
var
key = r(options.databaseName) + r(options.tableName) + r(options.url) + r(options.apiUrl) + r(options.oDataServiceHost);
var
storeDef = {
provider: options.provider,
databaseName: options.databaseName,
tableName: options.tableName,
dataSource: options.url,
apiUrl: options.apiUrl,
oDataServiceHost: options.oDataServiceHost
};
Object.keys(storeDef).forEach(
function
(k) {
delete
options[k];
});
type.setStore(key, storeDef);
return
key;
}
type.asKendoDataSource =
function
(options, modelOptions, storeAlias) {
options = options || {};
var
mOptions = modelOptions || {};
var
salias = registerStoreAlias(type, options) || storeAlias;
var
token = $data.ItemStore._getStoreAlias(type, salias);
var
ctx = $data.ItemStore._getContextPromise(token, type);
var
set = ctx.getEntitySetFromElementType(type);
return
set.asKendoDataSource(options, mOptions);
};
if
(oldProcessor) {
oldProcessor(type);
}
}
$data.Queryable.addMember(
"asKendoColumns"
,
function
(columns) {
//console.log('col', this, arguments);
var
result = [];
columns = columns || {};
var
showComplex = columns[
'$showComplexFields'
] ===
true
;
delete
columns[
'$showComplexFields'
];
this
.defaultType
.memberDefinitions
.getPublicMappedProperties()
.forEach(
function
(pd) {
//if (pd.dataType !== "Array" && !(pd.inverseProperty)) {
if
(showComplex || kendoTypeMap[$data.Container.resolveName(pd.type)]) {
var
col = columns[pd.name] || {};
var
colD = { field: pd.name };
$.extend(colD, col)
result.push(colD);
}
//}
});
function
append(field) {
field = Array.isArray(field) ? field : [field];
var
result =
this
.concat(field);
return
prepareResult(result);
}
function
prepend(field) {
field = Array.isArray(field) ? field : [field];
var
result = field.concat(
this
);
return
prepareResult(result);
}
function
setColumn(colName, def) {
var
it =
this
.filter(
function
(item) {
return
item.field == colName })[0];
$.extend(it, def);
return
this
;
}
function
prepareResult(r) {
r.prepend = prepend;
r.append = append;
r.setColumn = setColumn;
return
r;
}
return
prepareResult(result);
//return ['id', 'Year', 'Manufacturer', { command: ["edit", "create", "destroy", "update"] }];
}),
//, { command: ["edit", "create", "destroy", "update"]}
$data.EntityContext.addProperty(
"EntitySetNames"
,
function
() {
var
self =
this
;
//var sets = Object.keys(self._entitySetReferences);
//return sets;
return
Object.keys(self._entitySetReferences).map(
function
(set) {
return
self._entitySetReferences[set].tableName;
});
});
$data.Queryable.addMember(
"asKendoModel"
,
function
(options) {
options.owningContextType = options.owningContextType ||
this
.entityContext.getType();
return
this
.defaultType.asKendoModel(options);
});
$data.Queryable.addMember(
"asKendoRemoteTransportClass"
,
function
(modelItemClass) {
var
self =
this
;
var
ctx = self.entityContext;
function
reset() {
ctx.stateManager.reset();
};
var
TransportClass = kendo.data.RemoteTransport.extend({
init:
function
() {
this
.items = [];
},
read:
function
(options) {
var
query = self;
query.entityContext.onReady().then(
function
() {
var
_this =
this
;
var
q = query;
var
sp = query.entityContext.storageProvider;
var
withInlineCount = query.entityContext.storageProvider.supportedSetOperations.withInlineCount;
var
withLength = (!withInlineCount) && query.entityContext.storageProvider.supportedSetOperations.length;
if
(withInlineCount) {
q = q.withInlineCount();
}
if
(options.data.filter) {
var
filter =
""
;
var
thisArg = {};
options.data.filter.filters.forEach(
function
(f, index) {
if
(index > 0) { filter += options.data.filter.logic ==
"or"
?
" || "
:
" && "
; }
//console.log(filter, f);
switch
(f.operator) {
case
'eq'
:
filter +=
"it."
+ f.field;
filter +=
" == this."
+ f.field;
break
;
case
'neq'
:
filter +=
"it."
+ f.field;
filter +=
" != this."
+ f.field;
break
;
case
'startswith'
:
filter +=
"it."
+ f.field;
filter +=
".startsWith(this."
+ f.field +
")"
;
break
;
case
'contains'
:
filter +=
"it."
+ f.field;
filter +=
".contains(this."
+ f.field +
")"
;
break
;
case
'doesnotcontain'
:
filter +=
"!"
;
filter +=
"it."
+ f.field;
filter +=
".contains(this."
+ f.field +
")"
;
break
;
case
'endswith'
:
filter +=
"it."
+ f.field;
filter +=
".endsWith(this."
+ f.field +
")"
;
break
;
case
'gte'
:
filter +=
"it."
+ f.field;
filter +=
" >= this."
+ f.field;
break
;
case
'gt'
:
filter +=
"it."
+ f.field;
filter +=
" > this."
+ f.field;
break
;
case
'lte'
:
filter +=
"it."
+ f.field;
filter +=
" <= this."
+ f.field;
break
;
case
'lt'
:
filter +=
"it."
+ f.field;
filter +=
" < this."
+ f.field;
break
;
default
:
console.log(
'unknown operator'
, f.operator);
break
;
}
thisArg[f.field] = f.value;
})
q = q.filter(filter, thisArg);
}
var
allItemsQ = q;
if
(options.data.sort) {
options.data.sort.forEach(
function
(s) {
q = q.order((s.dir ==
'desc'
?
"-"
:
""
) + s.field);
})
}
if
(options.data.skip) {
q = q.skip(options.data.skip);
}
if
(options.data.take) {
q = q.take(options.data.take);
}
//Data.defaultHttpClient.enableJsonpCallback = true;
var
promises = [];
promises.push(q.toArray());
//var ta = q.toArray();
if
(withLength) {
promises.push(allItemsQ.length());
}
else
if
(!withInlineCount) {
promises.push(allItemsQ.toArray());
}
console.log(promises);
jQuery.when.apply(
this
, promises).then(
function
(items, total) {
//console.dir(arguments);
//var result = items.map(function (item) { return item instanceof $data.Entity ? new model(item.initData) : item; });
var
result = items.map(
function
(item) {
var
d = (item
instanceof
$data.Entity) ? item.initData : item;
var
kendoItem = item.asKendoObservable();
return
kendoItem;
});
var
r = {
data: result,
total: withInlineCount ? items.totalCount : (withLength ? total : total.length)
}
console.log(r);
options.success(r);
}).fail(
function
() {
console.log(
"error in create"
);
options.error({}, arguments);
});
});
},
create:
function
(options, model) {
var
query = self;
query.entityContext.onReady().then(
function
() {
if
(model.length > 1) {
var
modelItems = [];
model.forEach(
function
(modelItem) {
modelItems.push(modelItem.innerInstance());
});
ctx.addMany(modelItems);
ctx.saveChanges().then(
function
() {
var
data = [];
modelItems.forEach(
function
(modelItem) {
data.push(modelItem.initData);
});
options.success({ data: data });
}).fail(
function
() {
console.log(
"error in create"
);
options.error({}, arguments);
ctx.stateManager.reset();
});
}
else
{
//console.log("save single");
//console.dir(ctx.storeToken);
model[0]
.innerInstance()
.save(ctx.storeToken)
.then(
function
() {
options.success({ data: model[0].innerInstance().initData });
})
.fail(
function
() {
console.log(
"error in create"
);
options.error({}, arguments);
});
}
});
},
update:
function
(options, model) {
//console.log("update");
//console.dir(arguments);
var
query = self;
query.entityContext.onReady().then(
function
() {
if
(model.length > 1) {
var
items = model.map(
function
(item) {
return
item.innerInstance() });
items.forEach(
function
(item) {
ctx.attach(item,
true
);
});
ctx.saveChanges().then(
function
() {
options.success();
}).fail(
function
() {
ctx.stateManager.reset();
//alert("error in batch update");
options.error({}, arguments);
});
}
else
{
model[0].innerInstance().save().then(
function
(item) {
options.success();
}).fail(
function
() {
//alert("error in update")
options.error({}, arguments);
});
}
});
},
destroy:
function
(options, model) {
var
query = self;
query.entityContext.onReady().then(
function
() {
if
(model.length > 1) {
model.forEach(
function
(item) {
ctx.remove(item.innerInstance());
});
ctx.saveChanges().then(
function
() {
options.success({ data: options.data });
}).fail(
function
() {
ctx.stateManager.reset();
//alert("error in save:" + arguments[0]);
options.error({},
"error"
, options.data);
});
}
else
{
model[0].innerInstance().remove().then(
function
() {
options.success({ data: options.data });
}).fail(
function
() {
ctx.stateManager.reset();
//alert("error in save:" + arguments[0]);
options.error({},
"error"
, options.data);
});
}
});
},
setup:
function
() {
console.log(
"setup"
);
//console.dir(arguments);
}
});
return
TransportClass;
});
var
jayDataSource = kendo.data.DataSource.extend({
init:
function
() {
kendo.data.DataSource.fn.init.apply(
this
, arguments);
},
createItem:
function
(initData) {
var
type =
this
.options.schema.model;
return
new
type(initData);
},
_promise:
function
(data, models, type) {
var
that =
this
,
extend = $.extend,
transport = that.transport;
return
$.Deferred(
function
(deferred) {
transport[type].call(transport, extend({
success:
function
(response) {
deferred.resolve({
response: response,
models: models,
type: type
});
},
error:
function
(response, status, error) {
deferred.reject(response);
that.error(response, status, error);
}
}, data), models
);
}).promise();
}
});
$data.kendo = $data.kendo || {};
$data.kendo.defaultPageSize = 25;
$data.Queryable.addMember(
"asKendoDataSource"
,
function
(ds, modelOptions) {
var
self =
this
;
modelOptions = modelOptions || {};
var
model = self.asKendoModel(modelOptions);
ds = ds || {};
//unless user explicitly opts out server side logic
//we just force it.
ds.serverPaging = ds.serverPaging ||
true
;
ds.serverFiltering = ds.serverFiltering ||
true
;
ds.serverSorting = ds.serverSorting ||
true
;
ds.pageSize = ds.pageSize === undefined ? $data.kendo.defaultPageSize : ds.pageSize;
var
TransportClass = self.asKendoRemoteTransportClass(model);
ds.transport =
new
TransportClass();
ds.schema = {
model: model,
data:
"data"
,
total:
"total"
};
return
new
jayDataSource(ds);
});
kendo.data.binders.submit = kendo.data.Binder.extend({
init:
function
(element, bindings, options) {
kendo.data.Binder.fn.init.call(
this
, element, bindings, options);
$(element).bind(
"submit"
,
function
() {
var
obj = bindings.submit.source;
var
fn = obj[bindings.submit.path];
if
(
typeof
fn ===
'function'
) {
fn.apply(obj, arguments);
return
false
;
}
});
},
refresh:
function
() {
}
});
})($data);
0
Richard
Top achievements
Rank 1
answered on 28 Jul 2013, 03:42 PM
Wonderful! I removed all "console.dir" statements from Kendo.min.js file and it worked on my iPhone. Thanks for your help. I have customized Jaydata.min.js to make it work with required.js. Now more customized code in Kendo.min.js. Getting messy!
0
Richard
Top achievements
Rank 1
answered on 28 Jul 2013, 03:43 PM
By the way, I'll also post the answer on JayData forum so that they can fix it in the next version.