listGrid's fieldEditor problem

Hi all,

I've got the following code:

  1. //sample data
  2.  
  3. <e:variable name="availableQItems" >
  4.         <e:data xmlns="" type="text/xml">
  5.                 <products xmlns="">
  6.                         <product id="3" name="6lt Foam" catname="Fire Extinguishers">
  7.                                 <price>40.8</price>
  8.                         </product>
  9.                         <product id="4" name="2kg Powder" catname="Fire Extinguishers">
  10.                                 <price>48</price>
  11.                         </product>
  12.                         <product id="5" name="9lt Water" catname="Fire Extinguishers">
  13.                                 <price>40.8</price>
  14.                         </product>
  15.                         <product id="57" name="Fire Action Notice" catname="General Signs">
  16.                                 <price>5.5</price>
  17.                         </product>
  18.                         <product id="64" name="Fire Plans Design" catname="General Signs">
  19.                                 <price>300</price>
  20.                         </product>
  21.                         <product id="65" name="Evacuation Plans" catname="General Signs">
  22.                                 <price>400</price>
  23.                         </product>
  24.                 </products>
  25.         </e:data>
  26. </e:variable>
  27.  
  28. //existingItems is empty at the beginning
  29. <e:variable name="existingItems" >
  30.         <e:data xmlns="" type="text/xml">
  31.                 <quotations>
  32.                 </quotations>
  33.         </e:data>
  34. </e:variable>
  35.  
  36. <b:dataSource id="myDataSource" name="myData" dataType="application/xml" dataSelect="$existingItems" e:behavior="b:localData">
  37.         <b:dataSchema>
  38.                 <b:dataRecordTemplate xmlns="">
  39.                         <item id="" name="" catname="">
  40.                                 <price>0.00</price>
  41.                                 <quantity>0</quantity>
  42.                         </item>
  43.                 </b:dataRecordTemplate>
  44.         </b:dataSchema>
  45.         <b:dataFormatter name="myPound" type="text/javascript">
  46.                 return '&pound;' + (parseFloat(value)).toFixed(2);
  47.         </b:dataFormatter>
  48.         <e:handler event="error" type="application/javascript">
  49.                 alert(event.message)
  50.         </e:handler>
  51. </b:dataSource>
  52.  
  53. <b:button>Add new item
  54.         <e:handler event="click" type="application/javascript"><![CDATA[
  55.                         var ds = bb.document.getElementById('myDataSource');
  56.  
  57.                         var uniqueId = 0;
  58.  
  59.                         while (true)
  60.                         {
  61.                                 if (btl.dataSource.recordExists(ds, ''+uniqueId))
  62.                                 {
  63.                                                 uniqueId++;
  64.                                 }
  65.                                 else
  66.                                 {
  67.                                                 break;
  68.                                 }
  69.                         }
  70.  
  71.                         var newRecordTemplate = {};
  72.                        
  73.                         newRecordTemplate['@id'] = '0';
  74.                         newRecordTemplate['@name'] = ' ';
  75.                         newRecordTemplate['@catname'] = '- category -';
  76.                         newRecordTemplate['price'] = '0';
  77.                         newRecordTemplate['quantity'] = '0';
  78.  
  79.                         btl.dataSource.actionRequest(ds, 'create', [newRecordTemplate]);
  80.                        
  81.                         var oListGrid = bb.document.getElementById('qListGrid');
  82.                        
  83.                         oListGrid.setAttribute("selectedIndexes", uniqueId);
  84.                         oListGrid.setProperty("focusedRow", uniqueId);
  85.                         bb.command.fireEvent(oListGrid, "focus", false, false);
  86.                         bb.command.fireEvent(oListGrid, "selectionChanged", false, false);
  87.         ]]></e:handler>
  88. </b:button>
  89.  
  90. <b:listGrid dataSource="myData" rowClasses="rowClass1, rowClass2" id="qListGrid" >
  91.         <b:listGridCol select="@id" label="pID" display="false" />
  92.         <b:listGridCol select="@catname" label="Category" width="170px" >
  93.                 <b:fieldEditor>
  94.                         <select>
  95.                                 <e:handler event="change" type="text/javascript">
  96.                                 <![CDATA[
  97.                                         var listgrid = bb.document.getElementById('qListGrid');
  98.                                         var categoryList = listgrid._._editControls[1];
  99.                                         var productList = listgrid._._editControls[2];
  100.                                         var price = listgrid._._editControls[3];
  101.                                        
  102.                                         //when category changes, we have to clear products list...                                                                     
  103.                                         productList.options.length = 0;
  104.                                        
  105.                                         //...get category name...
  106.                                         var catName = categoryList.value;
  107.                                        
  108.                                         //...get all products (matching category name)...
  109.                                         matchingProducts = bb.evaluate("//product[@catname eq '"+catName+"']",availableQItems);
  110.                                        
  111.                                         for (var i=0; i<matchingProducts.length; i++)
  112.                                         {
  113.                                                 var pName = matchingProducts[i].getAttribute('name');
  114.                                                 productList.options[i] = new Option(pName, pName, false, false);
  115.                                         }
  116.                                        
  117.                                 ]]>
  118.                                 </e:handler>
  119.                                 <?php echo $this->partialLoop("option.phtml",$this->itemCats); ?>
  120.                         </select>
  121.                 </b:fieldEditor>
  122.         </b:listGridCol>
  123.         <b:listGridCol select="@name" label="Product name" >
  124.                 <b:fieldEditor>
  125.                         <select>
  126.                                 <e:handler event="change" type="text/javascript">
  127.                                         console.info('items - selection changed');
  128.                                         var listgrid = bb.document.getElementById('qListGrid');
  129.                                         var productList = listgrid._._editControls[2];
  130.                                        
  131.                                         var productPrice = bb.evaluate("string(//product[@name eq '"+productList.value+"']/price)",availableQItems);
  132.                                        
  133.                                         var priceSpinner = bb.evaluate("//b:spinner",listgrid.modelNode);
  134.                                         var ctrl = bb.getControllerFromModel(priceSpinner[0]);
  135.  
  136.                                         ctrl._.__inputSubmit.value = productPrice;
  137.                                         ctrl._.__inputView.value = productPrice;
  138.                                 </e:handler>
  139.                         </select>
  140.                 </b:fieldEditor>
  141.         </b:listGridCol>
  142.         <b:listGridCol select="price" label="Unit price" format="myPound" width="70px" align="right" >
  143.                 <b:fieldEditor>
  144.                         <b:spinner decimals="2" min="0.00" max="10000.00" step="1.00" />
  145.                 </b:fieldEditor>
  146.         </b:listGridCol>
  147.         <b:listGridCol select="quantity" label="Quantity" width="60px" align="right" >
  148.                 <b:fieldEditor>
  149.                         <b:spinner decimals="0" min="1" max="10000" step="1" />
  150.                 </b:fieldEditor>
  151.         </b:listGridCol>
  152. </b:listGrid>

The basic idea is to select product's category from the first dropdown, then the second dropdown is being dynamically populated with products matching the selected category (the list of which is being stored in $availableQItems). Everything works well until this moment. Then, when you add another item to the listGrid, you go through the same procedure.

Now, let's say you want to edit the first item. When you bring it to edit mode, the second dropdown changes the saved value! It happens because the dropdown in fieldEditor is always the same, i.e. when you populate it with data, it retains that data and cannot show the correct list of products when editing previously added items.

I know it's complicated, but I don't know how to explain that more clearly - just try to use the code I provided to see what I mean.

So my question is: how to prevent this situation? How to detect that a listGrid goes to "edit mode" and how to populate the second dropdown with the correct data in that moment? Is there any event (like "onBeforeEdit" or "onEdit") I could use? As far as I have searched, there is nothing like that.

Any comments/workarounds/solutions greatly appreciated.

Any ideas?

Any ideas?

Hi Piotrek, I am trying to

Hi Piotrek,
I am trying to run your code, but I cannot because of the PHP on line 119:

<?php echo $this->partialLoop("option.phtml",$this->itemCats); ?>

Can you do something to make it runnable (mock-up the output, or attach a test PHP) so that I can understand what you are talking about?

I'm sorry for that omission.

I'm sorry for that omission. The sample output for 119 line is the following:

<option value="- category -">- category -</option>
<option value="category 1">category 1</option>
<option value="category 2">category 2</option>
<option value="Fire Extinguishers">Fire Extinguishers</option>
<option value="General Signs">General Signs</option>

Actually, I kind of sorted out most of my problems here, the only questions left are these:

- How to detect that a listGrid goes to "edit mode"?
- ...and how to populate the second dropdown with the correct data in that moment? [for now I just catch selectionChanged event, get category name from the first dropdown, select the right items (from available items list, with XPATH), populate the second dropdown with those items]
- Is there any event (like "onBeforeEdit" or "onEdit") I could use?

Event not fired

Hi Piotrek,
I talked to a developer, and it seems that the event you are asking for is not fired.
In the next release there will be a new and improved fieldEditor that does fire events.

Thank you

Thank you. There are a few significant issues that we are waiting to be solved (and which prevent our new application from working properly), so I cannot wait the next BB release.