wf.StoreMgr=wf.apply(new wf.MixedCollection(),{
register:function(){
for(var i=0,s;s=arguments[i];i++){
this.add(s);}},
unregister:function(){
for(var i=0,s;s=arguments[i];i++){
this.remove(this.lookup(s));}},
lookup:function(id){
return typeof id=="object"?id:this.get(id);},
getKey:function(o){
return o.storeId||o.id;}});
wf.data.HttpProxy=function(conn){
wf.data.HttpProxy.superclass.constructor.call(this);
this.conn=conn;};
wf.extend(wf.data.HttpProxy,wf.Observable,{
load:function(params,reader,callback,scope,arg){
var o={
params:params||{},
request:{
callback:callback,
scope:scope,
arg:arg},
reader:reader,
callback:this.loadResponse,
scope:this};
wf.applyIf(o,this.conn);
if(this.activeRequest){
wf.Ajax.abort(this.activeRequest);}
this.activeRequest=wf.Ajax.request(o);},
loadResponse:function(o,success,response){
delete this.activeRequest;
if(!success){
o.request.callback.call(o.request.scope,null,o.request.arg,false);
return;}
var result;
try{
result=o.reader.read(response);}catch(e){
o.request.callback.call(o.request.scope,null,o.request.arg,false);
return;}
o.request.callback.call(o.request.scope,result,o.request.arg,result.success);}});
wf.data.DataReader=function(fields){
this.fields=fields;};
wf.data.DataReader.prototype={};
wf.data.JsonReader=function(fields){
wf.data.JsonReader.superclass.constructor.call(this,fields);};
wf.extend(wf.data.JsonReader,wf.data.DataReader,{
read:function(response){
var json=response.responseText;
var o=eval("("+json+")");
if(!o){
throw{message:"JsonReader.read: Json object not found"};}
return this.readRecords(o);},
readRecords:function(o){
if(!this.fields){
return;}
this.jsonData=o;
var R=wf.data.Record;
var fs=this.fields,fl=fs.length;
var datas=o.datas;
var total=o.total;
var success=o.success;
var errMsg;
var records=[];
if(!success){
errMsg=o.msg;}else{
this.getId=function(data){
return data.id;}
for(var i=0;i<datas.length;i++){
var data=datas[i];
var values={};
var id=this.getId(data);
for(var j=0;j<fl;j++){
f=fs[j];
var v=data[f.name];
values[f.name]=f.convert((v!==undefined)?v:f.defaultValue);}
var record=new R(values,id);
records[i]=record;}}
return{
success:success,
errMsg:errMsg,
records:records,
total:total};}});
wf.data.ArrayReader=wf.extend(wf.data.JsonReader,{
readRecords:function(o){
if(!this.fields){
return;}
var fs=this.fields,fl=fs.length;
var R=wf.data.Record;
var records=[];
for(var i=0;i<o.length;i++){
var data=o[i];
var values={};
for(var j=0;j<fl;j++){
var f=fs[j];
var v=data[f.name];
values[f.name]=f.convert((v!==undefined)?v:f.defaultValue);}
var record=new R(values);
records[records.length]=record;}
return{
records:records,
total:records.length};}});
wf.data.Store=function(config){
this.data=new wf.MixedCollection();
this.baseParams={};
this.paramNames={
"start":"start",
"limit":"limit",
"sort":"sort",
"dir":"dir"};
if(config&&config.data){
this.inlineData=config.data;
delete config.data;}
wf.apply(this,config);
if(this.url&&!this.proxy){
this.proxy=new wf.data.HttpProxy({url:this.url});}
this.sortToggle={};
wf.data.Store.superclass.constructor.call(this);
this.addEvents('datachanged','add','remove','update','clear','beforeload','load','failure');
if(this.storeId||this.id){
wf.StoreMgr.register(this);}
if(this.fields.length>0){
this.fields=wf.data.Record.create(this.fields);}
if(!this.reader){
if(this.readerType=="json"||this.url){
this.reader=new wf.data.JsonReader(this.fields);}else{
this.reader=new wf.data.ArrayReader(this.fields);}}
if(this.inlineData){
this.loadData(this.inlineData);
delete this.inlineData;}};
wf.extend(wf.data.Store,wf.Observable,{
remoteSort:false,
lazy:true,
lastOptions:null,
add:function(records){
records=[].concat(records);
if(records.length<1){
return;}
for(var i=0,len=records.length;i<len;i++){
records[i].join(this);}
var index=this.data.length;
this.data.addAll(records);
if(this.snapshot){
this.snapshot.addAll(records);}
this.fireEvent("add",this,records,index);},
getField:function(id){
var f;
for(var i=0;i<this.fields.length;i++){
if(this.fields[i].name==id){
f=this.fields[i];
break;}}
return f;},
addSorted:function(record){
var index=this.findInsertIndex(record);
this.insert(index,record);},
insert:function(index,records){
records=[].concat(records);
for(var i=0,len=records.length;i<len;i++){
this.data.insert(index,records[i]);
records[i].join(this);}
this.fireEvent("add",this,records,index);},
remove:function(record){
var index=this.data.indexOf(record);
this.data.removeAt(index);
if(this.snapshot){
this.snapshot.remove(record);}
this.fireEvent("remove",this,record,index);},
clear:function(){
this.data.clear();
if(this.snapshot){
this.snapshot.clear();}
this.fireEvent("clear",this);},
indexOf:function(record){
return this.data.indexOf(record);},
indexOfId:function(id){
return this.data.indexOfKey(id);},
getAt:function(index){
return this.data.itemAt(index);},
getById:function(id){
return this.data.key(id);},
getRange:function(start,end){
return this.data.getRange(start,end);},
storeOptions:function(o){
o=wf.apply({},o);
delete o.callback;
delete o.scope;
this.lastOptions=o;},
load:function(options){
options=options||{};
if(this.fireEvent("beforeload",this,options)!==false){
this.storeOptions(options);
var p=this.baseParams;
var p=wf.apply(p,options.params||{});
if(this.sortInfo&&this.remoteSort){
var pn=this.paramNames;
p[pn["sort"]]=this.sortInfo.field;
p[pn["dir"]]=this.sortInfo.direction;}
this.proxy.load(p,this.reader,this.loadRecords,this,options);}},
reload:function(options){
this.load(wf.applyIf(options||{},this.lastOptions));},
loadRecords:function(o,options,success){
if(!o||success==false){
if(success!==false){
this.fireEvent("load",this,[],options);}else{
var msg=(o&&o.errMsg)?o.errMsg:'';
this.fireEvent("failure",this,msg);}
if(options.callback){
options.callback.call(options.scope||this,[],options,false);}
return;}
var r=o.records,t=o.total||r.length;
if(!options||options.add!==true){
if(this.snapshot){
this.data=this.snapshot;
delete this.snapshot;}
this.data.clear();
for(var i=0,len=r.length;i<len;i++){
r[i].join(this);}
this.data.addAll(r);
this.totalLength=t;
this.applySort();
this.fireEvent("datachanged",this,r);}else{
this.totalLength=Math.max(t,this.data.length+r.length);
this.add(r);}
this.fireEvent("load",this,r,options);
if(options.callback){
options.callback.call(options.scope||this,r,options,true);}},
loadData:function(o,append){
var r=this.reader.readRecords(o);
this.loadRecords(r,{add:append},true);},
getCount:function(){
return this.data.length||0;},
getTotalCount:function(){
return this.totalLength||0;},
getSortState:function(){
return this.sortInfo;},
applySort:function(){
if(this.sortInfo&&!this.remoteSort){
var s=this.sortInfo,f=s.field;
this.sortData(f,s.direction);}},
sortData:function(f,direction){
direction=direction||'ASC';
var st=this.getField(f).sortType;
var fn=function(r1,r2){
var v1=st(r1.data[f]),v2=st(r2.data[f]);
return v1>v2?1:(v1<v2?-1:0);};
this.data.sort(direction,fn);
if(this.snapshot&&this.snapshot!=this.data){
this.snapshot.sort(direction,fn);}},
setDefaultSort:function(field,dir){
dir=dir?dir.toUpperCase():"ASC";
this.sortInfo={field:field,direction:dir};
this.sortToggle[field]=dir;},
sort:function(fieldName,dir){
var f=this.getField(fieldName);
if(!f){
return false;}
if(!dir){
if(this.sortInfo&&this.sortInfo.field==f.name){
var r=this.sortToggle[f.name];
dir=(r&&r=="ASC")?"DESC":"ASC";}else{
dir=f.sortDir||"ASC";}}
this.sortToggle[f.name]=dir;
this.sortInfo={field:f.name,direction:dir};
if(!this.remoteSort){
this.applySort();
this.fireEvent("datachanged",this);}else{
this.load(this.lastOptions);}},
createFilterFn:function(property,value,anyMatch,caseSensitive){
if(!value){
return false;}
value=this.data.createValueMatcher(value,anyMatch,caseSensitive);
return function(r){
return value.test(r.data[property]);};},
sum:function(property,start,end){
var rs=this.data.items,v=0;
start=start||0;
end=(end||end===0)?end:rs.length-1;
for(var i=start;i<=end;i++){
v+=(rs[i].data[property]||0);}
return v;},
filter:function(property,value,anyMatch,caseSensitive){
var fn=this.createFilterFn(property,value,anyMatch,caseSensitive);
return fn?this.filterBy(fn):this.clearFilter();},
filterBy:function(fn,scope){
this.snapshot=this.snapshot||this.data;
this.data=this.queryBy(fn,scope||this);
this.fireEvent("datachanged",this);},
clearFilter:function(suppressEvent){
if(this.isFiltered()){
this.data=this.snapshot;
delete this.snapshot;
if(suppressEvent!==true){
this.fireEvent("datachanged",this);}}},
isFiltered:function(){
return this.snapshot&&this.snapshot!=this.data;},
query:function(property,value,anyMatch,caseSensitive){
var fn=this.createFilterFn(property,value,anyMatch,caseSensitive);
return fn?this.queryBy(fn):this.data.clone();},
queryBy:function(fn,scope){
var data=this.snapshot||this.data;
return data.filterBy(fn,scope||this);},
find:function(property,value,start,anyMatch,caseSensitive){
var fn=this.createFilterFn(property,value,anyMatch,caseSensitive);
return fn?this.data.findIndexBy(fn,null,start):-1;},
findBy:function(fn,scope,start){
return this.data.findIndexBy(fn,scope,start);},
afterEdit:function(record){
this.fireEvent("update",this,record,wf.data.Record.EDIT);},
findInsertIndex:function(record){
this.suspendEvents();
var data=this.data.clone();
this.data.add(record);
this.applySort();
var index=this.data.indexOf(record);
this.data=data;
this.resumeEvents();
return index;}});
wf.data.SortTypes={
none:function(s){
return s;},
stripTagsRE:/<\/?[^>]+>/gi,
asText:function(s){
return String(s).replace(this.stripTagsRE,"");},
asUCText:function(s){
return String(s).toUpperCase().replace(this.stripTagsRE,"");},
asUCString:function(s){
return String(s).toUpperCase();},
asDate:function(s){
if(!s){
return 0;}
if(s instanceof Date){
return s.getTime();}
return Date.parse(String(s));},
asFloat:function(s){
var val=parseFloat(String(s).replace(/,/g,""));
if(isNaN(val))val=0;
return val;},
asInt:function(s){
var val=parseInt(String(s).replace(/,/g,""));
if(isNaN(val))val=0;
return val;}};
wf.data.Field=function(config){
if(typeof config=="string"){
config={name:config};}
wf.apply(this,config);
if(!this.type){
this.type="auto";}
var st=wf.data.SortTypes;
if(typeof this.sortType=="string"){
this.sortType=st[this.sortType];}
if(!this.sortType){
switch(this.type){
case "string":
this.sortType=st.asUCString;
break;
case "date":
this.sortType=st.asDate;
break;
default:
this.sortType=st.none;}}
var stripRe=/[\$,%]/g;
if(!this.convert){
var cv,dateFormat=this.dateFormat;
switch(this.type){
case "":
case "auto":
case undefined:
cv=function(v){return v;};
break;
case "string":
cv=function(v){return(v===undefined||v===null)?'':String(v);};
break;
case "int":
cv=function(v){
return v!==undefined&&v!==null&&v!==''?
parseInt(String(v).replace(stripRe,""),10):'';};
break;
case "float":
cv=function(v){
return v!==undefined&&v!==null&&v!==''?
parseFloat(String(v).replace(stripRe,""),10):'';};
break;
case "bool":
case "boolean":
cv=function(v){return v===true||v==="true"||v==1;};
break;
case "date":
cv=function(v){
if(!v){
return '';}
if(v instanceof Date){
return v;}
if(dateFormat){
if(dateFormat=="timestamp"){
return new Date(v*1000);}
if(dateFormat=="time"){
return new Date(parseInt(v,10));}
return Date.parseDate(v,dateFormat);}
var parsed=Date.parse(v);
return parsed?new Date(parsed):null;};
break;}
this.convert=cv;}};
wf.data.Field.prototype={
dateFormat:null,
defaultValue:"",
sortType:null,
sortDir:"ASC"};
wf.data.Record=function(data,id){
this.id=(id||id===0)?id:++wf.data.Record.AUTO_ID;
this.data=data;};
wf.data.Record.AUTO_ID=1000;
wf.data.Record.create=function(fields){
var fs=[];
for(var i=0;i<fields.length;i++){
fs[i]=new wf.data.Field(fields[i]);}
return fs;};
wf.data.Record.prototype={
set:function(name,value){
if(String(this.data[name])==String(value)){
return;}
this.data[name]=value;
this.store.afterEdit(this);},
join:function(store){
this.store=store;},
get:function(name){
return this.data[name];}};