Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Combobox values in Editable Grid

    Hello,

    I have an editable grid. With a column that is a combox. The combox has a datasource and it can contain thousands of entries. I cannot use the Smart Client Server. Because I´m using Smart Client with a proprietary back end. This is the grid source:

    Code:
       isc.ListGrid.create(
        {
         ID:"openAdvancesListGrid",
         isGroup:false,
         selectionType:"single",
         canEdit:true,
         editEvent:"click",
         autoSaveEdits:false,
         alternateRecordStyles:true,
         modalEditing:true,
         fields:
         [
          {
           editorType:"comboBox",
           ID:"openAdvancesTripColumn",
           displayField:"openAdvancesTripColumn",
           editorProperties:
           {
            optionDataSource:isc.DataSource.create(
             {
              fields:
              [
               {
                primaryKey:true,
                name:"generatedIndex"
               },
               {
                name:"openAdvancesTripColumn"
               }
              ],
              dataFormat:"json",
              dataURL:"ScComboBoxDataStore?viewNumber=7&id=openAdvancesTripColumn",
              transformRequest:function (dsRequest) {
    			var operationType = {
    				operationType: dsRequest.operationType
    			};
    		 if (dsRequest.operationType == 'fetch') {
    			 var params = {
    				start : dsRequest.startRow,
    				end : dsRequest.endRow
    			 };
    			 // combine paging parameters with criteria
    			 return isc.addProperties({}, operationType, dsRequest.data, params);
    		 }},
              transformResponse:function (dsResponse, dsRequest, jsonData)  {
    			 if (dsRequest.operationType == 'fetch') {
    				dsResponse.totalRows = jsonData.totalRows;
    				dsResponse.endRow = jsonData.endRow;
    				dsResponse.startRow = jsonData.startRow;
    				};
    		 if (dsRequest.operationType == 'update') {
    		console.log(dsResponse);
    		};				
    				
    			},
              recordXPath:"/resultData"
             }
             ),
            displayField:"openAdvancesTripColumn"
           },
           width:250,
           name:"openAdvancesTripColumn",
           title:"Travels"
          }
         ],
         data:
         [
          {
           openAdvancesTripColumn:"01.08 - 02.08 London",
           generatedIndex:"1"
          }
         ]
        }
        )
    ...
    The data store of this column named openAdvancesTripColumn answers its data in JSON. Example:

    Code:
    {
     totalRows:"3",
     resultData:
     [
      {
       openAdvancesTripColumn:" – No Travel - ",
       generatedIndex:"1"
      },
      {
       openAdvancesTripColumn:"03.08 - 03.08 Paris",
       generatedIndex:"2"
      },
      {
       openAdvancesTripColumn:"01.08 - 02.08 London",
       generatedIndex:"3"
      }
     ]
    }
    Everything works fine so far. The user can chose a travel form the combobox.

    But I need to access the key (in this case the attribute generatedIndex) of the chosen object of the openAdvancesTripColumn.
    But when asking the grid with

    Code:
     
    openAdvancesListGrid.getEditValue(0,0)
    I´m getting only the chosen string, not the generatedIndex.

    What should I do in order to get the generatedIndex?

    Regards Thomas

    #2
    You can call getSelectedRecord on the ComboBoxItem to get the complete selected record (when there is one).

    Comment


      #3
      Yes, but this also answers only the string form the openAdvancesTripColumn, not the generatedIndex from the combobox as I need.

      Comment


        #4
        getSelectedRecord gives you the whole record, so you can acces any properites inside it as just record.propertyName, eg record.generatedIndex.

        Comment


          #5
          Ah, thank you, good point!

          But what is the ComboBox Item in my case? when executing

          openAdvancesTripColumn.getSelectedRecord()

          I´m getting always null

          Comment


            #6
            That is the ComboBoxItem (since you gave it that ID), however, a selected record is only going to be available once the user has actually chosen something from the drop-down list or typed a value with a unique completion.

            Comment


              #7
              Sorry, I don’t understand. I´m getting always null when executing

              openAdvancesTripColumn.getSelectedRecord()

              Independently if something was chosen in the combobox (=the combobox is blue), or not.

              In the above example source, I cannot see any ID “ComboBoxItem”. Could you please show me the exact code for the above example that gives me the selected record of the editor grid combobox?

              Comment


                #8
                ComboBoxItem is a classname and there are instances of the classname (just like with any other object oriented system). You wouldn't refer to the ComboBoxItem as "ComboBoxItem" but via a local variable, or in this case, by a global ID you gave it.

                However I've just noticed you put the ID property on the ListGridField, but this doesn't exist as a property on ListGridField. So your ComboBoxItem at the moment has no ID by which you could refer to it.

                Bigger picture, the ComboBoxItem is being created by the grid automatically and so does not always exist, so there's no way to refer to it that works at all times. How you refer to it depends on what context you're in (again, as with any OO system). For example, if you want to refer to it during a change() event, you would add the change() event to your editorProperties block, and within the change() event you could refer to the ComboBoxItem as "item" because that's one of the parameter of the change() event. Make sense?

                Comment


                  #9
                  Yes, thank you. It makes all sense what you say.

                  But my initial question is still unanswered. How can I get the chosen value of the combobox, instead of the chosen string?

                  My context is that I want to get the value at any time, for example from the firebug command line.

                  Comment


                    #10
                    ? I'm not sure how to answer that. If the user hasn't used the ComboBox, there is no chosen value, so of course it's not something that can be accessed at an arbitrary time.

                    Looking again at your code, it's a bit of a jumble. You've got a field "openAdvancesTripColumn" with an optionDataSource, but you haven't specified what valueField to use. You seem to expect that a number generatedIndex would be stored; if so, set valueField to "generatedIndex". But your data disagrees, and sets openAdvancesTripColumn to a user-visible String instead.

                    We'd suggest taking a look at the docs for listGridField.optionDataSource to get an idea of what your options are, and if you need more help, explaining much more specifically what values you are trying to store to what fields.

                    Comment


                      #11
                      I'm not sure how to answer that. If the user hasn't used the ComboBox, there is no chosen value, so of course it's not something that can be accessed at an arbitrary time.
                      Thank for your quick response. Yes, that would be OK, if it results null in case when nothing was chosen.

                      Looking again at your code, it's a bit of a jumble. You've got a field "openAdvancesTripColumn" with an optionDataSource, but you haven't specified what valueField to use. You seem to expect that a number generatedIndex would be stored; if so, set valueField to "generatedIndex". But your data disagrees, and sets openAdvancesTripColumn to a user-visible String instead.
                      Yes, you are right it is a jumble. It is my “best” result how I got it working. I already tried to set the valueField to "generatedIndex". But in this case I got the index, but the index was also displayed to the user in the combobox.
                      We'd suggest taking a look at the docs for listGridField.optionDataSource to get an idea of what your options are, and if you need more help, explaining much more specifically what values you are trying to store to what fields.
                      Yes, thank you for pointing me there. I read this several times. The Smart Client documentation is very good. Until this problem I got all questions answered from the documentation. But in this case, I did not manage create the grid with an editor combobox and the corresponding code to get the selected combobox value. And therefore I´m posting here.

                      I do not understand why there is the optionDataSource as an attribute of the column (=listGridField). And in other case it is an attribute of the editorProperties. The documentation says, that in case of comboxes with high number of entries, the editorProperties optionDataSource should be taken. This is what I did.

                      For me it looks like in Smart Client the column (=listGridField) *is* the editor widget. I´m also evaluating ExtJs. The columns there *have* an editor widget. IMHO this seems from me more obvious that the grid columns *have* an editor instead they *are* an editor. Because in the latter case, all attributes from all possible widgets must be copied to the column (=listGridField).

                      Anyway, I greatly appreciate any hint, how to create a gird with Smart Client, with comboxes that have a datasource with potentially thousand of entries. And How I could query the chosen value instead of the display value of that comboxes.

                      Comment


                        #12
                        Here's the relevant doc:

                        Unlike the similar use of PickList.optionDataSource for pickLists used during editing or filtering, listGridField.optionDataSource causes the entire set of records from the optionDataSource to be fetched, without paging. Hence listGridField.optionDataSource is appropriate only for smaller valueMaps. For very large valueMap situations, such as an accountId field that should be displayed as an accountName where there are thousands of accounts, the recommended approach is:

                        * do not set listGridField.optionDataSource
                        * declare two fields in the DataSource, eg "accountId" and "accountName".
                        * Set the ListGridField.displayField attribute on the data field to the name of the display field.
                        * When fetching records for display in a grid, have your server send back values for both fields, but show only the data field ("accountId") in the grid.

                        In this case the cells in the accountId field will show the record value from the accountName field. This approach means the valueMap will never be loaded in its entirety, instead, each loaded record contains the valueMapping for that one record, as a pair of fields within the record.
                        So, in your situation it sounds like your valueField is "generatedIndex" and your displayField is "openAdvancesTripColumn". You haven't really made this clear as we asked but we'll assume that this is the case.

                        Set these on the ListGrid field and when data is initially loaded in the grid (not the combobox), populate both fields.

                        Continue using ComboBoxItem as you are but set valueField and displayField to match the settings on the grid field. When change() fires on the ComboBoxItem, use getSelectedRecord() to get the selected record, and if there is one, grab the value of the displayField from the record, and apply it as an editValue on the grid.

                        Here's a code sample - runnable in any Feature Explorer example that incorporates the supplyItem DataSource. Note that it's not strictly necessary to add the "changed" handler below in most cases, since saving happens immediately and the record is refresh from the server, hence gets the new itemName that way.

                        Code:
                        isc.DataSource.create({
                            ID:"myOrders",
                            fields : [
                                { name : "orderId", type:"sequence", primaryKey:true },
                                { name : "itemID" },
                                { name : "itemName" },
                                {name: "quantity"},
                                {name: "unitPrice"}
                            ],
                            clientOnly:true,
                            testData : [
                                { orderId:1, itemID:272, itemName:"Compendium W60A4 Executive Tri-fold Grey" }
                            ]
                            
                        })
                        
                        isc.ListGrid.create({
                            ID: "orderItemList",
                            width:700, height:224, alternateRecordStyles:true, 
                            dataSource: myOrders,
                            autoFetchData: true,
                            canEdit: true
                            
                            fields:[
                                {name: "orderID"},
                                {name: "itemID", title: "Item Name", align: "left", width: "50%",  
                                 displayField: "itemName", editorType: "ComboBoxItem",
                                 editorProperties : {
                                    optionDataSource:"supplyItem", valueField:"itemID", displayField:"itemName",
                                    changed : function (form, item, value) {
                                        var cbRecord = item.getSelectedRecord();
                        
                                        if (!cbRecord) return;
                        
                                        var grid = item.grid;
                                        grid.setEditValue(grid.getEditRow(), "itemName", cbRecord.itemName);
                                    }
                                 } 
                                },
                                {name: "quantity"},
                                {name: "unitPrice"}
                            ]
                        });
                        PS: the Ext architecture (where a field "has a" editor) is limited in that it doesn't accommodate multiple different types of editors being used in different situations, which the SmartClient architecture does (see grid.getEditorType, getEditorProperties, and related APIs)

                        Comment


                          #13
                          Thank you very much for the insightful example. This clears up some points. :-)

                          But it looks like I did not explain it very good what I need to accomplish. I need to get the itemID of the selected supplyItem in the terms of your example code. But the example sets the itemName.

                          Anyway, the example has opened my eyes, I can set the itemID in the changed handler as an additional hidden attribute in the local grid data attribute:
                          Code:
                          changed : function (form, item, value) {
                            var cbRecord = item.getSelectedRecord();
                            if (!cbRecord) return;
                            var grid = item.grid;
                            grid.data[grid.getEditRow()].chosenItemID = cbRecord.itemID;
                          }
                          And then, I can query the id of the selected combobox item it at any time with:
                          Code:
                          orderItemList[0].chosenItemID
                          Do you see any problems with this solution?

                          Comment


                            #14
                            In the example, the itemId is already being stored to the record as part of the automatic ListGrid behavior, even if change() is not
                            implemented. Try it and see. Therefore, there's no need for the additional code you've shown.

                            Comment


                              #15
                              Oh, yes. That works. The itemId is set automaticity in the data of the grid. That’s fine!

                              But unfortunately the chosen combobox item is not shown. Independently of the chosen combobox entry it shows, also after the selection, the default value. For example for row 0, there is always “Compendium W60A4 Executive Tri-fold Grey” in the grid.
                              What must be done, in order to display the chosen value in the combo box of the grid?

                              Here the showcase:

                              Code:
                              isc.DataSource.create({
                                  ID:"myOrders",
                                  fields : [
                                      { name : "orderId", type:"sequence", primaryKey:true },
                                      { name : "itemID" },
                                      { name : "itemName" },
                                      {name: "quantity"},
                                      {name: "unitPrice"}
                                  ],
                                  clientOnly:true,
                                  testData : [
                                      { orderId:1, itemID:272, itemName:"Compendium W60A4 Executive Tri-fold Grey" },
                                      { orderId:1, itemID:1, itemName:"Pens Stabiliner 808 Ballpoint Fine Black" }
                                  ]
                                  
                              });
                              
                              isc.ListGrid.create({
                                  ID: "orderItemList",
                                  width:700, height:224, alternateRecordStyles:true, 
                                  dataSource: myOrders,
                                  autoFetchData: true,
                                  canEdit: true,
                                  
                                  fields:[
                                      {name: "orderID"},
                                      {name: "itemID", title: "Item Name", align: "left", width: "50%",  
                                       displayField: "itemName", editorType: "ComboBoxItem",
                                       editorProperties : {
                                          optionDataSource:"supplyItem", valueField:"itemID", displayField:"itemName"
                                                } 
                                      },
                                      {name: "quantity"},
                                      {name: "unitPrice"}
                                  ]
                              });

                              Comment

                              Working...
                              X