CellSelection.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. define([
  2. "dojo/_base/declare",
  3. "dojo/aspect",
  4. "dojo/on",
  5. "dojo/has",
  6. "./Selection",
  7. "put-selector/put"
  8. ], function(declare, aspect, listen, has, Selection, put){
  9. return declare(Selection, {
  10. // summary:
  11. // Add cell level selection capabilities to a grid. The grid will have a selection property and
  12. // fire "dgrid-select" and "dgrid-deselect" events.
  13. // ensure we don't select when an individual cell is not identifiable
  14. selectionDelegate: ".dgrid-cell",
  15. _selectionTargetType: "cells",
  16. _select: function(cell, toCell, value){
  17. var i, id;
  18. if(typeof value === "undefined"){
  19. // default to true
  20. value = true;
  21. }
  22. if(typeof cell != "object" || !("element" in cell)){
  23. cell = this.cell(cell);
  24. }else if(!cell.row){
  25. // Row object was passed instead of cell
  26. if(value && typeof value === "object"){
  27. // value is a hash of true/false values
  28. for(id in value){
  29. this._select(this.cell(cell.id, id), null, value[id]);
  30. }
  31. }else{
  32. // Select/deselect all columns in row
  33. for(id in this.columns){
  34. this._select(this.cell(cell.id, id), null, value);
  35. }
  36. }
  37. return;
  38. }
  39. if(this.allowSelect(cell)){
  40. var selection = this.selection,
  41. rowId = cell.row.id,
  42. previousRow = selection[rowId];
  43. if(!cell.column){
  44. for(i in this.columns){
  45. this._select(this.cell(rowId, i), null, value);
  46. }
  47. return;
  48. }
  49. var previous = previousRow && previousRow[cell.column.id];
  50. if(value === null){
  51. // indicates a toggle
  52. value = !previous;
  53. }
  54. var element = cell.element;
  55. previousRow = previousRow || {};
  56. previousRow[cell.column.id] = value;
  57. this.selection[rowId] = previousRow;
  58. // Check for all-false objects to see if it can be deleted.
  59. // This prevents build-up of unnecessary iterations later.
  60. var hasSelected = false;
  61. for(i in previousRow){
  62. if(previousRow[i] === true){
  63. hasSelected = true;
  64. break;
  65. }
  66. }
  67. if(!hasSelected){ delete this.selection[rowId]; }
  68. if(element){
  69. // add or remove classes as appropriate
  70. if(value){
  71. put(element, ".dgrid-selected.ui-state-active");
  72. }else{
  73. put(element, "!dgrid-selected!ui-state-active");
  74. }
  75. }
  76. if(value != previous && element){
  77. this._selectionEventQueues[(value ? "" : "de") + "select"].push(cell);
  78. }
  79. if(toCell){
  80. // a range
  81. if(!toCell.element){
  82. toCell = this.cell(toCell);
  83. }
  84. var toElement = toCell.element;
  85. var fromElement = cell.element;
  86. // find if it is earlier or later in the DOM
  87. var traverser = (toElement && (toElement.compareDocumentPosition ?
  88. toElement.compareDocumentPosition(fromElement) == 2 :
  89. toElement.sourceIndex > fromElement.sourceIndex)) ? "nextSibling" : "previousSibling";
  90. // now we determine which columns are in the range
  91. var idFrom = cell.column.id, idTo = toCell.column.id, started, columnIds = [];
  92. for(id in this.columns){
  93. if(started){
  94. columnIds.push(id);
  95. }
  96. if(id == idFrom && (idFrom = columnIds) || // once found, we mark it off so we don't hit it again
  97. id == idTo && (idTo = columnIds)){
  98. columnIds.push(id);
  99. if(started || // last id, we are done
  100. (idFrom == columnIds && id == idTo)){ // the ids are the same, we are done
  101. break;
  102. }
  103. started = true;
  104. }
  105. }
  106. // now we iterate over rows
  107. var row = cell.row, nextNode = row.element;
  108. toElement = toCell.row.element;
  109. do{
  110. // looping through each row..
  111. // and now loop through each column to be selected
  112. for(i = 0; i < columnIds.length; i++){
  113. cell = this.cell(nextNode, columnIds[i]);
  114. this._select(cell, null, value);
  115. }
  116. if(nextNode == toElement){
  117. break;
  118. }
  119. }while((nextNode = cell.row.element[traverser]));
  120. }
  121. }
  122. },
  123. isSelected: function(object, columnId){
  124. // summary:
  125. // Returns true if the indicated cell is selected.
  126. if(typeof object === "undefined" || object === null){
  127. return false;
  128. }
  129. if(!object.element){
  130. object = this.cell(object, columnId);
  131. }
  132. // First check whether the given cell is indicated in the selection hash;
  133. // failing that, check if allSelected is true (testing against the
  134. // allowSelect method if possible)
  135. var rowId = object.row.id;
  136. if(rowId in this.selection){
  137. return !!this.selection[rowId][object.column.id];
  138. }else{
  139. return this.allSelected && (!object.row.data || this.allowSelect(object));
  140. }
  141. },
  142. clearSelection: function(exceptId){
  143. // disable exceptId in cell selection, since it would require double parameters
  144. exceptId = false;
  145. this.inherited(arguments);
  146. }
  147. });
  148. });