topical media & game development
lib-jquery-plugin-charts-lib--old-jquery.tablelib.js / js
/*
* Copyright (c) 2008 Greg Weber greg at gregweber.info
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* jquery plugin for working with tables and table rows
* create table objects and table row objects and use convenience methods
* serialize objects to table rows and extract objects from table rows
* support for saving object properties as row attributes
* advanced querying of table rows
*
* documentation at http://gregweber.info/projects/tablelib
* also in the source
*
* plugin dependent on lib/iterator.js (included in tarball)
*/
// support both .table() interface and
jQuery.fn.table = function(jq){
if( this instanceof jQuery.fn.table ){
this. = jq;
return this;
}
return new jQuery.fn.table(this);
}
// : null, // constructor fills this in!
table: function(){return this},
filter_query: function(obj, query ){
for( var i in query ) {
var qv = query[i], ov = obj[i];
if(typeof(qv) == "function"){ if( isTrue(qv(ov)) ) return true }
else if ( ov === qv ) return true;
}
return false;
},
// by default try to parse to a float
// turn off by setting to false (or set your own parse function)
parse: function(val){ var p = parseFloat(val); return isNaN(p) ? val :
(p.toString() === val) // extra verification
? p : val },
head_row: function(){
return jQuery.headRow( this..find("thead > tr:last > th"),
function(th) { return jQuery(th).text() });
},
clear_rows: function(){ this..find("tbody > tr").filter( function() {
return that.filter_query( jQuery.row(this).attrs(), attributes );
});
}
else return this..find("tbody > tr").filter( function(){
var row = .find("tbody > tr").filter( function(){
return that.filter_query( jQuery.row(this).texts(), query )
});
},
// two options passed as objects,
// query for table data cells, query for row attributes
// two minor options, both have two properties: query and fields
// query is a filtering expression
// fields is an array of keys that will be present in the returned objects
// by default, no query is performed, all table data keys are present,
// and none of the row attributes are present
// query can be abbreviated as q, fields as f
// the fields value is an array
// if no fields parameter is passed, there is no need to pass the query of fields keys
// objs( {query : {k:v}, fields : [f]}, {query : {k:a}, fields : [a]}
// objs( {q: {k:v}, f: [f]}, {q: {k:a}, f: [a]}
// objs( {k:v}, {k:a} )
// objs( "all", {k:a} )
// if attributes are queried and there are no fields specified,
// by default all queried fields will become members of the object
objs: function( query, attributes ){
var parse_args = function( query ){
var fields; var q;
if( query && query != "all" ) {
q = query.query || query.q
fields = query.fields || query.f
// not a query object, coincidental
if( q && ( typeof(q) != "object" ) )
{ q = null }
// not a field object, coincidental
if( !(fields) || ( typeof(fields) != "object" ) )
{ fields = null }
// did not decalre a query or fields parameter, default is a query
if( !(fields) && !(q) )
{ q = query }
}
return { query : q, fields : fields }
}
var q_f = parse_args( query );
var q = q_f.query; var fields = q_f.fields;
var a_f = parse_args( attributes )
var aquery = a_f.query; var afields = a_f.fields;
var ths_text = this.titles();
if( fields ) {
fields = map( fields, function( field ) {
var i = jQuery.inArray( field, ths_text )
return i === -1 ? null : { field : field, i : i }
})
} else {
fields = map(ths_text, function(th,i){ return {field : th, i : i} })
}
var af;
if( afields ) af = invert( afields, true );
var that = this;
return map( this.rows(q, aquery), function(row){ return jQuery.row( row )
.to_object( { fields : fields, attributes : af, table : that } );
})
},
object_to_html: function(obj, attribute_fields, titles){
titles = titles || this.titles();
var attrs = null;
// turn array of fields into obj
if( attribute_fields ) {
attrs = {};
jQuery.each( attribute_fields, function(i){
attrs[ this ] = obj[ this ];
});
}
return this.array_to_tr( jQuery.map( titles,
function(text){ return obj[ text ] }), attrs )
},
// [""], {"":""} -> ""
array_to_tr: function(arr, attributes){
var tr = null;
if( attributes ) {
var at = [];
for(key in attributes){ at.push(key + '="' + attributes[key]); }
tr = '<tr ' + at.join('" ') + '">';
}
else { tr = "<tr>"; }
if( arr.length === 0 ) return tr + "</tr>";
return tr + "<td>" + arr.join("</td><td>") + "</td></tr>";
},
// objs : an array of objects
// options.attributes : attributes to be saved, see save
// options.clear : clear all existing rows before saving
save: function( objects, options ) {
var attributes, clear
if( options ){
attributes = options.attributes;
if( typeof attributes == "string" ) attributes = [attributes]
clear = options.clear;
}
if( objects.constructor != Array ) objects = [objects]
var ths_text = this.titles();
var that = this;
if( clear ) this.clear_rows();
this. = jq;
return this;
}
return new jQuery.fn.row(this);
}
jQuery.fn.headRow = function(jq){
if( this instanceof jQuery.fn.headRow ){
this. should be new jQuery object
jQuery.fn.row.genericRowProperties = function(type){
this.row = function(){return this;}
this.table = function(){return jQuery.table(this..children(type));
d.row = this;
d.table = this.table;
return d;
}
this.texts = function(){ return jQuery.map( this..get(0).attributes,
((fields && typeof(fields) === "object") ? a_filter_fields : a_filter));
return attrs;
}
// options.parse = false prevents trying to parse fields as floats
// options.table is performance optimization if fields are not given
// options.attributes - see row.attrs
this.to_object = function( options ) { // fields, attributes, table, parse
var obj = {}; // to be returned
options = options || {};
var table = options.table;
var fields = options.fields || map( (table || this.table()).head_row().ths(),
function(th,i){ return { field : jQuery(th).text(), i : i } } );
var texts = this.texts();
// convert the table text (probably to a number)
var parse = options.parse || (table && table.parse);
if( parse ){
if( typeof( parse ) == "function" ) {
jQuery.each( fields, function( i, fi ) {
var field = fi.field;
var text = texts[ fi.i ];
obj[ field ] = parse(text);
});
}else{ //object
jQuery.each( fields, function( i, fi ) {
var field = fi.field;
var transform = parse[ field ];
var text = texts[ fi.i ];
obj[ field ] = transform ? transform(text) : text;
});
}
}else{
jQuery.each( fields, function( i, fi ) {
obj[ fi.field ] = texts[ fi.i ];
});
}
if( options.attributes ) { this.attrs( options.attributes, obj ); }
return obj;
}
// current_table optional performance enhancement
this.transfer_to = function( table, current_table )
{
var obj = this.to_object( { table : current_table } );
this..find("tbody > tr:last");
}
return this;
};
jQuery.fn.row.prototype = jQuery.fn.row.fn =
new jQuery.fn.row.genericRowProperties("td");
jQuery.fn.headRow.prototype = jQuery.fn.headRow.fn =
new jQuery.fn.row.genericRowProperties("th");
jQuery.row = function(selector){
return new jQuery.fn.row(jQuery(selector));
}
jQuery.headRow = function(selector){
return new jQuery.fn.headRow(jQuery(selector));
}
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.