Announcement

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

    SearchForm Dependent Selects

    I have a SearchForm with two selects. Each of them is bound to a different datasource. The second select will be populated based on first select. The code is as following:

    isc.SearchForm.create({
    cellPadding:4,
    numCols:6,
    fields:[
    { name:"field1",
    type: "select",
    required: false,
    optionDataSource:"myDS1",
    valueField:"typeId",
    displayField:"desc",
    searchForm:this,
    change: function (searchForm) {
    var typeId = this.getValue('field1');
    searchForm.getField('field2').getOptionDataSource().fetchData({typeId:typeId });
    }
    },
    { name:"field2",
    autoFetchData:false,
    type: "select",
    required: false,
    width:200,
    optionDataSource:"myDS2",
    valueField:"userId",
    displayField:"userName"
    }
    ],

    });


    The problem is:

    1. when I selected an item in the first select, the request was sent to the server. However, the value is null and this only happens for the first time.

    2. After the selected value changed, the server side sent back the data but the second select is not populated with the data.


    Am i missing something here?

    Thank you for your help!

    #2
    Hi JavaDeveloper

    There are a couple of reasons this is not working as you'd expect.

    Firstly FormItem.change fires when the user enters a new value, but before the value is available via item.getValue() - it works this way so you can return false from this method and suppress the change.
    The new value is passed into this method as a parameter, so in your change handler you would refer to that, rather than calling 'this.getValue()' to assemble the desired filter criteria.

    Secondly, your logic is calling 'fetchData()' directly on the second dataSource (myDS2). This method simply performs the fetch and allows you to fire an arbitrary callback - it won't effect the second form item at all, which is populated by a separate fetch operation against the dataSource.

    In 5.6, the best way to do this is to get rid of your change handler on the first FormItem, and instead implement a getPickListFilterCriteria() override on the second form item that assembles the desired criteria for the fetch based on the value of the first item.
    This method will then be run whenever the user shows the pickList, so if the value of the first item has changed, the second items set of options will be re-filtered.

    Your code would look something like this:
    Code:
    { name:"field2",
      autoFetchData:false,
      type: "select",
      required: false,
      width:200,
      optionDataSource:"myDS2",
      valueField:"userId",
      displayField:"userName",
      getPickListFilterCriteria : function () {
         // assumes form has ID "mySearchForm"
         return {typeId:mySearchForm.getValue("field1")}
      }
    }

    Comment


      #3
      with your suggestion, i am seeing the second "select" being populated. But it does not work the way I expected:

      I selected an item from the first "select". When I click on the second "select", nothing happens. I then selected a different item from the first "select", and when i click on the second "select", it was populated with the data.
      Why and how to fix?


      My requirement is like this:

      1. there are three "select" in a search form, say "select1", "select2", and "select3".
      2. "select2" is populated by calling server each time user selects a different item from "select1"
      3. "select3" is independent of "select1" and "select2"
      4. each time user selects a different item from "select2", "change()" on "select2" will fire and call server (with values from "select1", "select2", and "select3" as parameters) to populate a listgrid.
      5. each time user selects a different item from "select3", "change()" on "select3" will fire and call server (with values from "select1", "select2", and "select3" as parameters) to populate a listgrid.


      With the suggestion you proposed, one problem I can is that if user selects a different item from "select1" and a different item from "select3", the new value from "select1" and "select3" and old value from "select2" will be sent to server. So there is a way to let "change()" on "select1" to fire and populate data for "select2"? If so, how? If not, what other options do i have to do this?

      We have a very aggressive schedule and any help will be appreciated!

      Thanks.

      Comment


        #4
        Ok - I think this will do what you want:


        Continue to use getPickListFilterCriteria() to control what options show up in the second select item.

        Have a "changed" handler on the first select item that clears out the value of the second select item. This solves the problem of the value of the second item being out of date.

        Have a changed handler on both the second and third items that calls 'filter()' on your ListGrid, passing in the current values from the form.

        Note: using 'changed' rather than 'change' gives you the advantage that the newly entered value has been saved and is availble as this.getValue() / form.getValue('fieldName')).

        Code to demonstrate this (using the "supplyCategory" / "supplyItem" dataSources, since they're available in the SDK)

        Code:
        // Assume your list grid is called "itemList"
        isc.SearchForm.create({
            ID:"findForm",
            fields:[
                {name:"category", editorType:"select", 
                 optionDataSource:"supplyCategory",
                 // get rid of out of date values in the second select when this
                 // value changes
                 changed:"form.getItem('itemName').setValue(null);"
                },
                {name:"itemName", editorType:"select", 
                 optionDataSource:"supplyItem",
                 // filter set of options based on value of first field
                 getPickListFilterCriteria:function () {
                     return {category:findForm.getValue("category")};
                 },
                 // filter data on the listGrid on change
                 changed:"itemList.filterData(form.getValues());"
                },
                {name:"type", editorType:"select", 
                  valueMap:["ea", "roll", "pkt"],
                  // filter listGrid on change
                  changed:"itemList.filterData(form.getValues());"}
            ]
        });
        You should find with this code:
        - when you click on the first select item, it shows all the options from the supplyCategory dataSource.
        - when you click on the second select item, it shows only the values from the supplyItem dataSource that match the value of the first
        - when you select a value from the first select item it clears out the current value of the second select (and changes the filter criteria so next time the second select is clicked the set of possible options will be different).
        - when you select a value from either the second or third item, the ListGrid data is updated based on the filter criteria.

        I think this covers all your requirements - let us know if we've missed something. There are other approaches, but this is probably the easiest, if we understand your problem correctly.

        Thanks

        Comment


          #5
          Hi, Thank you for your reply.

          I followed the suggestions, I am still having the following issues:

          1. The first time I select an item from "select1" and then click on "select2", no items show in the list (but i am expecting the getPickListFilterCriteria() on "select2" will be fired and fetch data from server).
          I have to come back to "select1" and select a different item and from now on the "select2" will change based on "select1".
          Why and how to fix?

          2. Data inconsistent: I selected an item from "select1". I then selected another item from "select2". I went back to "select1" and selected a different item. Then I selected an item from "select3". The data submit to the server for "select2" is the old value. So is there a way to "changed()" function of "select1" to fire and populated data for "select2"? or are there other ways to do this?

          Thanks!

          Comment


            #6
            Hi Again,

            We're not reproducing these issues in our tests using the code we posted. If you could send us a prototype (to support@isomorphic.com), with step by step instructions to reproduce the issues, we'd be happy to take a look

            Thanks
            Isomorphic Support

            Comment


              #7
              Hi I have sent the code to support. Thanks.

              Comment

              Working...
              X