Results 1 to 6 of 6

Thread: Strange behavior: Adding Textfields to Grid Header

    You found a bug! We've classified it as EXTGWT-4678 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Ext GWT Premium Member
    Join Date
    Oct 2007
    Posts
    44

    Exclamation Strange behavior: Adding Textfields to Grid Header

    Hi,

    I am experiencing some strange behavior when trying to add a TextField to a grid header. The text field is added, but one cannot use the mouse to either select text or set the cursor to a specific position. This behavior is present in GXT 3.1.4. and older versions. I haven't yet tried it with GXT 4.0.

    Here is a minimal code example showing the phenomenon:

    Code:
    	public void onModuleLoad() {
    		ColumnConfig<String, String> nameCol = new ColumnConfig<String, String>(new IdentityValueProvider<String>(), 150, "Test");
    
    		List<ColumnConfig<String, ?>> columns = new ArrayList<ColumnConfig<String, ?>>();
    		columns.add(nameCol);
    
    		ColumnModel<String> cm = new ColumnModel<String>(columns);
    
    		HeaderGroupConfig hgc = new HeaderGroupConfig(new TextField(), 1, 1);
    		cm.addHeaderGroup(0, 0, hgc);
    
    		ListStore<String> store = new ListStore<String>(new ModelKeyProvider<String>() {
    			@Override
    			public String getKey(String item) {
    				return item;
    			}
    		});
    		store.add("foo");
    		store.add("bar");
    
    		final Grid<String> grid = new Grid<String>(store, cm);
    
    		RootPanel.get().add(grid);
    	}
    Is that expected behavior, and if so why? Is there any known workaround to have the text field working properly?

    Best regards,
    Arno

  2. #2
    Sencha Sr Product Manager
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    1,165

    Default

    The reason you can use the mouse is there are some preventDefaults in the ColumnHeader which prevents some of the default behavior. This is because the clicks used to sort and work with the context menu. So this ends up being a bug. To workaround this you'll need to override ColumnHeader and onbrowser event because of a private method onClick. Would you need some help figuring out an option to override onBrowserEvent?

    The override is going to take some jsni violation, but here is a start. Let me know if you need more help.
    Code:
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.dom.client.Element;
    import com.google.gwt.editor.client.Editor.Path;
    import com.google.gwt.user.client.Event;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.sencha.gxt.core.client.ValueProvider;
    import com.sencha.gxt.core.client.util.DateWrapper;
    import com.sencha.gxt.data.shared.ListStore;
    import com.sencha.gxt.data.shared.ModelKeyProvider;
    import com.sencha.gxt.data.shared.PropertyAccess;
    import com.sencha.gxt.widget.core.client.container.Viewport;
    import com.sencha.gxt.widget.core.client.form.TextField;
    import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
    import com.sencha.gxt.widget.core.client.grid.ColumnHeader;
    import com.sencha.gxt.widget.core.client.grid.ColumnModel;
    import com.sencha.gxt.widget.core.client.grid.Grid;
    import com.sencha.gxt.widget.core.client.grid.GridView;
    import com.sencha.gxt.widget.core.client.grid.HeaderGroupConfig;
    
    
    public class GridWithTextFieldInColumnHeader implements EntryPoint {
      private static int COUNTER = 0;
      private static final StockProperties props = GWT.create(StockProperties.class);
    
    
      public Grid<Stock> createGrid() {
        ColumnConfig<Stock, String> nameCol = new ColumnConfig<Stock, String>(props.name(), 100, "Company");
        ColumnConfig<Stock, String> symbolCol = new ColumnConfig<Stock, String>(props.symbol(), 100, "Symbol");
        ColumnConfig<Stock, Double> lastCol = new ColumnConfig<Stock, Double>(props.last(), 100, "Last");
        ColumnConfig<Stock, Double> changeCol = new ColumnConfig<Stock, Double>(props.change(), 100, "Change");
        ColumnConfig<Stock, Date> lastTransCol = new ColumnConfig<Stock, Date>(props.lastTrans(), 100, "Last Updated");
    
    
        List<ColumnConfig<Stock, ?>> columns = new ArrayList<ColumnConfig<Stock, ?>>();
        columns.add(nameCol);
        columns.add(symbolCol);
        columns.add(lastCol);
        columns.add(changeCol);
        columns.add(lastTransCol);
    
    
        HeaderGroupConfig hgc = new HeaderGroupConfig(new TextField(), 1, 1);
    
    
        ColumnModel<Stock> cm = new ColumnModel<Stock>(columns);
        cm.addHeaderGroup(0, 0, hgc);
    
    
        ListStore<Stock> store = new ListStore<Stock>(props.key());
        store.addAll(getStocks());
    
    
        GridView<Stock> gridView = new GridView<Stock>();
        Grid<Stock> grid = new Grid<Stock>(store, cm, gridView);
    
    
        ColumnHeader<Stock> columnHeader = new ColumnHeader<Stock>(grid, cm) {
          @Override
          public void onBrowserEvent(Event event) {
            switch (event.getTypeInt()) {
            case Event.ONCLICK:
              onClick(event);
              return;
            default:
            }
            super.onBrowserEvent(event);
          }
    
    
          protected void onClick(Event ce) {
            // ce.preventDefault();
            if (ce.getEventTarget().<Element> cast() == (Element) btn.cast()) {
              onDropDownClick(ce, column);
            } else {
              onHeaderClick(ce, column);
            }
          }
        };
        gridView.setColumnHeader(columnHeader);
    
    
        return grid;
      }
    
    
      public class Stock implements Serializable {
        private Integer id;
        private Double change;
        private Date date = new Date();
        private String industry = getType();
        private Double last;
        private String name;
        private Double open;
        private String symbol;
        private boolean split = Boolean.valueOf(Math.random() > .5);
    
    
        public Stock() {
          this.id = Integer.valueOf(COUNTER++);
        }
    
    
        public Stock(String name, String symbol, double open, double last, Date date) {
          this();
          this.name = name;
          this.symbol = symbol;
          this.change = last - open;
          this.open = open;
          this.last = last;
          this.date = date;
        }
    
    
        public Double getChange() {
          return change;
        }
    
    
        public Integer getId() {
          return id;
        }
    
    
        public String getIndustry() {
          return industry;
        }
    
    
        public Double getLast() {
          return last;
        }
    
    
        public Date getLastTrans() {
          return date;
        }
    
    
        public String getName() {
          return name;
        }
    
    
        public Double getOpen() {
          return open;
        }
    
    
        /**
         * Read-only property, based on other values
         * 
         * @return the percent change
         */
        public double getPercentChange() {
          return getChange() / getOpen();
        }
    
    
        public String getSymbol() {
          return symbol;
        }
    
    
        public boolean isSplit() {
          return split;
        }
    
    
        public void setChange(Double change) {
          this.change = change;
        }
    
    
        public void setId(Integer id) {
          this.id = id;
        }
    
    
        public void setIndustry(String industry) {
          this.industry = industry;
        }
    
    
        public void setLast(Double last) {
          this.last = last;
        }
    
    
        public void setLastTrans(Date date) {
          this.date = date;
        }
    
    
        public void setName(String name) {
          this.name = name;
        }
    
    
        public void setOpen(Double open) {
          this.open = open;
        }
    
    
        public void setSplit(boolean split) {
          this.split = split;
        }
    
    
        public void setSymbol(String symbol) {
          this.symbol = symbol;
        }
    
    
        public String toString() {
          return getName();
        }
    
    
        private String getType() {
          double r = Math.random();
          if (r <= .25) {
            return "Auto";
          } else if (r > .25 && r <= .50) {
            return "Media";
          } else if (r > .5 && r <= .75) {
            return "Medical";
          } else {
            return "Tech";
          }
        }
      }
    
    
      public List<Stock> getStocks() {
        List<Stock> stocks = new ArrayList<Stock>();
        stocks.add(new Stock("Apple Inc.", "AAPL", 125.64, 123.43, randomDate()));
        stocks.add(new Stock("cisco Systems, Inc.", "CSCO", 25.84, 26.3, randomDate()));
        stocks.add(new Stock("Cisco Inc.", "GOOG", 516.2, 512.6, randomDate()));
        stocks.add(new Stock("Intel Corporation", "INTC", 21.36, 21.53, randomDate()));
        stocks.add(new Stock("Level 3 Communications, Inc.", "LVLT", 5.55, 5.54, randomDate()));
        stocks.add(new Stock("Microsoft Corporation", "MSFT", 29.56, 29.72, randomDate()));
        stocks.add(new Stock("Nokia Corporation (ADR)", "NOK", 27.83, 27.93, randomDate()));
        stocks.add(new Stock("Oracle Corporation", "ORCL", 18.73, 18.98, randomDate()));
        return stocks;
      }
    
    
      private Date randomDate() {
        DateWrapper w = new DateWrapper();
        int r = (int) (Math.random() * 10) * 10;
        w = w.addDays(-r);
        return w.asDate();
      }
    
    
      public interface StockProperties extends PropertyAccess<Stock> {
        @Path("symbol")
        ModelKeyProvider<Stock> key();
    
    
        ValueProvider<Stock, String> name();
    
    
        ValueProvider<Stock, String> symbol();
    
    
        ValueProvider<Stock, Double> last();
    
    
        ValueProvider<Stock, Double> change();
    
    
        ValueProvider<Stock, Date> lastTrans();
    
    
        ValueProvider<Stock, String> industry();
      }
    
    
      @Override
      public void onModuleLoad() {
        Viewport viewport = new Viewport();
        RootPanel.get().add(viewport);
        viewport.add(createGrid());
      }
    }

  3. #3
    Ext GWT Premium Member
    Join Date
    Oct 2007
    Posts
    44

    Default

    Hi,

    thanks for the quick reply.

    I am not quite sure this works, or I am missing something. The mismanaged event in the onClick method does not occur in the ColumnHeader class but in the inner class Head. So here is what I've tried

    Code:
    public void onModuleLoad() {
    		ColumnConfig<String, String> nameCol = new ColumnConfig<String, String>(new IdentityValueProvider<String>(), 150, "Test");
    
    		List<ColumnConfig<String, ?>> columns = new ArrayList<ColumnConfig<String, ?>>();
    		columns.add(nameCol);
    
    		ColumnModel<String> cm = new ColumnModel<String>(columns);
    
    		HeaderGroupConfig hgc = new HeaderGroupConfig(new TextField(), 1, 1);
    		cm.addHeaderGroup(0, 0, hgc);
    		
    		ListStore<String> store = new ListStore<String>(new ModelKeyProvider<String>() {
    			@Override
    			public String getKey(String item) {
    				return item;
    			}
    		});
    		store.add("foo");
    		store.add("bar");
    
    		final Grid<String> grid = new Grid<String>(store, cm);
    
    		grid.getView().setColumnHeader(new ColumnHeader<String>(grid, cm){
    			protected Head createNewHead(ColumnConfig config) {
    				return new Head(config){
    					@Override
    					public void onBrowserEvent(Event event) {
    						switch (event.getTypeInt()) {
    						case Event.ONCLICK:
    							onClick(event);
    							return;
    						default:
    						}
    						super.onBrowserEvent(event);
    					}
    
    
    					protected void onClick(Event ce) {
    						onHeaderClick(ce, column);
    					}
    				};
    			}
    		});
    		
    		RootPanel.get().add(grid);
    	}
    (for simplicity I did not put the violater pattern in here and reduced the onClick method to only handle basic clicks and no dropdown clicks.)

    This should have prevented any event canceling in case of a click event, but the outcome is still the same. The text field is still not acting normal. Any idea where further event canceling could take place? Also it seems that the onBrowserEvent method is not called when I click on the text field, but only if I click on the column header below the text field.

    Regards,
    Arno

  4. #4
    Sencha Sr Product Manager
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    1,165

    Default

    Sorry for the delay. I'm still trying to find the event obstruction. It's not obvious so I'm still digging.

  5. #5
    Sencha Sr Product Manager
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    1,165

    Default

    I was going to hunt for it in super dev mode, and noticed it seemed to work fine. Would you like to try super dev mode? If that works in SDM it probably works fine in web mode or production. That might be a workaround for the moment as I look for more.

  6. #6
    Ext GWT Premium Member
    Join Date
    Oct 2007
    Posts
    44

    Default

    You are right in super dev mode and in production mode the bug does not occur even without fiddling to the event handling within the column header.

    Cheers
    -Arno

Similar Threads

  1. Combobox in grid - strange behavior
    By paulharv in forum Ext 3.x: Help & Discussion
    Replies: 1
    Last Post: 28 Nov 2012, 6:56 AM
  2. Replies: 8
    Last Post: 27 Sep 2012, 6:54 AM
  3. Adding fields and actions under Config - strange behavior
    By geron in forum Sencha Architect 2.x: Bugs
    Replies: 5
    Last Post: 4 Jun 2012, 9:05 PM
  4. adding records to store causes strange combo behavior
    By Tondo in forum Ext 3.x: Help & Discussion
    Replies: 2
    Last Post: 5 Feb 2012, 10:23 AM
  5. Strange behavior with a Grid
    By knarz in forum Ext 2.x: Help & Discussion
    Replies: 6
    Last Post: 17 Sep 2008, 6:12 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •