Announcement

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

    Unwanted changeEvent on empty JSArray formatted to empty string

    Hi,

    For a formItem, the data delivered by fetch as a JSArray. For an empty value, the fetch delivers as JSArray of size 0.
    Problem: whenever the user just tabs in and out of this field, a ChangedEvent is fired, which I'm not expecting:


    - The formItem has a setInputTransformer
    After tab out, it kicks in.
    It detects the new value == null. Since we don't want to change our underlying value, this returns again oldValue (which is the empty JSArray).



    - The formItem has a setEditorValueFormatter.
    This detects the empty JSArray size 0 value, and formats it into an empty string so the user sees nothing.


    Am I still changing the internal value somewhere which makes the SmartClient framework triggers a ChangedEvent?
    If I inspect the ChangeEvent, the oldValue and newValue are the same (value-wise, I don't know if JavaScript also has some kind of equals method to check if this is the same 'instance' as well?).



    thanks,
    dev mode, firefox 3.5.7, SC_SNAPSHOT-2011-04-22

    #2
    Sorry, this is too abstract -

    1. what kind of FormItem are we talking about

    2. what is the user input

    3. what led you to use an inputTransformer (which is typically for things like text capitalization) vs a ValueParser (which is more for converting from a text value to some kind of logical value that isn't text)

    Comment


      #3
      Aahh, I think indeed that I should use the setEditorValueParser in this case iso the InputTransformer. Will try, thanks.

      The FormItem is just an extension of TextItem.

      The user input is nothing: the field is shown empty (as done my parser) while the underlying JS value is an empty array (multiple=true). The user tabs in, then tabs out (changes nothing), and in that case I still did get a ChangedEvent.

      Comment


        #4
        Hello,

        on a ComboBoxItem, it seems the setEditorValueParser is never called when the user chooses a value from ValueMap - using e.g. arrow up & down, then hit Enter. At that time, the inputTransformer is called and then the ValueFormatter.

        Shouldn't the ValueParser be called as well somewhere?

        Comment


          #5
          No, ValueParser is for user-entered values only, not values chosen from the dataset.

          Comment


            #6
            Hmm, that's too bad:

            In this sample, if the user types a value in the combobox before choosing the dropdown, the value in the form is the one returned from the EditorValueParser ("CORRECT KEY")
            When he chooses one from the the dropdown, I loose that technical value.

            I could store the new value to send to the server in the "serverValue" field of each record.
            - This requires me to create the correct value beforehand: Even if the user never choses that object, I've done that work for nothing.
            - Then using setValueField pass the "serverValue" field

            But I can't: the technical value to send to the server is actually composed of the current value and the the user's new value (typed, or pre existing). So that's something I should do in an EditorValueParser, right?



            Code: goal is to always send "CORRECT KEY ..." to the backend.
            Code:
            private void test12() {
            	final DynamicForm form = new DynamicForm();
            	
            	DataSourceTextField pkDS = new DataSourceTextField("id");
            	pkDS.setHidden(true);
            	pkDS.setPrimaryKey(true);
            	DataSourceTextField e = new DataSourceTextField("description");
            	DataSourceField f = new DataSourceField("serverValue", FieldType.ANY);
            	
            	ListGridRecord r1 = new ListGridRecord();
            	r1.setAttribute("id", 1);
            	r1.setAttribute("description", "first one");
            	r1.setAttribute("serverValue", "TECHNICALKEY1");
            	ListGridRecord r2 = new ListGridRecord();
            	r2.setAttribute("id", 2);
            	r2.setAttribute("description", "first one");
            	r2.setAttribute("serverValue", "TECHNICALKEY2");
            	ListGridRecord [] records = new ListGridRecord[]{r1,r2};
            	
            	DataSource datasource = new DataSource();
            	datasource.setFields(pkDS, e, f);
            	datasource.setCacheData(records);
            	datasource.setClientOnly(true);  
            	
            	ComboBoxItem comboBoxItem = new ComboBoxItem("itemName", "Custom");
            	comboBoxItem.setEditorValueParser(new FormItemValueParser() {
            		
            		public Object parseValue(String value, DynamicForm form, FormItem item) {
            			//problem, the valueParser is never hit after the user has chosen a value
            			return "CORRECT KEY " + someAlgorithm(oldValue, newValue);
            			}
            		});
            		comboBoxItem.setOptionDataSource(datasource);
                    comboBoxItem.setWidth(260);  
              
                    ListGrid pickListProperties = new ListGrid();  
                    pickListProperties.setCellHeight(50);  
                    pickListProperties.setCanHover(true);  
                    pickListProperties.setShowHover(true);
                    pickListProperties.setCellFormatter(new CellFormatter() {  
                        
                        public String format(Object value, ListGridRecord record, int rowNum, int colNum) {  
                            String descStr = record.getAttribute("description");  
                        if (descStr == null) descStr = "[no description]";  
              
                            String serverValue = record.getAttribute("serverValue");  
              
                            String styleStr = "font-family:arial;font-size:11px;white-space:nowrap;overflow:hidden;";  
                        String retStr = "<table>" +  
                                "<tr><td ><span style='" + styleStr + "width:70px;float:left'>" + descStr + "<span></td>" +  
                                "<td align='right'><span style='" + styleStr + "width:150px;float:right;font-weight:bold'>" + serverValue + "<span></td></tr>" +  
                                "</table>";  
                            return retStr;  
              
                        }  
                    });
                    comboBoxItem.setPickListProperties(pickListProperties);
                    form.setFields(comboBoxItem);
            		
            		Button addData = new Button("Are you CORRECT KEY?");
            	addData.addClickHandler(new ClickHandler() {
            		
            		public void onClick(ClickEvent event) {
            			SC.say("Key is: " + form.getValue("itemName"));
            		}
            	});
            	
            	VLayout layout = new VLayout();
            	layout.setWidth100();
            	layout.setHeight(500);
            	layout.setMembers(form, addData);
            	masterPanel.addChild(layout);
            }

            Comment


              #7
              As far as the ComboBox is concerned, the valueField should be set to the field containing the value to be sent to the server. If you want to manipulate that value in some way before it gets to the server, don't try to do it via APIs intended for user input (ValueParser et al), do it immediately before saving the form, in transformRequest, or on the server.

              Comment

              Working...
              X