GridContainerLite.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.layout.GridContainerLite"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.layout.GridContainerLite"] = true;
  8. dojo.provide("dojox.layout.GridContainerLite");
  9. dojo.require("dijit._Templated");
  10. dojo.require("dijit.layout._LayoutWidget");
  11. dojo.require("dojox.mdnd.AreaManager");
  12. dojo.require("dojox.mdnd.DropIndicator");
  13. dojo.require("dojox.mdnd.dropMode.OverDropMode");
  14. dojo.require("dojox.mdnd.AutoScroll");
  15. dojo.declare(
  16. "dojox.layout.GridContainerLite",
  17. [dijit.layout._LayoutWidget, dijit._Templated],
  18. {
  19. // summary:
  20. // The GridContainerLite is a container of child elements that are placed in a kind of grid.
  21. //
  22. // description:
  23. // GridContainerLite displays the child elements by column
  24. // (ie: the children widths are fixed by the column width of the grid but
  25. // the children heights are free).
  26. // Each child is movable by drag and drop inside the GridContainer.
  27. // The position of other children is automatically calculated when a child is moved.
  28. //
  29. // example:
  30. // | <div dojoType="dojox.layout.GridContainerLite" nbZones="3" isAutoOrganized="true">
  31. // | <div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div>
  32. // | <div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div>
  33. // | <div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div>
  34. // | </div>
  35. //
  36. // example:
  37. // | dojo.ready(function(){
  38. // | var cpane1 = new dijit.layout.ContentPane({
  39. // | title:"cpane1", content: "Content Pane 1 : Drag Me !"
  40. // | }),
  41. // | cpane2 = new dijit.layout.ContentPane({
  42. // | title:"cpane2",
  43. // | content: "Content Pane 2 : Drag Me !"
  44. // | }),
  45. // | cpane3 = new dijit.layout.ContentPane({
  46. // | title:"cpane3",
  47. // | content: "Content Pane 3 : Drag Me !"
  48. // | });
  49. // |
  50. // | var widget = new dojox.layout.GridContainerLite({
  51. // | nbZones: 3,
  52. // | isAutoOrganized: true
  53. // | }, dojo.byId("idNode"));
  54. // | widget.addChild(cpane1, 0, 0);
  55. // | widget.addChild(cpane2, 1, 0);
  56. // | widget.addChild(cpane3, 2, 1);
  57. // | widget.startup();
  58. // | });
  59. // autoRefresh: Boolean
  60. // Enable the refresh of registered areas on drag start.
  61. autoRefresh: true,
  62. // templateString: String
  63. // template of gridContainer.
  64. templateString: dojo.cache("dojox.layout", "resources/GridContainer.html", "<div id=\"${id}\" class=\"gridContainer\" dojoAttachPoint=\"containerNode\" tabIndex=\"0\" dojoAttachEvent=\"onkeypress:_selectFocus\">\n\t<div dojoAttachPoint=\"gridContainerDiv\">\n\t\t<table class=\"gridContainerTable\" dojoAttachPoint=\"gridContainerTable\" cellspacing=\"0\" cellpadding=\"0\">\n\t\t\t<tbody>\n\t\t\t\t<tr dojoAttachPoint=\"gridNode\" >\n\t\t\t\t\t\n\t\t\t\t</tr>\n\t\t\t</tbody>\n\t\t</table>\n\t</div>\n</div>\n"),
  65. // dragHandleClass: Array :
  66. // CSS class enabling a drag handle on a child.
  67. dragHandleClass: "dojoxDragHandle",
  68. // nbZones: Integer
  69. // The number of dropped zones, by default 1.
  70. nbZones: 1,
  71. // doLayout: Boolean
  72. // If true, change the size of my currently displayed child to match my size.
  73. doLayout: true,
  74. // isAutoOrganized: Boolean
  75. // If true, widgets are organized automatically,
  76. // else the attribute colum of child will define the right column.
  77. isAutoOrganized: true,
  78. // acceptTypes: Array
  79. // The GridContainer will only accept the children that fit to the types.
  80. acceptTypes: [],
  81. // colWidths: String
  82. // A comma separated list of column widths. If the column widths do not add up
  83. // to 100, the remaining columns split the rest of the width evenly
  84. // between them.
  85. colWidths: "",
  86. constructor: function(/*Object*/props, /*DOMNode*/node){
  87. this.acceptTypes = (props || {}).acceptTypes || ["text"];
  88. this._disabled = true;
  89. },
  90. postCreate: function(){
  91. //console.log("dojox.layout.GridContainerLite ::: postCreate");
  92. this.inherited(arguments);
  93. this._grid = [];
  94. this._createCells();
  95. // need to resize dragged child when it's dropped.
  96. this.subscribe("/dojox/mdnd/drop", "resizeChildAfterDrop");
  97. this.subscribe("/dojox/mdnd/drag/start", "resizeChildAfterDragStart");
  98. this._dragManager = dojox.mdnd.areaManager();
  99. // console.info("autorefresh ::: ", this.autoRefresh);
  100. this._dragManager.autoRefresh = this.autoRefresh;
  101. // Add specific dragHandleClass to the manager.
  102. this._dragManager.dragHandleClass = this.dragHandleClass;
  103. if(this.doLayout){
  104. this._border = {
  105. 'h':(dojo.isIE) ? dojo._getBorderExtents(this.gridContainerTable).h : 0,
  106. 'w': (dojo.isIE == 6) ? 1 : 0
  107. }
  108. }
  109. else{
  110. dojo.style(this.domNode, "overflowY", "hidden");
  111. dojo.style(this.gridContainerTable, "height", "auto");
  112. }
  113. // Call postCreate of dijit.layout._LayoutWidget.
  114. this.inherited(arguments);
  115. },
  116. startup: function(){
  117. //console.log("dojox.layout.GridContainerLite ::: startup");
  118. if(this._started){ return; }
  119. if(this.isAutoOrganized){
  120. this._organizeChildren();
  121. }
  122. else{
  123. this._organizeChildrenManually();
  124. }
  125. // Need to call getChildren because getChildren return null
  126. // The children are not direct children because of _organizeChildren method
  127. dojo.forEach(this.getChildren(), function(child){ child.startup(); });
  128. // Need to enable the Drag And Drop only if the GridContainer is visible.
  129. if(this._isShown()){
  130. this.enableDnd();
  131. }
  132. this.inherited(arguments);
  133. },
  134. resizeChildAfterDrop: function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){
  135. // summary:
  136. // Resize the GridContainerLite inner table and the dropped widget.
  137. // description:
  138. // These components are resized only if the targetArea.node is a
  139. // child of this instance of gridContainerLite.
  140. // To be resized, the dropped node must have also a method resize.
  141. // node:
  142. // domNode of dropped widget.
  143. // targetArea:
  144. // AreaManager Object containing information of targetArea
  145. // indexChild:
  146. // Index where the dropped widget has been placed
  147. // returns:
  148. // True if resized.
  149. //console.log("dojox.layout.GridContainerLite ::: resizeChildAfterDrop");
  150. if(this._disabled){
  151. return false;
  152. }
  153. if(dijit.getEnclosingWidget(targetArea.node) == this){
  154. var widget = dijit.byNode(node);
  155. if(widget.resize && dojo.isFunction(widget.resize)){
  156. widget.resize();
  157. }
  158. // Update the column of the widget
  159. widget.set("column", node.parentNode.cellIndex);
  160. if(this.doLayout){
  161. var domNodeHeight = this._contentBox.h,
  162. divHeight = dojo.contentBox(this.gridContainerDiv).h;
  163. if(divHeight >= domNodeHeight){
  164. dojo.style(this.gridContainerTable, "height",
  165. (domNodeHeight - this._border.h) + "px");
  166. }
  167. }
  168. return true;
  169. }
  170. return false;
  171. },
  172. resizeChildAfterDragStart: function(/*Node*/node, /*Object*/sourceArea, /*Integer*/indexChild){
  173. // summary:
  174. // Resize the GridContainerLite inner table only if the drag source
  175. // is a child of this gridContainer.
  176. // node:
  177. // domNode of dragged widget.
  178. // sourceArea:
  179. // AreaManager Object containing information of sourceArea
  180. // indexChild:
  181. // Index where the dragged widget has been placed
  182. //console.log("dojox.layout.GridContainerLite ::: resizeChildAfterDragStart");
  183. if(this._disabled){
  184. return false;
  185. }
  186. if(dijit.getEnclosingWidget(sourceArea.node) == this){
  187. this._draggedNode = node;
  188. if(this.doLayout){
  189. dojo.marginBox(this.gridContainerTable, {
  190. 'h': dojo.contentBox(this.gridContainerDiv).h - this._border.h
  191. });
  192. }
  193. return true;
  194. }
  195. return false;
  196. },
  197. getChildren: function(){
  198. // summary:
  199. // A specific method which returns children after they were placed in zones.
  200. // returns:
  201. // An array containing all children (widgets).
  202. // tags:
  203. // protected
  204. //console.log("dojox.layout.GridContainerLite ::: _getChildren");
  205. var children = [];
  206. dojo.forEach(this._grid, function(dropZone){
  207. children = children.concat(dojo.query("> [widgetId]", dropZone.node).map(dijit.byNode));
  208. });
  209. return children; // Array
  210. },
  211. _isShown: function(){
  212. // summary:
  213. // Check if the domNode is visible or not.
  214. // returns:
  215. // true if the content is currently shown
  216. // tags:
  217. // protected
  218. //console.log("dojox.layout.GridContainerLite ::: _isShown");
  219. if("open" in this){ // for TitlePane, etc.
  220. return this.open; // Boolean
  221. }
  222. else{
  223. var node = this.domNode;
  224. return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden"); // Boolean
  225. }
  226. },
  227. layout: function(){
  228. // summary:
  229. // Resize of each child
  230. //console.log("dojox.layout.GridContainerLite ::: layout");
  231. if(this.doLayout){
  232. var contentBox = this._contentBox;
  233. dojo.marginBox(this.gridContainerTable, {
  234. 'h': contentBox.h - this._border.h
  235. });
  236. dojo.contentBox(this.domNode, {
  237. 'w': contentBox.w - this._border.w
  238. });
  239. }
  240. dojo.forEach(this.getChildren(), function(widget){
  241. if(widget.resize && dojo.isFunction(widget.resize)){
  242. widget.resize();
  243. }
  244. });
  245. },
  246. onShow: function(){
  247. // summary:
  248. // Enabled the Drag And Drop if it's necessary.
  249. //console.log("dojox.layout.GridContainerLite ::: onShow");
  250. if(this._disabled){
  251. this.enableDnd();
  252. }
  253. },
  254. onHide: function(){
  255. // summary:
  256. // Disabled the Drag And Drop if it's necessary.
  257. //console.log("dojox.layout.GridContainerLite ::: onHide");
  258. if(!this._disabled){
  259. this.disableDnd();
  260. }
  261. },
  262. _createCells: function(){
  263. // summary:
  264. // Create the columns of the GridContainer.
  265. // tags:
  266. // protected
  267. //console.log("dojox.layout.GridContainerLite ::: _createCells");
  268. if(this.nbZones === 0){ this.nbZones = 1; }
  269. var accept = this.acceptTypes.join(","),
  270. i = 0;
  271. var origWidths = this.colWidths || [];
  272. var widths = [];
  273. var colWidth;
  274. var widthSum = 0;
  275. // Calculate the widths of each column.
  276. for(i = 0; i < this.nbZones; i++){
  277. if(widths.length < origWidths.length){
  278. widthSum += origWidths[i];
  279. widths.push(origWidths[i]);
  280. }else{
  281. if(!colWidth){
  282. colWidth = (100 - widthSum)/(this.nbZones - i);
  283. }
  284. widths.push(colWidth);
  285. }
  286. }
  287. i = 0;
  288. while(i < this.nbZones){
  289. // Add the parameter accept in each zone used by AreaManager
  290. // (see method dojox.mdnd.AreaManager:registerByNode)
  291. this._grid.push({
  292. 'node': dojo.create("td", {
  293. 'class': "gridContainerZone",
  294. 'accept': accept,
  295. 'id': this.id + "_dz" + i,
  296. 'style': {
  297. 'width': widths[i] + "%"
  298. }
  299. }, this.gridNode)
  300. });
  301. i++;
  302. }
  303. },
  304. _getZonesAttr: function(){
  305. // summary:
  306. // return array of zone (domNode)
  307. return dojo.query(".gridContainerZone", this.containerNode);
  308. },
  309. enableDnd: function(){
  310. // summary:
  311. // Enable the Drag And Drop for children of GridContainer.
  312. //console.log("dojox.layout.GridContainerLite ::: enableDnd");
  313. var m = this._dragManager;
  314. dojo.forEach(this._grid, function(dropZone){
  315. m.registerByNode(dropZone.node);
  316. });
  317. m._dropMode.updateAreas(m._areaList);
  318. this._disabled = false;
  319. },
  320. disableDnd: function(){
  321. // summary:
  322. // Disable the Drag And Drop for children of GridContainer.
  323. //console.log("dojox.layout.GridContainerLite ::: disableDnd");
  324. var m = this._dragManager;
  325. dojo.forEach(this._grid, function(dropZone){
  326. m.unregister(dropZone.node);
  327. });
  328. m._dropMode.updateAreas(m._areaList);
  329. this._disabled = true;
  330. },
  331. _organizeChildren: function(){
  332. // summary:
  333. // List all zones and insert child into columns.
  334. //console.log("dojox.layout.GridContainerLite ::: _organizeChildren");
  335. var children = dojox.layout.GridContainerLite.superclass.getChildren.call(this);
  336. var numZones = this.nbZones,
  337. numPerZone = Math.floor(children.length / numZones),
  338. mod = children.length % numZones,
  339. i = 0;
  340. // console.log('numPerZone', numPerZone, ':: mod', mod);
  341. for(var z = 0; z < numZones; z++){
  342. for(var r = 0; r < numPerZone; r++){
  343. this._insertChild(children[i], z);
  344. i++;
  345. }
  346. if(mod > 0){
  347. try{
  348. this._insertChild(children[i], z);
  349. i++;
  350. }
  351. catch(e){
  352. console.error("Unable to insert child in GridContainer", e);
  353. }
  354. mod--;
  355. }
  356. else if(numPerZone === 0){
  357. break; // Optimization
  358. }
  359. }
  360. },
  361. _organizeChildrenManually: function (){
  362. // summary:
  363. // Organize children by column property of widget.
  364. //console.log("dojox.layout.GridContainerLite ::: _organizeChildrenManually");
  365. var children = dojox.layout.GridContainerLite.superclass.getChildren.call(this),
  366. length = children.length,
  367. child;
  368. for(var i = 0; i < length; i++){
  369. child = children[i];
  370. try{
  371. this._insertChild(child, child.column - 1);
  372. }
  373. catch(e){
  374. console.error("Unable to insert child in GridContainer", e);
  375. }
  376. }
  377. },
  378. _insertChild: function(/*Widget*/child, /*Integer*/column, /*Integer?*/p){
  379. // summary:
  380. // Insert a child in a specific column of the GridContainer widget.
  381. // column:
  382. // Column number
  383. // p:
  384. // Place in the zone (0 - first)
  385. // returns:
  386. // The widget inserted
  387. //console.log("dojox.layout.GridContainerLite ::: _insertChild", child, column, p);
  388. var zone = this._grid[column].node,
  389. length = zone.childNodes.length;
  390. if(typeof p === "undefined" || p > length){
  391. p = length;
  392. }
  393. if(this._disabled){
  394. dojo.place(child.domNode, zone, p);
  395. dojo.attr(child.domNode, "tabIndex", "0");
  396. }
  397. else{
  398. if(!child.dragRestriction){
  399. this._dragManager.addDragItem(zone, child.domNode, p, true);
  400. }
  401. else{
  402. dojo.place(child.domNode, zone, p);
  403. dojo.attr(child.domNode, "tabIndex", "0");
  404. }
  405. }
  406. child.set("column", column);
  407. return child; // Widget
  408. },
  409. removeChild: function(/*Widget*/ widget){
  410. //console.log("dojox.layout.GridContainerLite ::: removeChild");
  411. if(this._disabled){
  412. this.inherited(arguments);
  413. }
  414. else{
  415. this._dragManager.removeDragItem(widget.domNode.parentNode, widget.domNode);
  416. }
  417. },
  418. addService: function(/*Object*/child, /*Integer?*/column, /*Integer?*/p){
  419. //console.log("dojox.layout.GridContainerLite ::: addService");
  420. dojo.deprecated("addService is deprecated.", "Please use instead.", "Future");
  421. this.addChild(child, column, p);
  422. },
  423. addChild: function(/*Object*/child, /*Integer?*/column, /*Integer?*/p){
  424. // summary:
  425. // Add a child in a specific column of the GridContainer widget.
  426. // child:
  427. // widget to insert
  428. // column:
  429. // column number
  430. // p:
  431. // place in the zone (first = 0)
  432. // returns:
  433. // The widget inserted
  434. //console.log("dojox.layout.GridContainerLite ::: addChild");
  435. child.domNode.id = child.id;
  436. dojox.layout.GridContainerLite.superclass.addChild.call(this, child, 0);
  437. if(column < 0 || column == undefined){ column = 0; }
  438. if(p <= 0){ p = 0; }
  439. try{
  440. return this._insertChild(child, column, p);
  441. }
  442. catch(e){
  443. console.error("Unable to insert child in GridContainer", e);
  444. }
  445. return null; // Widget
  446. },
  447. _setColWidthsAttr: function(value){
  448. this.colWidths = dojo.isString(value) ? value.split(",") : (dojo.isArray(value) ? value : [value]);
  449. if(this._started){
  450. this._updateColumnsWidth();
  451. }
  452. },
  453. _updateColumnsWidth: function(/*Object*/ manager){
  454. // summary:
  455. // Update the columns width.
  456. // manager:
  457. // dojox.mdnd.AreaManager singleton
  458. // tags:
  459. // private
  460. //console.log("dojox.layout.GridContainer ::: _updateColumnsWidth");
  461. var length = this._grid.length;
  462. var origWidths = this.colWidths || [];
  463. var widths = [];
  464. var colWidth;
  465. var widthSum = 0;
  466. var i;
  467. // Calculate the widths of each column.
  468. for(i = 0; i < length; i++){
  469. if(widths.length < origWidths.length){
  470. widthSum += origWidths[i] * 1;
  471. widths.push(origWidths[i]);
  472. }else{
  473. if(!colWidth){
  474. colWidth = (100 - widthSum)/(this.nbZones - i);
  475. // If the numbers don't work out, make the remaining columns
  476. // an even width and let the code below average
  477. // out the differences.
  478. if(colWidth < 0){
  479. colWidth = 100 / this.nbZones;
  480. }
  481. }
  482. widths.push(colWidth);
  483. widthSum += colWidth * 1;
  484. }
  485. }
  486. // If the numbers are wrong, divide them all so they add up to 100
  487. if(widthSum > 100){
  488. var divisor = 100 / widthSum;
  489. for(i = 0; i < widths.length; i++){
  490. widths[i] *= divisor;
  491. }
  492. }
  493. // Set the widths of each node
  494. for(i = 0; i < length; i++){
  495. this._grid[i].node.style.width = widths[i] + "%";
  496. }
  497. },
  498. _selectFocus: function(/*Event*/event){
  499. // summary:
  500. // Enable keyboard accessibility into the GridContainer.
  501. // description:
  502. // Possibility to move focus into the GridContainer (TAB, LEFT ARROW, RIGHT ARROW, UP ARROW, DOWN ARROW).
  503. // Possibility to move GridContainer's children (Drag and Drop) with keyboard. (SHIFT + ARROW).
  504. // If the type of widget is not draggable, a popup is displayed.
  505. //console.log("dojox.layout.GridContainerLite ::: _selectFocus");
  506. if(this._disabled){ return; }
  507. var key = event.keyCode,
  508. k = dojo.keys,
  509. zone = null,
  510. focus = dijit.getFocus(),
  511. focusNode = focus.node,
  512. m = this._dragManager,
  513. found,
  514. i,
  515. j,
  516. r,
  517. children,
  518. area,
  519. widget;
  520. if(focusNode == this.containerNode){
  521. area = this.gridNode.childNodes;
  522. switch(key){
  523. case k.DOWN_ARROW:
  524. case k.RIGHT_ARROW:
  525. found = false;
  526. for(i = 0; i < area.length; i++){
  527. children = area[i].childNodes;
  528. for(j = 0; j < children.length; j++){
  529. zone = children[j];
  530. if(zone != null && zone.style.display != "none"){
  531. dijit.focus(zone);
  532. dojo.stopEvent(event);
  533. found = true;
  534. break;
  535. }
  536. }
  537. if(found){ break };
  538. }
  539. break;
  540. case k.UP_ARROW:
  541. case k.LEFT_ARROW:
  542. area = this.gridNode.childNodes;
  543. found = false;
  544. for(i = area.length-1; i >= 0 ; i--){
  545. children = area[i].childNodes;
  546. for(j = children.length; j >= 0; j--){
  547. zone = children[j];
  548. if(zone != null && zone.style.display != "none"){
  549. dijit.focus(zone);
  550. dojo.stopEvent(event);
  551. found = true;
  552. break;
  553. }
  554. }
  555. if(found){ break };
  556. }
  557. break;
  558. }
  559. }
  560. else{
  561. if(focusNode.parentNode.parentNode == this.gridNode){
  562. var child = (key == k.UP_ARROW || key == k.LEFT_ARROW) ? "lastChild" : "firstChild";
  563. var pos = (key == k.UP_ARROW || key == k.LEFT_ARROW) ? "previousSibling" : "nextSibling";
  564. switch(key){
  565. case k.UP_ARROW:
  566. case k.DOWN_ARROW:
  567. dojo.stopEvent(event);
  568. found = false;
  569. var focusTemp = focusNode;
  570. while(!found){
  571. children = focusTemp.parentNode.childNodes;
  572. var num = 0;
  573. for(i = 0; i < children.length; i++){
  574. if(children[i].style.display != "none"){ num++ };
  575. if(num > 1){ break; }
  576. }
  577. if(num == 1){ return; }
  578. if(focusTemp[pos] == null){
  579. zone = focusTemp.parentNode[child];
  580. }
  581. else{
  582. zone = focusTemp[pos];
  583. }
  584. if(zone.style.display === "none"){
  585. focusTemp = zone;
  586. }
  587. else{
  588. found = true;
  589. }
  590. }
  591. if(event.shiftKey){
  592. var parent = focusNode.parentNode;
  593. for(i = 0; i < this.gridNode.childNodes.length; i++){
  594. if(parent == this.gridNode.childNodes[i]){
  595. break;
  596. }
  597. }
  598. children = this.gridNode.childNodes[i].childNodes;
  599. for(j = 0; j < children.length; j++){
  600. if(zone == children[j]){
  601. break;
  602. }
  603. }
  604. if(dojo.isMoz || dojo.isWebKit){ i-- };
  605. widget = dijit.byNode(focusNode);
  606. if(!widget.dragRestriction){
  607. r = m.removeDragItem(parent, focusNode);
  608. this.addChild(widget, i, j);
  609. dojo.attr(focusNode, "tabIndex", "0");
  610. dijit.focus(focusNode);
  611. }
  612. else{
  613. dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
  614. }
  615. }
  616. else{
  617. dijit.focus(zone);
  618. }
  619. break;
  620. case k.RIGHT_ARROW:
  621. case k.LEFT_ARROW:
  622. dojo.stopEvent(event);
  623. if(event.shiftKey){
  624. var z = 0;
  625. if(focusNode.parentNode[pos] == null){
  626. if(dojo.isIE && key == k.LEFT_ARROW){
  627. z = this.gridNode.childNodes.length-1;
  628. }
  629. }
  630. else if(focusNode.parentNode[pos].nodeType == 3){
  631. z = this.gridNode.childNodes.length - 2;
  632. }
  633. else{
  634. for(i = 0; i < this.gridNode.childNodes.length; i++){
  635. if(focusNode.parentNode[pos] == this.gridNode.childNodes[i]){
  636. break;
  637. }
  638. z++;
  639. }
  640. if(dojo.isMoz || dojo.isWebKit){ z-- };
  641. }
  642. widget = dijit.byNode(focusNode);
  643. var _dndType = focusNode.getAttribute("dndtype");
  644. if(_dndType == null){
  645. //check if it's a dijit object
  646. if(widget && widget.dndType){
  647. _dndType = widget.dndType.split(/\s*,\s*/);
  648. }
  649. else{
  650. _dndType = ["text"];
  651. }
  652. }
  653. else{
  654. _dndType = _dndType.split(/\s*,\s*/);
  655. }
  656. var accept = false;
  657. for(i = 0; i < this.acceptTypes.length; i++){
  658. for(j = 0; j < _dndType.length; j++){
  659. if(_dndType[j] == this.acceptTypes[i]){
  660. accept = true;
  661. break;
  662. }
  663. }
  664. }
  665. if(accept && !widget.dragRestriction){
  666. var parentSource = focusNode.parentNode,
  667. place = 0;
  668. if(k.LEFT_ARROW == key){
  669. var t = z;
  670. if(dojo.isMoz || dojo.isWebKit){ t = z + 1 };
  671. place = this.gridNode.childNodes[t].childNodes.length;
  672. }
  673. // delete of manager :
  674. r = m.removeDragItem(parentSource, focusNode);
  675. this.addChild(widget, z, place);
  676. dojo.attr(r, "tabIndex", "0");
  677. dijit.focus(r);
  678. }
  679. else{
  680. dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
  681. }
  682. }
  683. else{
  684. var node = focusNode.parentNode;
  685. while(zone === null){
  686. if(node[pos] !== null && node[pos].nodeType !== 3){
  687. node = node[pos];
  688. }
  689. else{
  690. if(pos === "previousSibling"){
  691. node = node.parentNode.childNodes[node.parentNode.childNodes.length-1];
  692. }
  693. else{
  694. node = (dojo.isIE)? node.parentNode.childNodes[0]: node.parentNode.childNodes[1];
  695. }
  696. }
  697. zone = node[child];
  698. if(zone && zone.style.display == "none"){
  699. // check that all elements are not hidden
  700. children = zone.parentNode.childNodes;
  701. var childToSelect = null;
  702. if(pos == "previousSibling"){
  703. for(i = children.length-1; i >= 0; i--){
  704. if(children[i].style.display != "none"){
  705. childToSelect = children[i];
  706. break;
  707. }
  708. }
  709. }
  710. else{
  711. for(i = 0; i < children.length; i++){
  712. if(children[i].style.display != "none"){
  713. childToSelect = children[i];
  714. break;
  715. }
  716. }
  717. }
  718. if(!childToSelect){
  719. focusNode = zone;
  720. node = focusNode.parentNode;
  721. zone = null;
  722. }
  723. else{
  724. zone = childToSelect;
  725. }
  726. }
  727. }
  728. dijit.focus(zone);
  729. }
  730. break;
  731. }
  732. }
  733. }
  734. },
  735. destroy: function(){
  736. //console.log("dojox.layout.GridContainerLite ::: destroy");
  737. var m = this._dragManager;
  738. dojo.forEach(this._grid, function(dropZone){
  739. m.unregister(dropZone.node);
  740. });
  741. this.inherited(arguments);
  742. }
  743. });
  744. dojo.extend(dijit._Widget, {
  745. // column: String
  746. // Column of the grid to place the widget.
  747. // Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
  748. column : "1",
  749. // dragRestriction: Boolean
  750. // If true, the widget can not be draggable.
  751. // Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
  752. dragRestriction : false
  753. });
  754. }