Announcement

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

    redraw cancels out focusInItem()

    Hi,

    When a user clicks in a field, we want the icon to become visible and the value in the field to be selected.

    What I'm seeing is that the redraw() followed by the focusInItem isn't working. Hence, the value in the field is not selected. I tried with selectValue as well, same issue.

    Could you please advice?

    FYI my custom editor is extending a TextItem.

    Code:
    		FormItemIcon icon = new FormItemIcon();
    		icon.setSrc(SilkImageConstants.ICON_SKIN_CONTROLS_DATE);
    		setIcons(icon);
    		setShowIcons(false);
    
    		// If user clicks in this field
    		 addFocusHandler(new FocusHandler() {		
    			 public void onFocus(FocusEvent event) {	
    				 event.getItem().setShowIcons(true);
    				 event.getItem().redraw();
    				 event.getItem().focusInItem();	
    			}
    		 });
    SmartClient Version: SC_SNAPSHOT-2010-12-14/EVAL Deployment

    #2
    Please let us know if this is happening with the 2.4 release, and indicate what browser(s) it occurs in. Also, since the most likely cause is other code in your application that attempts to move focus and may be triggered by redraw, please verify that you can reproduce this problem in a standalone test case.

    Comment


      #3
      Same behaviour on IE (8.0) and FireFox (3.6.13).
      Tested with SmartGWT/2.x/EnterpriseEval/2011-01-18.

      Standalone test case below:
      Code:
      package testcase.client;
      
      import com.google.gwt.core.client.EntryPoint;
      import com.smartgwt.client.widgets.Canvas;
      import com.smartgwt.client.widgets.form.DynamicForm;
      import com.smartgwt.client.widgets.form.fields.FormItemIcon;
      import com.smartgwt.client.widgets.form.fields.TextItem;
      import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
      import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
      import com.smartgwt.client.widgets.form.fields.events.FocusEvent;
      import com.smartgwt.client.widgets.form.fields.events.FocusHandler;
      
      /**
       * Entry point classes define <code>onModuleLoad()</code>.
       */
      public class Standalone implements EntryPoint {
      	
                   private static Canvas masterPanel = null;
      	
      	/**
      	 * This is the entry point method.
      	 */
      	public void onModuleLoad() {
      		
      		masterPanel = new Canvas(); 
      		masterPanel.setHeight100();
      		masterPanel.setWidth100();
      		masterPanel.setStyleName("pageBackground"); //background style from skin
      	
      		final DynamicForm dialogForm = new DynamicForm();
      		
      		TextItem theTextItem = new TextItem("FocusInItem");
      		theTextItem.setIconPrompt("Change value");
      		theTextItem.setShowHint(true);
      		FormItemIcon icon = new FormItemIcon();
      		icon.setSrc("[SKIN]/actions/edit.png");
      		theTextItem.setIcons(icon);
      		theTextItem.setShowIcons(false);
      		theTextItem.setValue("text that must be selected on focus");
      		
      		theTextItem.addFocusHandler(new FocusHandler() {
      			
      			public void onFocus(FocusEvent event) {
      				event.getItem().setShowIcons(true);
      				event.getItem().redraw();				
      				event.getItem().focusInItem();
      			}
      		});
      		
      		theTextItem.addBlurHandler(new BlurHandler() {
      			
      			public void onBlur(BlurEvent event) {
      				event.getItem().setShowIcons(false);
      				event.getItem().redraw();	
      			}
      		});
      		
      		dialogForm.setItems(theTextItem);
      		masterPanel.addChild(dialogForm);
      		masterPanel.draw();		
      	}
      }

      Comment


        #4
        During a redraw(), focus moves away from the item (since the old HTML is removed from the DOM). It's your blur handler, which is firing in this circumstance, which is the problem. Instead, you can check whether the item is still logically considered the focus item (form.getFocusItem()), and hide the icons if it is.

        Comment


          #5
          Using code below, the selectValue variant is working and doing what I want on IE, however, it's not doing the same on FireFox!

          Moreover, using the same code and switching to focusInItem is not working on IE and FireFox.

          See standalone test case below.

          Code:
          package testcase.client;
          
          import com.google.gwt.core.client.EntryPoint;
          import com.smartgwt.client.widgets.Canvas;
          import com.smartgwt.client.widgets.form.DynamicForm;
          import com.smartgwt.client.widgets.form.fields.FormItemIcon;
          import com.smartgwt.client.widgets.form.fields.TextItem;
          import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
          import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
          import com.smartgwt.client.widgets.form.fields.events.FocusEvent;
          import com.smartgwt.client.widgets.form.fields.events.FocusHandler;
          
          /**
           * Entry point classes define <code>onModuleLoad()</code>.
           */
          public class Standalone implements EntryPoint {
          	
          	private static Canvas masterPanel = null;
          	
          	/*
          	 * Setting the picker to show causes an onBlur event. So we would be stuck in a loop.
          	 */
          	boolean ignoreFocusInBlurEvent = false;
          	/*
          	 * The onFocus might actually trigger alot of events for the full duration of having focus.
          	 *  So omit unnecessarry redraws()s.
          	 */
          	boolean isPickerShowing = false;
          	
          	/**
          	 * Calling the redraw in the onFocus event (when receiving focus for the first time) 
          	 * triggers a onBlur event, so keep the state 
          	 */
          	boolean setFocusInItem = true;
          	
          	/**
          	 * This is the entry point method.
          	 * 
          	 */
          	public void onModuleLoad() {
          		
          		//masterPanel should be a Layout
          		// this way, it will re-layout its members if the browser gets resized
          		masterPanel = new Canvas(); 
          		masterPanel.setHeight100();
          		masterPanel.setWidth100();
          		masterPanel.setStyleName("pageBackground"); //background style from skin
          	
          		final DynamicForm dialogForm = new DynamicForm();
          		
          		TextItem theTextItem = new TextItem("FocusInItem");
          		theTextItem.setIconPrompt("Change value");
          		theTextItem.setShowHint(true);
          		FormItemIcon icon = new FormItemIcon();
          		icon.setSrc("[SKIN]/actions/edit.png");
          		theTextItem.setIcons(icon);
          		theTextItem.setShowIcons(false);
          		theTextItem.setValue("text that must be selected on focus");
          			
          		TextItem theTextItem2 = new TextItem("Item2");
          		
          		theTextItem.addFocusHandler(new FocusHandler() {
          			
          			public void onFocus(FocusEvent event) {		
          				if(setFocusInItem){
          					(new TextItem(event.getForm().getFocusItem().getJsObj())).selectValue();
          //					event.getForm().getFocusItem().focusInItem();
          //					event.getItem().focusInItem();
          					//(new TextItem(event.getItem().getJsObj())).selectValue();
          					//do this, so that second time around, we don't select the value again
          					setFocusInItem = false;
          				}
          				 if (isPickerShowing) return;
          				 //first time, picker will not be shown yet=> we know we received focus for the first time, so also select the value
          				 setFocusInItem = true;
          				 ignoreFocusInBlurEvent = true;//tell onBlur event that it is the focus that is triggering
          				 event.getItem().setShowIcons(true);
          				 event.getItem().redraw();
          				 isPickerShowing = true;	
          				 ignoreFocusInBlurEvent = false;//after redraw, make sure the onBlur hides the picker
          			}
          		});
          		
          		theTextItem.addBlurHandler(new BlurHandler() {
          			
          			public void onBlur(BlurEvent event) {
          				 if (!isPickerShowing) return;
          				 if (ignoreFocusInBlurEvent) return;
          				 event.getItem().setShowIcons(false);
          				 event.getItem().redraw();
          				 isPickerShowing = false;
          			}
          		});
          		
          		dialogForm.setItems(theTextItem, theTextItem2);
          		masterPanel.addChild(dialogForm);
          		masterPanel.draw();		
          	}
          }

          Comment


            #6
            Sorry, but timing and number of focus/blur events is one area where we can't realistically provide uniformity between browsers. If you're seeing differences here, you'll need to compensate for them.

            Comment


              #7
              I seem to have read this somewhere:

              Originally posted by Quick Start Guide
              Smart GWT‘s powerful, component-oriented APIs give Smart GWT the flexibility to use whatever approach works best in each browser, so you don‘t have to worry about it.

              This allows Smart GWT to make a simple guarantee: if there is a cross-browser issue, it's our problem, not yours.

              Comment


                #8
                Yes, this is true for 99.9% of the functionality (the other exception is IE's treatment of dangling commas as a syntax error) but there is no meaningful way to create consistent cross-browser focus/blur events, because what the browsers do is fundamentally different (synchronously vs asynchronously moving focus).

                It's true that these should probably be marked as such (certain APIs, known to expose you to platform inconsistencies, are supplied by with this caveat). This is partly why we created editorExit/editorEnter as more consistent APIs in this area (for grids, and eventually for forms as well).

                Bigger picture, separately from figuring out when to hide or show the icons, hide and showing icons on the fly currently required a whole-form redraw, which is fine for a singular search field or similar, but which will lead to a poor user experience in large forms (brief pauses on field entry). So if you need this behavior in large forms, you should probably consider sponsoring it (the alternative being writing out your own icons - quite a bit more involved and exposes you to other cross-platform issues).

                Comment


                  #9
                  Thanks for the thorough explanation.

                  Bart

                  Comment

                  Working...
                  X