Announcement

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

    ComboBoxItem :: getPickListFilterCriteria() method

    Hi,

    I have some code that used to work with 8.2p and is now broken with 8.3p.

    I have a form with 2 combo-boxes. The first combo-box is used to filter out the second. I therefore
    rely on the getPickListFilterCriteria() pattern to do so, from my 2nd combo-box.

    My problem is that when the getPickListFilterCriteria() method executes in my second combo-box,
    this.form.getValue("combo_1") always returns undefined.

    I inspected this.form.values from within getPickListFilterCriteria() and there are absolutely no values
    in there, whatsoever ...

    I've included our logic. Do you see anything that could have worked with 8.2p that wouldn't anymore with 8.3p?

    Thanks,

    Code:
    //----------------
    getComboOneFieldDefinition : function(properties)
    {
     var baseProperties =
     {
        name : 'level',
        title : MeiStrings.get('account.accountLevel'),
        hint : MeiStrings.get('account.hint.accountLevel'),
        showHintInField : true,
        width : 150,
        defaultToFirstOption : true,
        optionDataSource : 'dsAccountLevelPickerOptions',
        editorType : 'SelectItem',
        displayField : 'name',
        sortField : 'presentationOrder',
        valueField : 'primaryKey',
        addUnknownValues : false,
        validateOnExit : false,
        pickListFields : [{ name : 'name', width : '100%' }],
      };
    
     return isc.addProperties(baseProperties, properties);
    },
    
    //----------------
    getComboTwoFieldDefinition : function(properties)
    {
     var baseProperties =
     {
      name : 'account',
      title : MeiStrings.get('account.search.field.title'),
      width : 300,
      editorType : 'ComboBoxItem',
      displayField : 'name',
      valueField : 'primaryKey',
      addUnknownValues : false,
      optionDataSource : 'dsAccountMemberPickerOptions',
      sortField : 'name',
      hint : MeiStrings.get('account.search.field.hint'),
      showHintInField : true,
      textMatchStyle : 'substring',
      pickListWidth : 450,
      pickListHeight : 245,
      synchronizedFromLevelFieldName : null,
      pickListFields :
      [
        { name : 'code', width : '25%', title : MeiStrings.get('account.code') },
        { name : 'name', width : '75%', title : MeiStrings.get('account.name') }
      ],
      init : function()
      {
        // following code is actually invoked using DelayCall but I removed to keep things a little simpler
        if (this.synchronizedFromLevelFieldName)
        {
          var levelPicker = this.form.getField(this.synchronizedFromLevelFieldName);
          if (levelPicker)
          {
            this.observe(levelPicker, 'dataArrived', 'observer.levelPickerChanged(observed)');
            this.observe(levelPicker, 'changed', 'observer.levelPickerChanged(observed)');
          }
        }
    
        return this.Super('init', arguments);
      },
      levelPickerChanged: function(levelPicker)
      {
        this.resetField();
        this.setHint(MeiStrings.get('account.search.field.hintWithLevel', levelPicker.getSelectedRecord().name));
      },
      getPickListFilterCriteria : function()
      {
        var criteria = this.Super('getPickListFilterCriteria', arguments);
    
        if (!criteria)
          criteria = {};
    
        if (this.synchronizedFromLevelFieldName)
          criteria['dimensionLevel'] = this.form.getValue(this.synchronizedFromLevelFieldName);
    
        return criteria;
      }
     }
    
     return isc.addProperties(baseProperties, properties);
    },
    
    //
    // Actual Form
    //
    
    form = DynamicForm.create
    ({
        autoFocus : true,
        saveOnEnter : true,
        wrapItemTitles : false,
        titleOrientation : 'top',
        titleSuffix : '',
        requiredTitleSuffix : '',
        numCols : 4,
        cellPadding : 5,
        vAlign: 'top',
        valuesManager: this.valuesManager,
        fields :
        [
          this.getComboOneFieldDefinition({ name : 'combo_1',
             width: 100, tabIndex : 1, 
             shouldSaveValue: false, required: false }),
    
          this.getComboTwoFieldDefinition({ name: 'combo_2',
             width: 100, tabIndex : 2, 
             synchronizedFromLevelFieldName : 'combo_1', 
             shouldSaveValue: false, required: false }),
    
          ...
        ]
        ...
    });

    #2
    There's been no (intended) behavior change in this area.

    1. is this cross-browser consistent?

    2. If you look at the value of "this", is it the ComboBoxItem as you expect?

    3. If you look at the value of "this.form", is it the form, as you expect?

    4. if you look at the form values via some external mechanism (eg a button that just logs form.getValues()), do you see the expected values? If not, do you have any trouble calling setValue() / setValues() and seeing the values appear as expected?

    5. do you have any code that calls form.getValues() then *manipulates* the returned object (this would have been invalid last version too).

    Comment


      #3
      Hi,

      Yes, this is consistent across browsers. 'this' and 'this.form' are as expected. From within
      the getPickListFilterCriteria() method, when I observe different things, this is what I get:

      this.form.getFields() -> [_2, _2, ... ]
      this.form.getFields()[0].name -> "combo_0"
      this.form.getFields()[1].name -> "combo_1"
      this.form.getValues() -> Object {}
      this.form.valuesManager.getValues() -> Object {}
      this.form.getFields()[0].getValue() -> 1094

      So the field's value is set, but somehow this is not communicated back to the underlying form
      nor the underlying valuesManager.

      To answer your other question, when I evaluate this.form.getValues() outside the getPickListFilterCriteria()
      method, those fields are not filled either.

      Obviously, I could fix this by replacing with the following ...
      Code:
      this.form.getField(this.synchronizedFromLevelFieldName).getValue()
      ... but I'd be leaving something behind that may explode in my face later. I can't figure it out though ...

      This code AS-IS used to work in 8.2p but is now broken with 8.3p.

      Thanks for your help,
      Last edited by yavery; 8 Aug 2013, 12:54.

      Comment


        #4
        Actually, I just found out that if I call this.form.validate() then my this.form.getValues()
        will return my data as expected ...

        Has that changed between 8.2p and 8.3p ? Seems odd, no ?

        Thanks for any feedback,

        Comment


          #5
          You have addUnknownValues:false and an optionDataSource - what could be going on here is an issue with verifying whether the value is "new".

          When the user tabs out of the field after typing something, you should see the ComboBoxItem attempt to contact the server to figure out if the value is new or not (you can see this in the RPC tab). If your response is not correct, it would explain why the ComboBoxItem doesn't know what to do with the value and doesn't save it to the form.

          Comment


            #6
            My first combo is a SelectItem, not a ComboBoxItem so selections are limited to "valid" selections
            provided by the OptionsDataSource ...

            I tried your use case and there's no XHR going out following the entry of a selection in combo_1 ...

            Any other ideas ?

            Comment


              #7
              If you look at my code, I do have "validateOnExit" set to FALSE on my combo_1 SelectItem though ...

              That has always been like that and it worked before in 8.2p. As I said, if I explicitly call form.validate(),
              this call returns true and from that point on, my form.getValues() is indeed populated as expected.

              Does any of this help figure out what's going on ?

              Comment


                #8
                Ooogh a SelectItem named "combo_1", yeah that tripped us up.

                We'll check out whether validateOnExit:false would cause the value to not be saved.

                Comment


                  #9
                  The problem actually appears to be that you've explicitly got "shouldSaveValue" set to false on these items.
                  This is basically telling the form not to absorb the items' values into its values object. If you get rid of that flag, your example works, without the validate call.

                  Is there a reason you have this setting?

                  Comment


                    #10
                    We have the shouldSaveValue set to false because we don't want to have those values as
                    part of the POST XHR request, but we still need them in the form as we use the values in
                    the client-side processing logic.

                    Again, this is how things were in 8.2p and now in 8.3p this seems to have changed ...

                    For the time being, I replaced my code to use the following pattern instead:
                    Code:
                    this.form.getField(this.synchronizedFromLevelFieldName).getValue()
                    Please advise if you believe there's something else that's wrong with the overall approach.

                    Thanks,

                    Comment


                      #11
                      If shouldSaveValue is false, we would expect the value not to be present in the form's values object. This was not an intentional recent change - it's possible that 8.2 had a bug where the values were getting absorbed when the shouldn't be.
                      The sendExtraFields parameter can be used to handle the case where you want to trim fields not defined in the DataSource out of an edited Record (values object) before submitted to the server, so this may be an approach that works for you, or you can stick with having 'shouldSaveValue' be false, and have client-side code just look at the result of a "getValue()" call directly on the live item. Either approach should be fine.

                      Regards
                      Isomorphic Software

                      Comment


                        #12
                        Ok.

                        Thanks!

                        Comment

                        Working...
                        X