ItemExplorer.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  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.data.ItemExplorer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.data.ItemExplorer"] = true;
  8. dojo.provide("dojox.data.ItemExplorer");
  9. dojo.require("dijit.Tree");
  10. dojo.require("dijit.Dialog");
  11. dojo.require("dijit.Menu");
  12. dojo.require("dijit.form.ValidationTextBox");
  13. dojo.require("dijit.form.Textarea");
  14. dojo.require("dijit.form.Button");
  15. dojo.require("dijit.form.CheckBox");
  16. dojo.require("dijit.form.FilteringSelect");
  17. (function(){
  18. var getValue = function(store, item, prop){
  19. var value = store.getValues(item, prop);
  20. if(value.length < 2){
  21. value = store.getValue(item, prop);
  22. }
  23. return value;
  24. }
  25. dojo.declare("dojox.data.ItemExplorer", dijit.Tree, {
  26. useSelect: false,
  27. refSelectSearchAttr: null,
  28. constructor: function(options){
  29. dojo.mixin(this, options);
  30. var self = this;
  31. var initialRootValue = {};
  32. var root = this.rootModelNode = {value:initialRootValue,id:"root"};
  33. this._modelNodeIdMap = {};
  34. this._modelNodePropMap = {};
  35. var nextId = 1;
  36. this.model = {
  37. getRoot: function(onItem){
  38. onItem(root);
  39. },
  40. mayHaveChildren: function(modelNode){
  41. return modelNode.value && typeof modelNode.value == 'object' && !(modelNode.value instanceof Date);
  42. },
  43. getChildren: function(parentModelNode, onComplete, onError){
  44. var keys, parent, item = parentModelNode.value;
  45. var children = [];
  46. if(item == initialRootValue){
  47. onComplete([]);
  48. return;
  49. }
  50. var isItem = self.store && self.store.isItem(item, true);
  51. if(isItem && !self.store.isItemLoaded(item)){
  52. // if it is not loaded, do so now.
  53. self.store.loadItem({
  54. item:item,
  55. onItem:function(loadedItem){
  56. item = loadedItem;
  57. enumerate();
  58. }
  59. });
  60. }else{
  61. enumerate();
  62. }
  63. function enumerate(){
  64. // once loaded, enumerate the keys
  65. if(isItem){
  66. // get the properties through the dojo data API
  67. keys = self.store.getAttributes(item);
  68. parent = item;
  69. }else if(item && typeof item == 'object'){
  70. parent = parentModelNode.value;
  71. keys = [];
  72. // also we want to be able to drill down into plain JS objects/arrays
  73. for(var i in item){
  74. if(item.hasOwnProperty(i) && i != '__id' && i != '__clientId'){
  75. keys.push(i);
  76. }
  77. }
  78. }
  79. if(keys){
  80. for(var key, k=0; key = keys[k++];){
  81. children.push({
  82. property:key,
  83. value: isItem ? getValue(self.store, item, key) : item[key],
  84. parent: parent});
  85. }
  86. children.push({addNew:true, parent: parent, parentNode : parentModelNode});
  87. }
  88. onComplete(children);
  89. }
  90. },
  91. getIdentity: function(modelNode){
  92. if(!modelNode.id){
  93. if(modelNode.addNew){
  94. modelNode.property = "--addNew";
  95. }
  96. modelNode.id = nextId++;
  97. if(self.store){
  98. if(self.store.isItem(modelNode.value)){
  99. var identity = self.store.getIdentity(modelNode.value);
  100. (self._modelNodeIdMap[identity] = self._modelNodeIdMap[identity] || []).push(modelNode);
  101. }
  102. if(modelNode.parent){
  103. identity = self.store.getIdentity(modelNode.parent) + '.' + modelNode.property;
  104. (self._modelNodePropMap[identity] = self._modelNodePropMap[identity] || []).push(modelNode);
  105. }
  106. }
  107. }
  108. return modelNode.id;
  109. },
  110. getLabel: function(modelNode){
  111. return modelNode === root ?
  112. "Object Properties" :
  113. modelNode.addNew ? (modelNode.parent instanceof Array ? "Add new value" : "Add new property") :
  114. modelNode.property + ": " +
  115. (modelNode.value instanceof Array ? "(" + modelNode.value.length + " elements)" : modelNode.value);
  116. },
  117. onChildrenChange: function(modelNode){
  118. },
  119. onChange: function(modelNode){
  120. }
  121. };
  122. },
  123. postCreate: function(){
  124. this.inherited(arguments);
  125. // handle the clicking on the "add new property item"
  126. dojo.connect(this, "onClick", function(modelNode, treeNode){
  127. this.lastFocused = treeNode;
  128. if(modelNode.addNew){
  129. //this.focusNode(treeNode.getParent());
  130. this._addProperty();
  131. }else{
  132. this._editProperty();
  133. }
  134. });
  135. var contextMenu = new dijit.Menu({
  136. targetNodeIds: [this.rootNode.domNode],
  137. id: "contextMenu"
  138. });
  139. dojo.connect(contextMenu, "_openMyself", this, function(e){
  140. var node = dijit.getEnclosingWidget(e.target);
  141. if(node){
  142. var item = node.item;
  143. if(this.store.isItem(item.value, true) && !item.parent){
  144. dojo.forEach(contextMenu.getChildren(), function(widget){
  145. widget.attr("disabled", (widget.label != "Add"));
  146. });
  147. this.lastFocused = node;
  148. // TODO: Root Node - allow Edit when mutli-value editing is possible
  149. }else if(item.value && typeof item.value == 'object' && !(item.value instanceof Date)){
  150. // an object that's not a Date - could be a store item
  151. dojo.forEach(contextMenu.getChildren(), function(widget){
  152. widget.attr("disabled", (widget.label != "Add") && (widget.label != "Delete"));
  153. });
  154. this.lastFocused = node;
  155. // TODO: Object - allow Edit when mutli-value editing is possible
  156. }else if(item.property && dojo.indexOf(this.store.getIdentityAttributes(), item.property) >= 0){ // id node
  157. this.focusNode(node);
  158. alert("Cannot modify an Identifier node.");
  159. }else if(item.addNew){
  160. this.focusNode(node);
  161. }else{
  162. dojo.forEach(contextMenu.getChildren(), function(widget){
  163. widget.attr("disabled", (widget.label != "Edit") && (widget.label != "Delete"));
  164. })
  165. // this won't focus the node but gives us a way to reference the node
  166. this.lastFocused = node;
  167. }
  168. }
  169. });
  170. contextMenu.addChild(new dijit.MenuItem({label: "Add", onClick: dojo.hitch(this, "_addProperty")}));
  171. contextMenu.addChild(new dijit.MenuItem({label: "Edit", onClick: dojo.hitch(this, "_editProperty")}));
  172. contextMenu.addChild(new dijit.MenuItem({label: "Delete", onClick: dojo.hitch(this, "_destroyProperty")}));
  173. contextMenu.startup();
  174. },
  175. store: null,
  176. setStore: function(store){
  177. this.store = store;
  178. var self = this;
  179. if(this._editDialog){
  180. this._editDialog.destroyRecursive();
  181. delete this._editDialog;
  182. }
  183. // i think we should just destroy this._editDialog and let _createEditDialog take care of everything
  184. // once it gets called again by either _editProperty or _addProperty - it will create everything again
  185. // using the new store. this way we don't need to keep track of what is in the dialog if we change it.
  186. /*if(this._editDialog && this.useSelect){
  187. dojo.query(".reference [widgetId]", this._editDialog.containerNode).forEach(function(node){
  188. dijit.getEnclosingWidget(node).attr("store", store);
  189. });
  190. }*/
  191. dojo.connect(store, "onSet", function(item, attribute, oldValue, newValue){
  192. var nodes, i, identity = self.store.getIdentity(item);
  193. nodes = self._modelNodeIdMap[identity];
  194. if(nodes &&
  195. (oldValue === undefined || newValue === undefined ||
  196. oldValue instanceof Array || newValue instanceof Array || typeof oldValue == 'object' || typeof newValue == 'object')){
  197. for(i = 0; i < nodes.length; i++){
  198. (function(node){
  199. self.model.getChildren(node, function(children){
  200. self.model.onChildrenChange(node, children);
  201. });
  202. })(nodes[i]);
  203. }
  204. }
  205. nodes = self._modelNodePropMap[identity + "." + attribute];
  206. if(nodes){
  207. for(i = 0; i < nodes.length; i++){
  208. nodes[i].value = newValue;
  209. self.model.onChange(nodes[i]);
  210. }
  211. }
  212. });
  213. this.rootNode.setChildItems([]);
  214. },
  215. setItem: function(item){
  216. // this is called to show a different item
  217. // reset the maps, for the root getIdentity is not called, so we pre-initialize it here
  218. (this._modelNodeIdMap = {})[this.store.getIdentity(item)] = [this.rootModelNode];
  219. this._modelNodePropMap = {};
  220. this.rootModelNode.value = item;
  221. var self = this;
  222. this.model.getChildren(this.rootModelNode, function(children){
  223. self.rootNode.setChildItems(children);
  224. });
  225. },
  226. refreshItem: function(){
  227. this.setItem(this.rootModelNode.value);
  228. },
  229. _createEditDialog: function(){
  230. this._editDialog = new dijit.Dialog({
  231. title: "Edit Property",
  232. execute: dojo.hitch(this, "_updateItem"),
  233. preload: true
  234. });
  235. this._editDialog.placeAt(dojo.body());
  236. this._editDialog.startup();
  237. // handle for dialog content
  238. var pane = dojo.doc.createElement('div');
  239. // label for property
  240. var labelProp = dojo.doc.createElement('label');
  241. dojo.attr(labelProp, "for", "property");
  242. dojo.style(labelProp, "fontWeight", "bold");
  243. dojo.attr(labelProp, "innerHTML", "Property:")
  244. pane.appendChild(labelProp);
  245. // property name field
  246. var propName = new dijit.form.ValidationTextBox({
  247. name: "property",
  248. value: "",
  249. required: true,
  250. disabled: true
  251. }).placeAt(pane);
  252. pane.appendChild(dojo.doc.createElement("br"));
  253. pane.appendChild(dojo.doc.createElement("br"));
  254. // radio button for "value"
  255. var value = new dijit.form.RadioButton({
  256. name: "itemType",
  257. value: "value",
  258. onClick: dojo.hitch(this, function(){this._enableFields("value");})
  259. }).placeAt(pane);
  260. // label for value
  261. var labelVal = dojo.doc.createElement('label');
  262. dojo.attr(labelVal, "for", "value");
  263. dojo.attr(labelVal, "innerHTML", "Value (JSON):")
  264. pane.appendChild(labelVal);
  265. // container for value fields
  266. var valueDiv = dojo.doc.createElement("div");
  267. dojo.addClass(valueDiv, "value");
  268. // textarea
  269. var textarea = new dijit.form.Textarea({
  270. name: "jsonVal"
  271. }).placeAt(valueDiv);
  272. pane.appendChild(valueDiv);
  273. // radio button for "reference"
  274. var reference = new dijit.form.RadioButton({
  275. name: "itemType",
  276. value: "reference",
  277. onClick: dojo.hitch(this, function(){this._enableFields("reference");})
  278. }).placeAt(pane);
  279. // label for reference
  280. var labelRef = dojo.doc.createElement('label');
  281. dojo.attr(labelRef, "for", "_reference");
  282. dojo.attr(labelRef, "innerHTML", "Reference (ID):")
  283. pane.appendChild(labelRef);
  284. pane.appendChild(dojo.doc.createElement("br"));
  285. // container for reference fields
  286. var refDiv = dojo.doc.createElement("div");
  287. dojo.addClass(refDiv, "reference");
  288. if(this.useSelect){
  289. // filteringselect
  290. // TODO: see if there is a way to sort the items in this list
  291. var refSelect = new dijit.form.FilteringSelect({
  292. name: "_reference",
  293. store: this.store,
  294. searchAttr: this.refSelectSearchAttr || this.store.getIdentityAttributes()[0],
  295. required: false,
  296. value: null, // need to file a ticket about the fetch that happens when declared with value: null
  297. pageSize: 10
  298. }).placeAt(refDiv);
  299. }else{
  300. var refTextbox = new dijit.form.ValidationTextBox({
  301. name: "_reference",
  302. value: "",
  303. promptMessage: "Enter the ID of the item to reference",
  304. isValid: dojo.hitch(this, function(isFocused){
  305. // don't validate while it's focused
  306. return true;//isFocused || this.store.getItemByIdentity(this._editDialog.attr("value")._reference);
  307. })
  308. }).placeAt(refDiv);
  309. }
  310. pane.appendChild(refDiv);
  311. pane.appendChild(dojo.doc.createElement("br"));
  312. pane.appendChild(dojo.doc.createElement("br"));
  313. // buttons
  314. var buttons = document.createElement('div');
  315. buttons.setAttribute("dir", "rtl");
  316. var cancelButton = new dijit.form.Button({type: "reset", label: "Cancel"}).placeAt(buttons);
  317. cancelButton.onClick = dojo.hitch(this._editDialog, "onCancel");
  318. var okButton = new dijit.form.Button({type: "submit", label: "OK"}).placeAt(buttons);
  319. pane.appendChild(buttons);
  320. this._editDialog.attr("content", pane);
  321. },
  322. _enableFields: function(selection){
  323. // enables/disables fields based on whether the value in this._editDialog is a reference or a primitive value
  324. switch(selection){
  325. case "reference":
  326. dojo.query(".value [widgetId]", this._editDialog.containerNode).forEach(function(node){
  327. dijit.getEnclosingWidget(node).attr("disabled", true);
  328. });
  329. dojo.query(".reference [widgetId]", this._editDialog.containerNode).forEach(function(node){
  330. dijit.getEnclosingWidget(node).attr("disabled", false);
  331. });
  332. break;
  333. case "value":
  334. dojo.query(".value [widgetId]", this._editDialog.containerNode).forEach(function(node){
  335. dijit.getEnclosingWidget(node).attr("disabled", false);
  336. });
  337. dojo.query(".reference [widgetId]", this._editDialog.containerNode).forEach(function(node){
  338. dijit.getEnclosingWidget(node).attr("disabled", true);
  339. });
  340. break;
  341. }
  342. },
  343. _updateItem: function(vals){
  344. // a single "execute" function that handles adding and editing of values and references.
  345. var node, item, val, storeItemVal, editingItem = this._editDialog.attr("title") == "Edit Property";
  346. var editDialog = this._editDialog;
  347. var store = this.store;
  348. function setValue(){
  349. try{
  350. var itemVal, propPath = [];
  351. var prop = vals.property;
  352. if(editingItem){
  353. while(!store.isItem(item.parent, true)){
  354. node = node.getParent();
  355. propPath.push(item.property);
  356. item = node.item;
  357. }
  358. if(propPath.length == 0){
  359. // working with an item attribute already
  360. store.setValue(item.parent, item.property, val);
  361. }else{
  362. // need to walk back down the item property to the object
  363. storeItemVal = getValue(store, item.parent, item.property);
  364. if(storeItemVal instanceof Array){
  365. // create a copy for modification
  366. storeItemVal = storeItemVal.concat();
  367. }
  368. itemVal = storeItemVal;
  369. while(propPath.length > 1){
  370. itemVal = itemVal[propPath.pop()];
  371. }
  372. itemVal[propPath] = val; // this change is reflected in storeItemVal as well
  373. store.setValue(item.parent, item.property, storeItemVal);
  374. }
  375. }else{
  376. // adding a property
  377. if(store.isItem(value, true)){
  378. // adding a top-level property to an item
  379. if(!store.isItemLoaded(value)){
  380. // fetch the value and see if it is an array
  381. store.loadItem({
  382. item: value,
  383. onItem: function(loadedItem){
  384. if(loadedItem instanceof Array){
  385. prop = loadedItem.length;
  386. }
  387. store.setValue(loadedItem, prop, val);
  388. }
  389. });
  390. }else{
  391. if(value instanceof Array){
  392. prop = value.length;
  393. }
  394. store.setValue(value, prop, val);
  395. }
  396. }else{
  397. // adding a property to a lower level in an item
  398. if(item.value instanceof Array){
  399. propPath.push(item.value.length);
  400. }else{
  401. propPath.push(vals.property);
  402. }
  403. while(!store.isItem(item.parent, true)){
  404. node = node.getParent();
  405. propPath.push(item.property);
  406. item = node.item;
  407. }
  408. storeItemVal = getValue(store, item.parent, item.property);
  409. itemVal = storeItemVal;
  410. while(propPath.length > 1){
  411. itemVal = itemVal[propPath.pop()];
  412. }
  413. itemVal[propPath] = val;
  414. store.setValue(item.parent, item.property, storeItemVal);
  415. }
  416. }
  417. }catch(e){
  418. alert(e);
  419. }
  420. }
  421. if(editDialog.validate()){
  422. node = this.lastFocused;
  423. item = node.item;
  424. var value = item.value;
  425. // var property = null;
  426. if(item.addNew){
  427. // we are adding a property to the parent item
  428. // the real value of the parent is in the parent property of the lastFocused item
  429. // this.lastFocused.getParent().item.value may be a reference to an item
  430. value = node.item.parent;
  431. node = node.getParent();
  432. item = node.item;
  433. }
  434. val = null;
  435. switch(vals.itemType){
  436. case "reference":
  437. this.store.fetchItemByIdentity({identity:vals._reference,
  438. onItem:function(item){
  439. val = item;
  440. setValue();
  441. },
  442. onError:function(){
  443. alert("The id could not be found");
  444. }
  445. });
  446. break;
  447. case "value":
  448. var jsonVal = vals.jsonVal;
  449. val = dojo.fromJson(jsonVal);
  450. // ifit is a function we want to preserve the source (comments, et al)
  451. if(typeof val == 'function'){
  452. val.toString = function(){
  453. return jsonVal;
  454. }
  455. }
  456. setValue();
  457. break;
  458. }
  459. }else{
  460. // the form didn't validate - show it again.
  461. editDialog.show();
  462. }
  463. },
  464. _editProperty: function(){
  465. // this mixin stops us polluting the tree item with jsonVal etc.
  466. // FIXME: if a store identifies items by instanceof checks, this will fail
  467. var item = dojo.mixin({}, this.lastFocused.item);
  468. // create the dialog or reset it if it already exists
  469. if(!this._editDialog){
  470. this._createEditDialog();
  471. }else{
  472. this._editDialog.reset();
  473. }
  474. // not allowed to edit an item's id - so check for that and stop it.
  475. if(dojo.indexOf(this.store.getIdentityAttributes(), item.property) >= 0){
  476. alert("Cannot Edit an Identifier!");
  477. }else{
  478. this._editDialog.attr("title", "Edit Property");
  479. // make sure the property input is disabled
  480. dijit.getEnclosingWidget(dojo.query("input", this._editDialog.containerNode)[0]).attr("disabled", true);
  481. if(this.store.isItem(item.value, true)){
  482. // root node || Item reference
  483. if(item.parent){
  484. // Item reference
  485. item.itemType = "reference";
  486. this._enableFields(item.itemType);
  487. item._reference = this.store.getIdentity(item.value);
  488. this._editDialog.attr("value", item);
  489. this._editDialog.show();
  490. } // else root node
  491. }else{
  492. if(item.value && typeof item.value == 'object' && !(item.value instanceof Date)){
  493. // item.value is an object but it's NOT an item from the store - no-op
  494. // only allow editing on a property not on the node that represents the object/array
  495. }else{
  496. // this is a primitive
  497. item.itemType = "value";
  498. this._enableFields(item.itemType);
  499. item.jsonVal = typeof item.value == 'function' ?
  500. // use the plain toString for functions, dojo.toJson doesn't support functions
  501. item.value.toString() :
  502. item.value instanceof Date ?
  503. // A json-ish form of a date:
  504. 'new Date("' + item.value + '")' :
  505. dojo.toJson(item.value);
  506. this._editDialog.attr("value", item);
  507. this._editDialog.show();
  508. }
  509. }
  510. }
  511. },
  512. _destroyProperty: function(){
  513. var node = this.lastFocused;
  514. var item = node.item;
  515. var propPath = [];
  516. // we have to walk up the tree to the item before we can know if we're working with the identifier
  517. while(!this.store.isItem(item.parent, true) || item.parent instanceof Array){
  518. node = node.getParent();
  519. propPath.push(item.property);
  520. item = node.item;
  521. }
  522. // this will prevent any part of the identifier from being changed
  523. if(dojo.indexOf(this.store.getIdentityAttributes(), item.property) >= 0){
  524. alert("Cannot Delete an Identifier!");
  525. }else{
  526. try{
  527. if(propPath.length > 0){
  528. // not deleting a top-level property of an item so get the top-level store item to change
  529. var itemVal, storeItemVal = getValue(this.store, item.parent, item.property);
  530. itemVal = storeItemVal;
  531. // walk back down the object if needed
  532. while(propPath.length > 1){
  533. itemVal = itemVal[propPath.pop()];
  534. }
  535. // delete the property
  536. if(dojo.isArray(itemVal)){
  537. // the value being deleted represents an array element
  538. itemVal.splice(propPath, 1);
  539. }else{
  540. // object property
  541. delete itemVal[propPath];
  542. }
  543. // save it back to the store
  544. this.store.setValue(item.parent, item.property, storeItemVal);
  545. }else{
  546. // deleting an item property
  547. this.store.unsetAttribute(item.parent, item.property);
  548. }
  549. }catch(e){
  550. alert(e);
  551. }
  552. }
  553. },
  554. _addProperty: function(){
  555. // item is what we are adding a property to
  556. var item = this.lastFocused.item;
  557. // value is the real value of the item - not a reference to a store item
  558. var value = item.value;
  559. var showDialog = dojo.hitch(this, function(){
  560. var property = null;
  561. if(!this._editDialog){
  562. this._createEditDialog();
  563. }else{
  564. this._editDialog.reset();
  565. }
  566. // are we adding another item to an array?
  567. if(value instanceof Array){
  568. // preset the property to the next index in the array and disable the property field
  569. property = value.length;
  570. dijit.getEnclosingWidget(dojo.query("input", this._editDialog.containerNode)[0]).attr("disabled", true);
  571. }else{
  572. // enable the property TextBox
  573. dijit.getEnclosingWidget(dojo.query("input", this._editDialog.containerNode)[0]).attr("disabled", false);
  574. }
  575. this._editDialog.attr("title", "Add Property");
  576. // default to a value type
  577. this._enableFields("value");
  578. this._editDialog.attr("value", {itemType: "value", property: property});
  579. this._editDialog.show();
  580. });
  581. if(item.addNew){
  582. // we are adding a property to the parent item
  583. item = this.lastFocused.getParent().item;
  584. // the real value of the parent is in the parent property of the lastFocused item
  585. // this.lastFocused.getParent().item.value may be a reference to an item
  586. value = this.lastFocused.item.parent;
  587. }
  588. if(item.property && dojo.indexOf(this.store.getIdentityAttributes(), item.property) >= 0){
  589. alert("Cannot add properties to an ID node!");
  590. }else{
  591. // ifthe value is an item then we need to get the item's value
  592. if(this.store.isItem(value, true) && !this.store.isItemLoaded(value)){
  593. // fetch the value and see if it is an array
  594. this.store.loadItem({
  595. item: value,
  596. onItem: function(loadedItem){
  597. value = loadedItem;
  598. showDialog();
  599. }
  600. });
  601. }else{
  602. showDialog();
  603. }
  604. //
  605. }
  606. }
  607. });
  608. })();
  609. }