GridFromHtml.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. define(["./Grid", "dojo/_base/declare", "put-selector/put"],
  2. function(Grid, declare, put){
  3. // summary:
  4. // This module supports parsing grid structure information from an HTML table.
  5. // This module does NOT support ColumnSets; see GridWithColumnSetsFromHtml
  6. // name of data attribute to check for column properties
  7. var bagName = "data-dgrid-column";
  8. function getSubRowsFromDom(domNode){
  9. // summary:
  10. // generate columns from DOM. Should this be in here, or a separate module?
  11. var
  12. columns = [], // to be pushed upon / returned
  13. trs = domNode.getElementsByTagName("tr"),
  14. trslen = trs.length,
  15. getCol = GridFromHtml.utils.getColumnFromCell,
  16. rowColumns, tr, ths, thslen;
  17. for(var i = 0; i < trslen; i++){
  18. rowColumns = [];
  19. columns.push(rowColumns);
  20. tr = trs[i];
  21. ths = tr.getElementsByTagName("th"), thslen = ths.length;
  22. for(var j = 0; j < thslen; j++){
  23. rowColumns.push(getCol(ths[j]));
  24. }
  25. }
  26. if(tr){
  27. // NOTE: this assumes that applicable TRs were ONLY found under one
  28. // grouping element (e.g. thead)
  29. domNode.removeChild(tr.parentNode);
  30. }
  31. return columns;
  32. }
  33. var GridFromHtml = declare(Grid, {
  34. configStructure: function(){
  35. // summary:
  36. // Configure subRows based on HTML originally in srcNodeRef
  37. if(!this._checkedTrs){
  38. this._checkedTrs = true;
  39. this.subRows = getSubRowsFromDom(this.srcNodeRef, this.subRows);
  40. }
  41. return this.inherited(arguments);
  42. },
  43. create: function(params, srcNodeRef){
  44. // We need to replace srcNodeRef, presumably a table, with a div.
  45. // (Otherwise we'll generate highly invalid markup, which IE doesn't like)
  46. var
  47. div = document.createElement("div"),
  48. id = srcNodeRef.id,
  49. style = srcNodeRef.getAttribute("style");
  50. // Copy some commonly-used attributes...
  51. if(id){ this.id = id; } // will be propagated in List's create
  52. div.className = srcNodeRef.className;
  53. style && div.setAttribute("style", style);
  54. // replace srcNodeRef in DOM with the div
  55. srcNodeRef.parentNode.replaceChild(div, srcNodeRef);
  56. (params = params || {}).srcNodeRef = srcNodeRef;
  57. // call inherited with the new node
  58. // (but configStructure will look at srcNodeRef)
  59. this.inherited(arguments, [params, div]);
  60. // destroy srcNodeRef for good now that we're done with it
  61. put(srcNodeRef, "!");
  62. }
  63. });
  64. // hang some utility functions, potentially useful for extensions
  65. GridFromHtml.utils = {
  66. // Functions for getting various types of values from HTML attributes
  67. getBoolFromAttr: function(node, attr){
  68. // used for e.g. sortable
  69. var val = node.getAttribute(attr);
  70. return val && val !== "false";
  71. },
  72. getNumFromAttr: function(node, attr){
  73. // used for e.g. rowSpan, colSpan
  74. var val = node.getAttribute(attr);
  75. val = val && Number(val);
  76. return isNaN(val) ? undefined : val;
  77. },
  78. getPropsFromNode: function(node){
  79. // used to pull properties out of bag e.g. "data-dgrid-column".
  80. var obj, str = node.getAttribute(bagName);
  81. if(!str){ return {}; } // no props bag specified!
  82. // Yes, eval is evil, but this is ultimately the same thing that
  83. // dojo.parser does for objects.
  84. try{
  85. obj = eval("(" + str + ")");
  86. }catch(e){
  87. throw new Error("Error in " + bagName + " {" + str + "}: " + e.toString());
  88. }
  89. return obj;
  90. },
  91. // Function for aggregating th attributes into column properties
  92. getColumnFromCell: function(th){
  93. var
  94. getNum = GridFromHtml.utils.getNumFromAttr,
  95. obj, tmp;
  96. // Look for properties in data attribute.
  97. // It's imperative that we hold on to this object as returned, as the
  98. // object may be augmented further by other sources,
  99. // e.g. Grid adding the grid property to reference the instance.
  100. obj = GridFromHtml.utils.getPropsFromNode(th);
  101. // inspect standard attributes, but data attribute takes precedence
  102. obj.label = "label" in obj ? obj.label : th.innerHTML;
  103. obj.field = obj.field || th.className || th.innerHTML;
  104. if(!obj.className && th.className){ obj.className = th.className; }
  105. if(!obj.rowSpan && (tmp = getNum(th, "rowspan"))){ obj.rowSpan = tmp; }
  106. if(!obj.colSpan && (tmp = getNum(th, "colspan"))){ obj.colSpan = tmp; }
  107. return obj;
  108. }
  109. };
  110. return GridFromHtml;
  111. });