/** A data source
* @constructor
*/
hui.ui.Source = function(options) {
this.options = hui.override({url:null,parameters:[],lazy:false},options);
this.name = options.name;
this.data = null;
this.parameters = [];
// Clone parameters so they can be reused
for (var i = 0; i < this.options.parameters.length; i++) {
var p = this.options.parameters[i];
this.parameters.push({key:p.key,value:p.value,separate:p.separate});
}
hui.ui.extend(this);
if (options.delegate) {
this.listen(options.delegate);
}
this.initial = true;
this.busy = false;
hui.ui.onReady(this._init.bind(this));
};
hui.ui.Source.prototype = {
_init : function() {
var self = this;
hui.each(this.parameters,function(parm) {
var val = hui.ui.bind(parm.value,function(value) {
self.changeParameter(parm.key,value);
});
parm.value = self._convertValue(val);
});
if (!this.options.lazy) {
this.refresh();
}
},
_convertValue : function(value) {
if (value && value.getTime) {
return value.getTime();
}
return value;
},
refreshFirst : function() {
if (this.initial) {
this.refresh();
}
},
/** Will refresh, but wait a little to let others contribute */
refreshLater : function() {
window.clearTimeout(this.paramDelay);
this.paramDelay = window.setTimeout(function() {
this.refresh();
}.bind(this),100);
},
/** Refreshes the data source */
refresh : function() {
if (this.options.delay<1) {
this._refresh();
} else {
window.clearTimeout(this._refreshDelay);
this._refreshDelay = window.setTimeout(this._refresh.bind(this),this.options.delay);
}
},
_refresh : function() {
if (this.delegates.length===0) {
return;
}
var shouldRefresh = this.delegates.length === 0;
for (var i=0; i < this.delegates.length; i++) {
var d = this.delegates[i];
if (d.$sourceShouldRefresh) {
shouldRefresh = shouldRefresh || d.$sourceShouldRefresh();
} else {
shouldRefresh = true;
}
}
if (!shouldRefresh) {return;}
if (this.busy) {
this.pendingRefresh = true;
// It might be better to cue rather than abort
//if (this.transport) {
// this.transport.abort();
//}
return;
}
this.initial = false;
this.pendingRefresh = false;
var self = this;
if (this.options.url) {
var prms = [];
for (var j=0; j < this.parameters.length; j++) {
var p = this.parameters[j];
if (hui.isArray(p.value) && p.separate) {
for (var k = 0; k < p.value.length; k++) {
prms.push({
name : p.key,
value : p.value[k]
});
}
} else {
prms.push({name : p.key, value : p.value});
}
}
this.busy = true;
hui.ui.callDelegates(this,'sourceIsBusy');
this.transport = hui.request({
method : 'POST',
url : this.options.url,
parameters : prms,
$success : this._parse.bind(this),
$exception : function(e,t) {
hui.log('Exception while loading source...');
hui.log(e);
self._end();
},
$forbidden : function() {
hui.ui.handleForbidden(self);
hui.ui.callDelegates(self,'sourceFailed');
self._end();
},
$failure : function(t) {
hui.log('sourceFailed');
hui.ui.callDelegates(self,'sourceFailed');
self._end();
}
});
}
},
_end : function() {
this.busy = false;
hui.ui.callDelegates(this,'sourceIsNotBusy');
if (this.pendingRefresh) {
this.refresh();
}
},
_parse : function(t) {
if (hui.request.isXMLResponse(t)) {
this._parseXML(t.responseXML);
} else {
var str = t.responseText.replace(/^\s+|\s+$/g, ''),
json = null;
if (str.length>0) {
json = hui.string.fromJSON(t.responseText);
}
this.fire('objectsLoaded',json);
}
this._end();
},
_parseXML : function(doc) {
var root = doc.documentElement.tagName;
if (root=='items' || root=='options') {
this.data = this._parseItems(doc);
this.fire('optionsLoaded',this.data);
} else if (root=='list') {
this.fire('listLoaded',doc);
} else if (root=='articles') {
this.fire('articlesLoaded',doc);
}
},
_parseItems : function(doc) {
var root = doc.documentElement;
var out = [];
this._parseSubItems(root,out);
return out;
},
_parseSubItems : function(parent,array) {
var children = parent.childNodes;
for (var i=0; i < children.length; i++) {
var node = children[i];
if (node.nodeType==1 && node.nodeName=='title') {
array.push({title:node.getAttribute('title'),type:'title'});
} else if (node.nodeType==1 && (node.nodeName=='item' || node.nodeName=='option')) {
var sub = [];
this._parseSubItems(node,sub);
array.push({
text : node.getAttribute('text'),
title : node.getAttribute('title'),
value : node.getAttribute('value'),
icon : node.getAttribute('icon'),
kind : node.getAttribute('kind'),
badge : node.getAttribute('badge'),
children : sub
});
}
}
},
addParameter : function(parm) {
this.parameters.push(parm);
var val = hui.ui.bind(parm.value,function(value) {
this.changeParameter(parm.key,value);
}.bind(this));
parm.value = this._convertValue(val);
},
setParameter : function(key,value) {
value = this._convertValue(value);
for (var i=0; i < this.parameters.length; i++) {
var p = this.parameters[i];
if (p.key==key) {
p.value=value;
return;
}
}
this.parameters.push({key:key,value:value});
},
changeParameter : function(key,value) {
value = this._convertValue(value);
for (var i=0; i < this.parameters.length; i++) {
var p = this.parameters[i];
if (p.key==key) {
p.value=value;
}
}
this.refreshLater();
}
};