123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- define(["./Grid", "dojo/_base/declare", "put-selector/put"],
- function(Grid, declare, put){
- // summary:
- // This module supports parsing grid structure information from an HTML table.
- // This module does NOT support ColumnSets; see GridWithColumnSetsFromHtml
-
- // name of data attribute to check for column properties
- var bagName = "data-dgrid-column";
-
- function getSubRowsFromDom(domNode){
- // summary:
- // generate columns from DOM. Should this be in here, or a separate module?
- var
- columns = [], // to be pushed upon / returned
- trs = domNode.getElementsByTagName("tr"),
- trslen = trs.length,
- getCol = GridFromHtml.utils.getColumnFromCell,
- rowColumns, tr, ths, thslen;
-
- for(var i = 0; i < trslen; i++){
- rowColumns = [];
- columns.push(rowColumns);
- tr = trs[i];
- ths = tr.getElementsByTagName("th"), thslen = ths.length;
- for(var j = 0; j < thslen; j++){
- rowColumns.push(getCol(ths[j]));
- }
- }
- if(tr){
- // NOTE: this assumes that applicable TRs were ONLY found under one
- // grouping element (e.g. thead)
- domNode.removeChild(tr.parentNode);
- }
-
- return columns;
- }
-
- var GridFromHtml = declare(Grid, {
- configStructure: function(){
- // summary:
- // Configure subRows based on HTML originally in srcNodeRef
- if(!this._checkedTrs){
- this._checkedTrs = true;
- this.subRows = getSubRowsFromDom(this.srcNodeRef, this.subRows);
- }
- return this.inherited(arguments);
- },
-
- create: function(params, srcNodeRef){
- // We need to replace srcNodeRef, presumably a table, with a div.
- // (Otherwise we'll generate highly invalid markup, which IE doesn't like)
- var
- div = document.createElement("div"),
- id = srcNodeRef.id,
- style = srcNodeRef.getAttribute("style");
-
- // Copy some commonly-used attributes...
- if(id){ this.id = id; } // will be propagated in List's create
- div.className = srcNodeRef.className;
- style && div.setAttribute("style", style);
-
- // replace srcNodeRef in DOM with the div
- srcNodeRef.parentNode.replaceChild(div, srcNodeRef);
-
- (params = params || {}).srcNodeRef = srcNodeRef;
- // call inherited with the new node
- // (but configStructure will look at srcNodeRef)
- this.inherited(arguments, [params, div]);
-
- // destroy srcNodeRef for good now that we're done with it
- put(srcNodeRef, "!");
- }
- });
-
- // hang some utility functions, potentially useful for extensions
- GridFromHtml.utils = {
- // Functions for getting various types of values from HTML attributes
- getBoolFromAttr: function(node, attr){
- // used for e.g. sortable
- var val = node.getAttribute(attr);
- return val && val !== "false";
- },
- getNumFromAttr: function(node, attr){
- // used for e.g. rowSpan, colSpan
- var val = node.getAttribute(attr);
- val = val && Number(val);
- return isNaN(val) ? undefined : val;
- },
- getPropsFromNode: function(node){
- // used to pull properties out of bag e.g. "data-dgrid-column".
- var obj, str = node.getAttribute(bagName);
- if(!str){ return {}; } // no props bag specified!
-
- // Yes, eval is evil, but this is ultimately the same thing that
- // dojo.parser does for objects.
- try{
- obj = eval("(" + str + ")");
- }catch(e){
- throw new Error("Error in " + bagName + " {" + str + "}: " + e.toString());
- }
- return obj;
- },
-
- // Function for aggregating th attributes into column properties
- getColumnFromCell: function(th){
- var
- getNum = GridFromHtml.utils.getNumFromAttr,
- obj, tmp;
-
- // Look for properties in data attribute.
- // It's imperative that we hold on to this object as returned, as the
- // object may be augmented further by other sources,
- // e.g. Grid adding the grid property to reference the instance.
- obj = GridFromHtml.utils.getPropsFromNode(th);
-
- // inspect standard attributes, but data attribute takes precedence
- obj.label = "label" in obj ? obj.label : th.innerHTML;
- obj.field = obj.field || th.className || th.innerHTML;
- if(!obj.className && th.className){ obj.className = th.className; }
- if(!obj.rowSpan && (tmp = getNum(th, "rowspan"))){ obj.rowSpan = tmp; }
- if(!obj.colSpan && (tmp = getNum(th, "colspan"))){ obj.colSpan = tmp; }
-
- return obj;
- }
- };
- return GridFromHtml;
- });
|