GridContainerLite.js 24 KB

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