LazyDataLoader.js: now handles NaN/Infinity/-Infinity as null, allows overriding jQuery's datatype converters; controllers/root: added echo_json for debugging/testing

This commit is contained in:
Carl Eberhard
2012-11-29 13:32:44 -05:00
parent 5ba52bb7da
commit 58ee5ce033
3 changed files with 39 additions and 2 deletions
@@ -531,6 +531,25 @@ class RootController( BaseUIController, UsesHistoryMixin, UsesAnnotations ):
rval += "-> %s" % kwd[k].file.read()
return rval
@web.json
def echo_json( self, trans, **kwd ):
"""Echos parameters as JSON (debugging)
Attempts to parse values passed as boolean, float, then int. Defaults
to string. Non-recursive (will not parse lists).
"""
rval = {}
for k in kwd:
rval[ k ] = kwd[k]
try:
if rval[ k ] in [ 'true', 'True', 'false', 'False' ]:
rval[ k ] = util.string_as_bool( rval[ k ] )
rval[ k ] = float( rval[ k ] )
rval[ k ] = int( rval[ k ] )
except:
pass
return rval
@web.expose
def generate_error( self, trans ):
raise Exception( "Fake error!" )
@@ -1 +1 @@
function LazyDataLoader(c){var a=this,d="loaded.new",b="complete";ERROR_EVENT="error";jQuery.extend(a,LoggableMixin);jQuery.extend(a,{total:undefined,url:undefined,currentIntervalId:undefined,data:[],delay:4000,start:0,size:4000,initialize:function(e){jQuery.extend(a,e);if(e.hasOwnProperty("initialize")){e.initialize.call(a,e)}this.log(this+" initialized:",a)},buildUrl:function(f,e){return this.url+"&"+jQuery.param({start_val:f,max_vals:e})},ajaxErrorFn:function(g,e,f){},load:function(h){this.log(this+".load");if(!a.url){throw (a+" requires a url")}if(this.total===null){this.log("\t total is null (will load all)")}else{this.log("\t total:",this.total)}var g=a.size;if((a.total!==null)&&(a.total<a.size)){g=a.total}a.log(a+"\t beginning recursion");f(a.start,g);function f(k,j){a.log(a+".loadHelper, start:",k,"size:",j);var i=a.buildUrl(k,j);a.log("\t url:",i);jQuery.ajax({url:a.buildUrl(k,j),dataType:"json",error:function(n,l,m){a.log("\t ajax error, status:",l,"error:",m);if(a.currentIntervalId){clearInterval(a.currentIntervalId)}$(a).trigger(ERROR_EVENT,[l,m]);a.ajaxErrorFn(n,l,m)},success:function(l){a.log("\t ajax success, response:",l,"next:",m,"remainder:",n);if(l!==null){a.data.push(l);$(a).trigger(d,[l,k,j]);var m=k+j,n=a.size;if(a.total!==null){n=Math.min(a.total-m,a.size)}a.log("\t next recursion, start:",m,"size:",n);if(a.total===null||n>0){a.currentIntervalId=setTimeout(function(){f(m,n)},a.delay);a.log("\t currentIntervalId:",a.currentIntervalId)}else{e()}}else{e()}}})}function e(){a.log(a+".loadHelper, has finished:",a.data);$(a).trigger(b,[a.data,a.total]);if(h){h(a.data)}}},toString:function(){return"LazyDataLoader"}});a.initialize(c);return a};
function LazyDataLoader(c){var a=this,d="loaded.new",b="complete";ERROR_EVENT="error";jQuery.extend(a,LoggableMixin);jQuery.extend(a,{total:undefined,url:undefined,currentIntervalId:undefined,data:[],delay:4000,start:0,size:4000,initialize:function(e){jQuery.extend(a,e);if(e.hasOwnProperty("initialize")){e.initialize.call(a,e)}this.log(this+" initialized:",a)},buildUrl:function(f,e){return this.url+"&"+jQuery.param({start_val:f,max_vals:e})},ajaxErrorFn:function(g,e,f){console.error("ERROR fetching data:",f)},converters:{"* text":window.String,"text html":true,"text xml":jQuery.parseXML,"text json":function(e){e=e.replace(/NaN/g,"null");e=e.replace(/-Infinity/g,"null");e=e.replace(/Infinity/g,"null");return jQuery.parseJSON(e)}},load:function(h){this.log(this+".load");if(!a.url){throw (a+" requires a url")}if(this.total===null){this.log("\t total is null (will load all)")}else{this.log("\t total:",this.total)}var g=a.size;if((a.total!==null)&&(a.total<a.size)){g=a.total}a.log(a+"\t beginning recursion");f(a.start,g);function f(k,j){a.log(a+".loadHelper, start:",k,"size:",j);var i=a.buildUrl(k,j);a.log("\t url:",i);jQuery.ajax({url:a.buildUrl(k,j),converters:a.converters,dataType:"json",error:function(n,l,m){a.log("\t ajax error, status:",l,"error:",m);if(a.currentIntervalId){clearInterval(a.currentIntervalId)}$(a).trigger(ERROR_EVENT,[l,m]);a.ajaxErrorFn(n,l,m)},success:function(l){a.log("\t ajax success, response:",l,"next:",m,"remainder:",n);if(l!==null){a.data.push(l);$(a).trigger(d,[l,k,j]);var m=k+j,n=a.size;if(a.total!==null){n=Math.min(a.total-m,a.size)}a.log("\t next recursion, start:",m,"size:",n);if(a.total===null||n>0){a.currentIntervalId=setTimeout(function(){f(m,n)},a.delay);a.log("\t currentIntervalId:",a.currentIntervalId)}else{e()}}else{e()}}})}function e(){a.log(a+".loadHelper, has finished:",a.data);$(a).trigger(b,[a.data,a.total]);if(h){h(a.data)}}},toString:function(){return"LazyDataLoader"}});a.initialize(c);return a};
+19 -1
View File
@@ -97,7 +97,6 @@ function LazyDataLoader( config ){
if( config.hasOwnProperty( 'initialize' ) ){
config.initialize.call( loader, config );
}
this.log( this + ' initialized:', loader );
},
@@ -115,6 +114,23 @@ function LazyDataLoader( config ){
//OVERRIDE: to handle ajax errors differently
ajaxErrorFn : function( xhr, status, error ){
console.error( 'ERROR fetching data:', error );
},
// converters passed to the jQuery ajax call for data type parsing
//OVERRIDE: to provide custom parsing
converters : {
'* text' : window.String,
'text html' : true,
'text xml' : jQuery.parseXML,
// add NaN, inf, -inf handling to jquery json parser (by default)
'text json' : function( json ){
json = json.replace( /NaN/g, 'null' );
json = json.replace( /-Infinity/g, 'null' );
json = json.replace( /Infinity/g, 'null' );
return jQuery.parseJSON( json );
}
},
// interface to begin load (and first recursive call)
@@ -149,7 +165,9 @@ function LazyDataLoader( config ){
jQuery.ajax({
url : loader.buildUrl( start, size ),
converters : loader.converters,
dataType : 'json',
error : function( xhr, status, error ){
loader.log( '\t ajax error, status:', status, 'error:', error );
if( loader.currentIntervalId ){