159 lines
4.1 KiB
JavaScript
159 lines
4.1 KiB
JavaScript
|
dojo.provide("dojox.dtl.contrib.data");
|
||
|
dojo.require("dojox.dtl._base");
|
||
|
|
||
|
(function(){
|
||
|
var dd = dojox.dtl;
|
||
|
var ddcd = dd.contrib.data;
|
||
|
|
||
|
var first = true;
|
||
|
|
||
|
ddcd._BoundItem = dojo.extend(function(item, store){
|
||
|
this.item = item;
|
||
|
this.store = store;
|
||
|
},
|
||
|
{
|
||
|
get: function(key){
|
||
|
var store = this.store;
|
||
|
var item = this.item;
|
||
|
|
||
|
if(key == "getLabel"){
|
||
|
return store.getLabel(item);
|
||
|
}else if(key == "getAttributes"){
|
||
|
return store.getAttributes(item);
|
||
|
}else if(key == "getIdentity"){
|
||
|
if(store.getIdentity){
|
||
|
return store.getIdentity(item);
|
||
|
}
|
||
|
return "Store has no identity API";
|
||
|
}else{
|
||
|
if(!store.hasAttribute(item, key)){
|
||
|
if(key.slice(-1) == "s"){
|
||
|
if(first){
|
||
|
first = false;
|
||
|
dojo.deprecated("You no longer need an extra s to call getValues, it can be figured out automatically");
|
||
|
}
|
||
|
key = key.slice(0, -1);
|
||
|
}
|
||
|
if(!store.hasAttribute(item, key)){
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var values = store.getValues(item, key);
|
||
|
if(!values){
|
||
|
return;
|
||
|
}
|
||
|
if(!dojo.isArray(values)){
|
||
|
return new ddcd._BoundItem(values, store);
|
||
|
}
|
||
|
|
||
|
values = dojo.map(values, function(value){
|
||
|
if(dojo.isObject(value) && store.isItem(value)){
|
||
|
return new ddcd._BoundItem(value, store);
|
||
|
}
|
||
|
return value;
|
||
|
});
|
||
|
values.get = ddcd._get;
|
||
|
return values;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
ddcd._BoundItem.prototype.get.safe = true;
|
||
|
|
||
|
ddcd.BindDataNode = dojo.extend(function(items, query, store, alias){
|
||
|
this.items = items && new dd._Filter(items);
|
||
|
this.query = query && new dd._Filter(query);
|
||
|
this.store = new dd._Filter(store);
|
||
|
this.alias = alias;
|
||
|
},
|
||
|
{
|
||
|
render: function(context, buffer){
|
||
|
var items = this.items && this.items.resolve(context);
|
||
|
var query = this.query && this.query.resolve(context);
|
||
|
var store = this.store.resolve(context);
|
||
|
if(!store || !store.getFeatures){
|
||
|
throw new Error("data_bind didn't receive a store");
|
||
|
}
|
||
|
|
||
|
if(query){
|
||
|
var sync = false;
|
||
|
|
||
|
store.fetch({
|
||
|
query: query,
|
||
|
sync: true,
|
||
|
scope: this,
|
||
|
onComplete: function(it){
|
||
|
sync = true;
|
||
|
items = it;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
if(!sync){
|
||
|
throw new Error("The bind_data tag only works with a query if the store executed synchronously");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var list = [];
|
||
|
|
||
|
if(items){
|
||
|
for(var i = 0, item; item = items[i]; i++){
|
||
|
list.push(new ddcd._BoundItem(item, store));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
context[this.alias] = list;
|
||
|
return buffer;
|
||
|
},
|
||
|
unrender: function(context, buffer){
|
||
|
return buffer;
|
||
|
},
|
||
|
clone: function(){
|
||
|
return this;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
dojo.mixin(ddcd, {
|
||
|
_get: function(key){
|
||
|
if(this.length){
|
||
|
return (this[0] instanceof ddcd._BoundItem) ? this[0].get(key) : this[0][key];
|
||
|
}
|
||
|
},
|
||
|
bind_data: function(parser, token){
|
||
|
// summary: Turns a list of data store items into DTL compatible items
|
||
|
// example:
|
||
|
// `contextItems` and `contextStore` should be an item list
|
||
|
// and a data store that get assigned to `newVariable`
|
||
|
//
|
||
|
// | {% bind_data contextItems to contextStore as newVariable %}
|
||
|
var parts = token.contents.split();
|
||
|
|
||
|
if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){
|
||
|
throw new Error("data_bind expects the format: 'data_bind items to store as varName'");
|
||
|
}
|
||
|
|
||
|
return new ddcd.BindDataNode(parts[1], null, parts[3], parts[5]);
|
||
|
},
|
||
|
bind_query: function(parser, token){
|
||
|
// summary: Queries a data store and makes the returned items DTL compatible
|
||
|
// example:
|
||
|
// You can only use this with data stores that work in a synchronous
|
||
|
// way (meaning that `onComplete` is fired during the `fetch` call).
|
||
|
// A `sync` flag is sent to the fetch call so that stores that usually
|
||
|
// work asynchronously make themselves syncrhonous if possible.
|
||
|
// | {% bind_query contextQuery to contextStore as newVariable %}
|
||
|
var parts = token.contents.split();
|
||
|
|
||
|
if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){
|
||
|
throw new Error("data_bind expects the format: 'bind_query query to store as varName'");
|
||
|
}
|
||
|
|
||
|
return new ddcd.BindDataNode(null, parts[1], parts[3], parts[5]);
|
||
|
}
|
||
|
});
|
||
|
ddcd._get.safe = true;
|
||
|
|
||
|
dd.register.tags("dojox.dtl.contrib", {
|
||
|
"data": ["bind_data", "bind_query"]
|
||
|
});
|
||
|
})();
|