Announcement

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

    Form Dependency - Select Item value population issue

    Isomorphic,

    There was a requirement where there would be two drop downs(one with list of years, and one with list of months). The values would be populated from the database.

    Here is the UI code
    Code:
    fromYear.setOptionDataSource(DataSource.get("dateRange"));
            Criteria criteria = new Criteria();
            criteria.addCriteria("PRODUCT_ID","NA_ADB");
            criteria.addCriteria("CLIENT_ID", 99);
            fromYear.setOptionCriteria(criteria);
            fromYear.setOptionOperationId("yearFetch");
            fromYear.setValueField("YEAR_NUM");
            fromYear.setAutoFetchData(true);
    
            fromYear.setName("fromYear");
            fromYear.setTitle("From");
            fromYear.setDefaultToFirstOption(true);
            fromYear.setWidth(60);
            fromYear.setWrapTitle(true);
            fromYear.setColSpan(1);
            //fromYear.setValueMap();
    
    
            fromMonth.setOptionDataSource(DataSource.get("dateRange"));
            Criteria criteriaFromMonth = new Criteria();
            criteriaFromMonth.addCriteria("PRODUCT_ID","NA_ADB");
            criteriaFromMonth.addCriteria("CLIENT_ID", 99);
            int selectedFromYear =  2011;
    //                (Integer)fromYear.getValue();
            criteriaFromMonth.addCriteria("YEAR_NUM" ,selectedFromYear);
            fromMonth.setOptionCriteria(criteriaFromMonth);
            fromMonth.setOptionOperationId("monthFetch");
            fromMonth.setValueField("MONTH_SHORT_NUM");
            fromMonth.setAutoFetchData(true);
            fromMonth.setName("fromMonth");
            fromMonth.setShowTitle(false);
            fromMonth.setType("comboBox");
            fromMonth.setWidth(60);
            fromMonth.setDefaultToFirstOption(true);
            fromMonth.setWrapTitle(false);
            fromMonth.setColSpan(1);
            fromMonth.setAutoFetchData(true);
    //        fromMonth.setValueMap("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","NOV","DEC");
            fromYear.addChangedHandler(new ChangedHandler() {
                public void onChanged(ChangedEvent changedEvent) {
                    int selectedItem = (Integer) changedEvent.getValue();
                    fromMonth.clearValue();
                    fromMonth.setOptionDataSource(DataSource.get("dateRange"));
                    Criteria criteriaFromMonth = new Criteria();
                    criteriaFromMonth.addCriteria("PRODUCT_ID","NA_ADB");
                    criteriaFromMonth.addCriteria("CLIENT_ID", 99);
    //                int selectedFromYear =  2011;
            //                (Integer)fromYear.getValue();
                    criteriaFromMonth.addCriteria("YEAR_NUM" ,selectedItem);
                    fromMonth.setOptionCriteria(criteriaFromMonth);
                    fromMonth.setOptionOperationId("monthFetch");
                    fromMonth.setValueField("MONTH_SHORT_NUM");
                    fromMonth.setAutoFetchData(true);
                    fromMonth.redraw();
                }
            });
    This is my ds.xml file
    Code:
    <DataSource ID="dateRange" table="CLIENT_VALID_DATES" serverType="sql" dbName="Oracle" showPrompt="false" qualifyColumnNames="false">
        <fields>
            <field name="CLIENT_ID" type="number" required="false" title="CLIENT_ID"/>
            <field name="YEAR_NUM" type="number" required="true" title="YEAR_NUM"/>
            <field name="MONTH_NUM" type="number" required="false" title="MONTH_NUM"/>
            <field name="MONTH_SHORT_NAME" type="text" required="false" title="MONTH_SHORT_NAME"/>
            <field name="MONTH_ID" type="number" required="false" title="MONTH_ID"/>
            <field name="QUARTER_ID" type="number" required="false" title="QUARTER_ID"/>
            <field name="PRODUCT_ID" type="text" required="false" title="PRODUCT_ID"/>
        </fields>
        <operationBindings>
            <operationBinding operationId="yearFetch" operationType="fetch">
                <serverObject lookupStyle="new" className="com.sabre.apd.mi.smartgwt.server.DateRangeDMI"/>
                <selectClause>
                     DISTINCT month_num, month_short_name, year_num
                </selectClause>
                <tableClause>
                    CLIENT_VALID_DATES
                </tableClause>
                <whereClause>
                    ($defaultWhereClause)
                </whereClause>
                <orderClause>
                    year_num desc ,month_num desc
                </orderClause>
            </operationBinding>
        </operationBindings>
        <operationBindings>
            <operationBinding operationId="monthFetch" operationType="fetch">
                <serverObject lookupStyle="new" className="com.sabre.apd.mi.smartgwt.server.DateRangeDMI"/>
            </operationBinding>
        </operationBindings>
    
    </DataSource>
    Here is the DMI class
    Code:
    public class DateRangeDMI {
        public DSResponse fetch(DSRequest dsRequest)
                throws Exception {
            long clientId = (Long)dsRequest.getCriteria().get("CLIENT_ID");
            String appType = (String) dsRequest.getCriteria().get("PRODUCT_ID");
            String operationID = dsRequest.getOperationId();
    
    
            DSResponse dsResponse = new DSResponse();
            if(operationID.equalsIgnoreCase("yearFetch"))
            {
                List<Map> yearList = CacheManager.getInstance().getYears(clientId,appType,dsRequest) ;
                dsResponse.setData(yearList);
            }
            else if(operationID.equalsIgnoreCase("monthFetch"))
            {
                int year = (Integer)dsRequest.getCriteria().get("YEAR_NUM");
                List<Map> monthList = CacheManager.getInstance().getMonths(clientId,appType,year,dsRequest) ;
                dsResponse.setData(monthList);
            }
            return dsResponse;
        }
    }
    By default, fromYear SelectItem would result into population of Years, But fromMonth would be populated based on what would be selected when the data gets loaded in fromYear Select Item.

    Here are my logs
    Code:
     
    
    Loading module: MarketIntelligence
      Top URL: http://127.0.0.1:8888/MarketIntelligence.html?gwt.codesvr=127.0.0.1:9997
      User agent: FF
      Remote host: 127.0.0.1:55215
      Tab key: 085EC900
      Session key: h"7Z3ikau",7}v14
    ERROR: Unable to load module entry point class com.sabre.apd.mi.smartgwt.client.MarketIntelligence (see associated exception for details). com.google.gwt.core.client.JavaScriptException: (TypeError): _1.getField(this.getValueFieldName()) is undefined
    	at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:248)
    	at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
    	at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
    	at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:289)
    	at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:107)
    	at com.smartgwt.client.widgets.form.ValuesManager.addMember(ValuesManager.java)
    	at com.sabre.apd.mi.smartgwt.client.searchCriteria.ODCriteria.fetchReportInputForm(ODCriteria.java:880)
    	at com.sabre.apd.mi.smartgwt.client.searchCriteria.ODCriteria.<init>(ODCriteria.java:41)
    	at com.sabre.apd.mi.smartgwt.client.layout.SearchCriteriaPane.getSearchCriteria(SearchCriteriaPane.java:383)
    	at com.sabre.apd.mi.smartgwt.client.layout.SearchCriteriaPane.createSearchCriteriaModules(SearchCriteriaPane.java:77)
    	at com.sabre.apd.mi.smartgwt.client.layout.SearchCriteriaPane.<init>(SearchCriteriaPane.java:39)
    	at com.sabre.apd.mi.smartgwt.client.MarketIntelligence.onModuleLoad(MarketIntelligence.java:60)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:396)
    	at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)
    	at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:525)
    	at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
    	at java.lang.Thread.run(Thread.java:619)
    ERROR: Failed to load module 'MarketIntelligence' from user agent 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2' at 127.0.0.1:55215.
    Please let me know what is the issue here and is this is the better approach to achieve Field dependency?

    #2
    I tried with Static data, which works fine but not with dynamic data(like populate from db etc..)

    Comment


      #3
      I have changed by adding addDataArrivedHandlers as below. and it loads the correct desired values. But it is not allowing me to select Year and causing infinite call to addDataArrivedHandler()

      Here is my code.
      Code:
      fromYear.addDataArrivedHandler(new DataArrivedHandler() {
                  public void onDataArrived(DataArrivedEvent event) {
                          fromMonth.setOptionDataSource(DataSource.get("dateRange"));
                          Criteria criteriaFromMonth = new Criteria();
                          criteriaFromMonth.addCriteria("PRODUCT_ID","NA_ADB");
                          criteriaFromMonth.addCriteria("CLIENT_ID", 99);
                          int selectedFromYear = Integer.parseInt(fromYear.getValue().toString());
                  //                (Integer)fromYear.getValue();
                          criteriaFromMonth.addCriteria("YEAR_NUM" ,selectedFromYear);
                          fromMonth.setOptionCriteria(criteriaFromMonth);
                          fromMonth.setOptionOperationId("monthFetch");
                          fromMonth.setValueField("MONTH_SHORT_NAME");
                          fromMonth.fetchData();
                          fromMonth.setDefaultToFirstOption(true);
                  }
              });
      As even Year combobox will be loaded from db, i added addDataArrivedHandler, so that based on the first Year, Month combobox gets populated(which works fine).

      Now, if i want to change years(i mean when i click), it agains calls addDataArrivedHandler() and goes for infinite loop.

      Please let me know how i can control this.

      Comment


        #4
        Wrong approach - take a look at the Databound Dependent Selects examples in the SmartGWT Showcase - they address specifically this use case.

        Comment


          #5
          In showcase, you are using static data but here in my case, i am populating from db, hence i am using addDataArrivedHandler method.

          Comment


            #6
            Isomorphic,

            As data population takes time, i wont be getting value, which causes Null pointer exception as there wont be any value.
            String category = (String) categoryItem.getValue();

            Hence, i used an approach to wait till data loads by using addDataArrivedHandler. which works for the first time. but if i change the values, requests goes for infinite loop.

            Comment


              #7
              Incorrect, the Showcase example uses DataSources, it is already asynchronous and works with data loaded from a DB.

              Comment


                #8
                Yes. I agree. In the showcase example, nothing would be selected by default, where as in my case, say year(2012) is selected and by default months(say jan-march) should be loaded in the dependent select item. I tried with the your approach but it leads to Null pointer exception when dependent select item tries to load the data based on selected independent select item.

                Comment


                  #9
                  This approach is used all the time for a wide variety of use cases and doesn't lead to NullPointerExceptions when applied as shown. If you're still having trouble with this and you think you've found a framework issue, you should prepare a standalone, minimal test case showing how applying the approach shown in the sample can lead to a NullPointerExceptions.

                  Comment


                    #10
                    To add to my previous post, in the showcase, by default, all the values would be loaded(like all the categories and items, regardless of any filter) But in my case, the first one should be selected and the corresponding items should be populated. But when i am trying to get the value of category, as there wont be any data populated, this exception occurs. I will prepare a test sample for you and post it.

                    Thanks,
                    Yathish

                    Comment


                      #11
                      One again, the values are not loaded in advance in the Showcase sample. The selectItems are connected to a DataSource. They have no idea that the DataSource is working from a local cache - the DataSource is still asynchronous and they have no direct access to the DataSource's internal cache.

                      That's why this pattern works for remotely loaded data coming from a database or other source.

                      Comment

                      Working...
                      X