Announcement

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

    transformValue for textField cursor position issue

    In the sample below, start typing 1234. Transform value should add a comma after "1". Now place the cursor right after the comma and press backspace. You'll notice the cursor jump to the end of the value.

    Code:
    isc.DynamicForm.create({
        width: 300,
        fields: [
            {title:"Item", type:"text", 
    		transformInput:function(form, item, value, oldValue){
    			 if(value.length > 3){
    					var lss = value.split("");
    
    					 var counter = 0;
    					 var newValue = "";
    					 //add commas to the left side
    					 for(var i=lss.length-1;i>-1;i--){
    						if(counter==3){
    							newValue ="," + newValue;
    							counter = 0;
    						}
    						counter++;
    						newValue = lss[i]+newValue; 
    					 }
    					   return newValue;
    				  }
    				return value;
    			}
    		} 
        ]
    });

    #2
    The expected behavior here is unclear - the "transformInput" is performing an arbitrary change to the value so it's not clear what should happen to the caret.

    When the user hits the delete key, the native value of the item becomes "1234" (the comma is deleted).
    The transform method then performs an arbitrary transformation - converting this to 1,234

    The transformInput method is custom of course, so at this point the value has changed in a way the system can't heuristically predict, so there's no "right" behavior. An option would be to maintain the current insertion position in terms of character count (the second character) but it's not clear that that's any better than putting focus at the end.

    [EDIT] Just as a note you could write your own change handler to modify the value and change the caret position via a call to setSelectionRange()
    Last edited by Isomorphic; 15 Dec 2011, 20:00.

    Comment


      #3
      I wouldn't say it's arbitrary - we are pretty much transforming the string so that it is more readable but instead of doing it on blur, we are performing this change as the user types.

      We'll take a look at your suggestion and get back to you. Thanks

      Comment


        #4
        By arbitrary I mean you could be doing anything - it's your custom function so the framework has no way of knowing what the transformation is. We recognize some things, like just shifting case but if the underlying string is changed like this, the framework can't really guess what changed / how to react to it.

        Comment


          #5
          I tried overriding change handler and updateValue methods:

          handleChange: function (newValue, oldValue){
          var selection = this.getSelectionRange();
          this.Super("handleChange", [newValue, oldValue]);
          this.setSelectionRange(selection[0], selection[1]);
          },

          updateValue: function(){
          var selection = this.getSelectionRange();
          this.Super("updateValue", null);
          this.setSelectionRange(selection[0], selection[1]);
          }


          Caret position still jumps to the end of the string.
          Debugging on FormItem.setSelectionRange(being, end) doesn't provide with much info - selection seems to be set to the proper range all the time.

          Is there is another method that sets caret position without invoking setSelectionRange()?

          An observation - if I place debug point on setSelectionRange() the selection seems to work fine. As soon as I remove debug points, selection again jumps to the end of the entry.

          Comment


            #6
            Try using just the 'change' handler and explicitly calling setValue followed by setSelectionRange rather than using both 'change' and 'transformTo'.
            Here's an example (which obviously doesn't have the logic required to do anything very meaningful but demonstrates the concept).

            Code:
            isc.DynamicForm.create({
                width: 300,
                fields: [
                    {title:"Item", type:"text",
                     change : function (form, item, newValue, oldValue) {
                         if (!isc.isA.String(newValue) || newValue.length < 3) return;
                         // Obviously not a realistic transform, but just to demonstrate 'setSelectionRange' plus value change:
                         var currentRange = this.getSelectionRange();
                         var modifiedValue = newValue.substring(0,3) + ", " + newValue.substring(3);
                         this.setValue(modifiedValue);
                         this.setSelectionRange(currentRange[0],currentRange[1]);
            
                     }
                    } 
                ]
            });

            Comment

            Working...
            X