Announcement

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

    Custom Editor Type, parsed value not propagated to the form

    Hi,

    SmartClient Version: SC_SNAPSHOT-2011-03-07/EVAL Deployment

    I noticed today that the value of our (behind the scenes) calculation doesn't work anymore.
    After investigation, it seems that the FormItemValueParser isn't properly propagating the parsed value to the form!

    In our custom Integer editor, the user has the ability to input a simple arithmical function, for instance 12+3.
    When the user leaves the field, the arithmical expression is evaluated and calculated and the value should be displayed.
    This worked a couple of builds ago!

    Also, when tabbing out of the field, the parser is called twice?!?
    Which makes no sense to me. This you can also clearly see via the SC.logWarn("REAL VALUE IS: " + integer);


    I have added a standalone test case below.

    Code:
    public class Standalone implements EntryPoint {
    	
    	private static Canvas masterPanel = null;
    	
    	private Button devConsole;
    	
    	
    	/**
    	 * 
    	 * TODO: add description here, do not procrastinate!
    	 * 
    	 * @sofhistory
    	 * 9-mrt-2011	bade	initial version
    	 * 
    	 * @see com.google.gwt.core.client.EntryPoint#onModuleLoad()
    	 *
    	 */
    	 public void onModuleLoad() {
    		  		
    		//masterPanel should be a Layout
    		masterPanel = new Canvas(); 
    		masterPanel.setHeight100();
    		masterPanel.setWidth100();
    		masterPanel.setStyleName("pageBackground"); //background style from skin
    				
    		DataSource dataSource = new DataSource();   
    	  
    	    DataSourceField myIntegerField = new DataSourceField();   
    	    myIntegerField.setName("inputField");   
    	    myIntegerField.setTitle("inputField");   
    	    myIntegerField.setType(new MyIntegerItem());   
    	    myIntegerField.setEditorType(new MyIntegerEditor());
    	    
    	    dataSource.setFields(myIntegerField);
    
    	    DynamicForm form = new DynamicForm();   
    	    form.setHeight(170);   
    	    form.setWidth(500);	    
    	    form.setDataSource(dataSource);   
    	          
    		masterPanel.addChild(form);
    		masterPanel.draw();	
    	}
    }
    
    public class MyIntegerEditor extends TextItem {
    	
    	public MyIntegerEditor() {
    		super();		
    		this.setChangeOnKeypress(false);
    		
    		// link the formatter to the editor
    		this.setEditorValueFormatter(new MyIntegerValueFormatter());
    		this.setEditorValueParser(new MyIntegerValueParser());
    		
    		addFocusHandler(new FocusHandler() {		
    			public void onFocus(FocusEvent event) {
    				event.getItem().focusInItem();
    			}
    		});
    	}
    	
    	public class MyIntegerValueFormatter implements FormItemValueFormatter {
    
    		public String formatValue(Object value, Record record, DynamicForm form, FormItem item) {
    
    			if (value == null) {
    				return "";
    			}
    
    			return (String) value;
    		}
    	}
    
    	public class MyIntegerValueParser implements FormItemValueParser {
    
    		public Object parseValue(String value, DynamicForm form, FormItem item) {
    
    			if (value == null || value.length() < 1)
    				return item.getValue();
    					
    			Integer integer = null;
    
    			try {
    				integer = new Integer(value);
    			} catch (NumberFormatException ex) {
    				// maybe it's an arithmical function
    				try{
    					integer = new Integer(calculate(value));
    				}catch(Exception ignore){
    					//ignore => bad input, return NULL_INT
    				}				
    			}
    			SC.logWarn("REAL VALUE IS: " + integer);
    			return integer;
    		}
    
    	}
    	
        public native String calculate(String input) /*-{
    	var result;    	
    	result = eval(input);
    	return result == null || result == undefined ? "" : result.toString();
    }-*/;
    
    }

    #2
    Hi Bade,
    Firstly a quick workaround for this issue - call setRedrawOnChange(true); on your item and you should see the form item display the calculated value rather than keeping the "12+3" visible when the user tabs out of the field.

    We're looking at how best to address the underlying issues you raise here but it would be helpful to have a clarification here:
    You say that this used to work for you a few builds ago. Can you let us know which version was behaving as expected, and verify that the standalone example posted here used to work with that build. Also which browser / OS are you working with?

    Thanks
    Isomorphic Software

    Comment


      #3
      Hi,

      Operating System is Windows 7
      Browser FireFox 3.6.15 (but not at the time I saw it work => firefox was updated recently)

      Looking at svn and the date I checked in the initial development:
      27 jan 2011. Checked in library at the same moment was SmartGWT EE nightly build 25 jan 2011.

      Regards,
      Bart

      Comment


        #4
        Any news on this?

        Comment


          #5
          We're working on it.
          Did the redrawOnChange() workaround resolve it for you in the meantime?

          Comment


            #6
            Hi Bart,
            We've now made the following changes:

            - fixed the issue whereby the custom parser method would fire twice on blur

            - added support for remapping to the formatted display value on blur in the case where you have a custom parser and formatter pair which is not 1:1 [as in your case, where the parser will accept multiple strings for a single data value, and the formatter will redisplay it as a single value].
            This is actually a new feature. Previously you could get the effect via a redraw of the form when the value had changed (which would force formatters to run on every field). It seems likely that this is what was happening in your application against the Jan 25th build.

            In any case it should be working now. Please try the next nightly build from here (March 16 2011) and let us know if things aren't working for you

            Thanks and Regards
            Isomorphic Software

            Comment


              #7
              Hi Isomorphic,

              SmartClient Version: SC_SNAPSHOT-2011-03-16/EVAL Deployment

              Just tried the stand alone test case and it still gave the same result.
              Could you double check if your fix was in this build?

              Regards,
              Bart

              Comment


                #8
                The change is present in that build - and I just retested with the standalone test case and things seem to be working.
                I had to make 2 tweaks to get the standalone test case working:
                1) I commented out the call to myIntegerField.setType(new MyIntegerItem()); since you didn't include source for MyIntegerItem and it seems like it shouldn't make a difference
                2) I modified the cast from Object to string in the formatter to just call 'toString()' as the underlying value [an Integer] couldn't cast to a string.

                Here's my modified version of the code.
                The test I ran was to enter "12 + 2" in the text box and hit tab. I see a single "REAL VALUE IS: 14" in the logs, and the value displayed is updated to show "14".

                If you're still seeing problems you may need to give me exact steps to reproduce (or new code if it differs from what I'm testing against)

                Thanks

                Code:
                package com.smartgwt.sample.client.editParserBug;
                
                import com.google.gwt.core.client.EntryPoint;
                import com.smartgwt.client.data.DataSource;
                import com.smartgwt.client.data.DataSourceField;
                import com.smartgwt.client.data.Record;
                import com.smartgwt.client.util.SC;
                import com.smartgwt.client.widgets.Button;
                import com.smartgwt.client.widgets.Canvas;
                import com.smartgwt.client.widgets.form.DynamicForm;
                import com.smartgwt.client.widgets.form.FormItemValueFormatter;
                import com.smartgwt.client.widgets.form.FormItemValueParser;
                import com.smartgwt.client.widgets.form.fields.FormItem;
                import com.smartgwt.client.widgets.form.fields.TextItem;
                import com.smartgwt.client.widgets.form.fields.events.FocusEvent;
                import com.smartgwt.client.widgets.form.fields.events.FocusHandler;
                
                public class Standalone implements EntryPoint {
                    
                    private static Canvas masterPanel = null;
                    
                    private Button devConsole;
                    
                    
                    /**
                     * 
                     * TODO: add description here, do not procrastinate!
                     * 
                     * @sofhistory
                     * 9-mrt-2011   bade    initial version
                     * 
                     * @see com.google.gwt.core.client.EntryPoint#onModuleLoad()
                     *
                     */
                     public void onModuleLoad() {
                                
                        //masterPanel should be a Layout
                        masterPanel = new Canvas(); 
                        masterPanel.setHeight100();
                        masterPanel.setWidth100();
                        masterPanel.setStyleName("pageBackground"); //background style from skin
                                
                        DataSource dataSource = new DataSource();   
                      
                        DataSourceField myIntegerField = new DataSourceField();   
                        myIntegerField.setName("inputField");   
                        myIntegerField.setTitle("inputField");   
                //        myIntegerField.setType(new MyIntegerItem());   
                        myIntegerField.setEditorType(new MyIntegerEditor());
                        
                        dataSource.setFields(myIntegerField);
                
                        DynamicForm form = new DynamicForm();   
                        form.setHeight(170);   
                        form.setWidth(500);     
                        form.setDataSource(dataSource);   
                              
                        masterPanel.addChild(form);
                        masterPanel.draw(); 
                    }
                     
                
                     public class MyIntegerEditor extends TextItem {
                         
                         public MyIntegerEditor() {
                             super();        
                             this.setChangeOnKeypress(false);
                             
                             // link the formatter to the editor
                             this.setEditorValueFormatter(new MyIntegerValueFormatter());
                             this.setEditorValueParser(new MyIntegerValueParser());
                             
                             addFocusHandler(new FocusHandler() {        
                                 public void onFocus(FocusEvent event) {
                                     event.getItem().focusInItem();
                                 }
                             });
                         }
                         
                         public class MyIntegerValueFormatter implements FormItemValueFormatter {
                
                             public String formatValue(Object value, Record record, DynamicForm form, FormItem item) {
                
                                 if (value == null) {
                                     return "";
                                 }
                                 return value.toString();
                //                 return (String) value;
                             }
                         }
                
                         public class MyIntegerValueParser implements FormItemValueParser {
                
                             public Object parseValue(String value, DynamicForm form, FormItem item) {
                
                                 if (value == null || value.length() < 1)
                                     return item.getValue();
                                         
                                 Integer integer = null;
                
                                 try {
                                     integer = new Integer(value);
                                 } catch (NumberFormatException ex) {
                                     // maybe it's an arithmical function
                                     try{
                                         integer = new Integer(calculate(value));
                                     }catch(Exception ignore){
                                         //ignore => bad input, return NULL_INT
                                     }               
                                 }
                                 SC.logWarn("REAL VALUE IS: " + integer);
                                 return integer;
                             }
                
                         }
                         
                         public native String calculate(String input) /*-{
                         var result;     
                         result = eval(input);
                         return result == null || result == undefined ? "" : result.toString();
                     }-*/;
                
                     }
                
                }

                Comment


                  #9
                  Hi,

                  I took your code and ran it... didn't see it happening.
                  Did exactly as you did (that was my test as well).
                  I re-downloaded the build of the 16th... no change.

                  UPDATE: tried it with the build of the 17th and it's working!

                  Thanx,
                  Bart
                  Last edited by bade; 17 Mar 2011, 07:19.

                  Comment

                  Working...
                  X