简体   繁体   中英

GXT3 Grid cannot send event for checkbox when inline edit mode is used

I'm using GXT 3 Grid with InlineEdit mode following (more or less) the example code on their site. I don't think there is a way to get the check box cell to fire the 'EditComplete' event and if so, I'm not sure how I would, upon receiving it, disable the date cell on that same row. Just look for the comment: "// not firing for checkbox:" in the code below.

The following code works in an Eclipse web application project - you just need to use it in your 'onModuleLoad' method as demonstrated here:

public void onModuleLoad() {
  GridInlineEditingTest j = new GridInlineEditingTest();
}

Here's the code:

    import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.cell.client.DateCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor.Path;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.cell.core.client.form.CheckBoxCell;
import com.sencha.gxt.core.client.ValueProvider;
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.data.shared.Store;
import com.sencha.gxt.widget.core.client.FramedPanel;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.BoxLayoutContainer.BoxLayoutPack;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
import com.sencha.gxt.widget.core.client.container.Viewport;
import com.sencha.gxt.widget.core.client.event.CompleteEditEvent;
import com.sencha.gxt.widget.core.client.event.CompleteEditEvent.CompleteEditHandler;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
import com.sencha.gxt.widget.core.client.form.CheckBox;
import com.sencha.gxt.widget.core.client.form.DateField;
import com.sencha.gxt.widget.core.client.form.DateTimePropertyEditor;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
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.Grid.GridCell;
import com.sencha.gxt.widget.core.client.grid.GridView;
import com.sencha.gxt.widget.core.client.grid.editing.GridEditing;
import com.sencha.gxt.widget.core.client.grid.editing.GridInlineEditing;

public class GridInlineEditingTest {
  public GridInlineEditingTest() {
        VerticalLayoutContainer vlc = new VerticalLayoutContainer();
        vlc.add(createGrid(), new VerticalLayoutData(1, 1));

        Viewport vp = new Viewport();
        vp.add(vlc);
        RootPanel.get().add(vp);
      }

      interface PlaceProperties extends PropertyAccess<Plant> {
        ValueProvider<Plant, Date> available();

        @Path("id")
        ModelKeyProvider<Plant> key();
        ValueProvider<Plant, String> name();
        ValueProvider<Plant, Boolean> indoor();
      }

      private static final PlaceProperties properties = GWT.create(PlaceProperties.class);

      protected Grid<Plant> grid;
      private FramedPanel panel;
      private ListStore<Plant> store;
      private DateField dateField;

      public Widget createGrid() {
        if (panel == null) {
          ColumnConfig<Plant, String>   nameCol     = new ColumnConfig<Plant, String>(  properties.name(),      220,    "Name"  );
          ColumnConfig<Plant, Date>     dateCol     = new ColumnConfig<Plant, Date>(    properties.available(), 95,     "Date"  );
          ColumnConfig<Plant, Boolean>  indorCol    = new ColumnConfig<Plant, Boolean>( properties.indoor(),    55,     "Indoor");

          // display formatting
          DateCell dateCell = new DateCell(DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT));
          dateCol.setCell(dateCell);

          // display a checkbox in the gridview
          indorCol.setCell(new CheckBoxCell());


          List<ColumnConfig<Plant, ?>> l = new ArrayList<ColumnConfig<Plant, ?>>();
          l.add(nameCol);
          l.add(dateCol);
          l.add(indorCol);
          ColumnModel<Plant> columns = new ColumnModel<Plant>(l);

          store = new ListStore<Plant>(properties.key());
          store.setAutoCommit(false);
          store.addAll(getPlants());

          GridView<Plant> gridView = new GridView<Plant>();
          grid = new Grid<Plant>(store, columns, gridView);
          grid.getView().setAutoExpandColumn(nameCol);

          // EDITING//
          final GridEditing<Plant> editing = new GridInlineEditing<Plant>(grid); 
          dateField = new DateField(new DateTimePropertyEditor(DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT)));
          dateField.setClearValueOnParseError(false);
          editing.addEditor(dateCol, dateField);
          CheckBox checkField = new CheckBox();
          editing.addEditor(indorCol, checkField);

          editing.addCompleteEditHandler( new CompleteEditHandler<Plant>(){

              // not firing for checkbox:
              @Override
              public void onCompleteEdit(CompleteEditEvent<Plant> event) {
                  GridCell cell = event.getEditCell();

                  int row = cell.getRow();
                  int col = cell.getCol();
                  System.out.println("got here. row "+row+", col "+col);

              }
          });

          panel = new FramedPanel();
          panel.setHeadingText("Editable Grid Example");
          panel.setPixelSize(600, 400);
          panel.addStyleName("margin-10");

          VerticalLayoutContainer con = new VerticalLayoutContainer();
          con.setBorders(true);
          con.add(grid, new VerticalLayoutData(1, 1));

          panel.setWidget(con);
          panel.setButtonAlign(BoxLayoutPack.CENTER);
          panel.addButton(new TextButton("Reset", new SelectHandler() {
            @Override
            public void onSelect(SelectEvent event) {
              store.rejectChanges();
            }
          }));

          panel.addButton(new TextButton("Save", new SelectHandler() {
            @Override
            public void onSelect(SelectEvent event) {
              store.commitChanges();
            }
          }));
        }
        return panel;
      }

      private static int AUTO_ID = 0;

      public class Plant {
        private DateTimeFormat df = DateTimeFormat.getFormat("MM/dd/y");
        private int id;
        private String name;
        private String light;
        private double price;
        private Date available;
        private boolean indoor;
        private String color;
        private int difficulty;
        private double progress;

        public Plant() {
          id = AUTO_ID++;
          difficulty = (int) (Math.random() * 100);
          progress = Math.random();
        }

        public Plant(String name, String light, double price, String available, boolean indoor) {
          this();
          setName(name);
          setLight(light);
          setPrice(price);
          setAvailable(df.parse(available));
          setIndoor(indoor);
        }

        public int getId() {                            return id;                      }
        public double getProgress() {                   return progress;                }
        public String getColor() {                      return color;                   }
        public int getDifficulty() {                    return difficulty;              }
        public Date getAvailable() {                    return available;               }
        public String getLight() {                      return light;                   }
        public String getName() {                       return name;                    }
        public double getPrice() {                      return price;                   }
        public boolean isIndoor() {                     return indoor;                  }

        public void setId(int id) {                     this.id = id;                   }
        public void setProgress(double progress) {      this.progress = progress;       }
        public void setAvailable(Date available) {      this.available = available;     }
        public void setDifficulty(int difficulty) {     this.difficulty = difficulty;   }
        public void setColor(String color) {            this.color = color;             }
        public void setIndoor(boolean indoor) {         this.indoor = indoor;           }
        public void setLight(String light) {            this.light = light;             }
        public void setName(String name) {              this.name = name;               }
        public void setPrice(double price) {            this.price = price;             }

        @Override
        public String toString() {
          return name != null ? name : super.toString();
        }
      }

      public List<Plant> getPlants() {
        List<Plant> plants = new ArrayList<Plant>();
        plants.add(new Plant("Bloodroot", "Mostly Shady", 2.44, "03/15/2006", true));
        plants.add(new Plant("Columbine", "Shade", 9.37, "03/15/2006", true));
        plants.add(new Plant("Marsh Marigold", "Mostly Sunny", 6.81, "05/17/2006", false));
        plants.add(new Plant("Cowslip", "Mostly Shady", 9.90, "03/06/2006", true));
        plants.add(new Plant("Dutchman's-Breeches", "Mostly Shady", 6.44, "01/20/2006", true));
        plants.add(new Plant("Ginger, Wild", "Mostly Shady", 9.03, "04/18/2006", true));
        return plants;
      }

}

thanks. and have a great day!!

You are setting a checkbox cell in the column, and then also attaching a field as an inline editor for the column. So if the user clicks the checkbox (cell), you are expecting that click to be ignored, but instead a checkbox (field) to show up over it, which the user may then click?

Instead what is happening is that the checkbox (cell) is reporting that it is using that click event to do something useful - it is changing its value. As a result, the grid editing mechanism ignores the click, so the checkbox (field) never goes into edit mode, and so of course it doesn't complete edit mode.

What are you trying to achieve by making it the purpose of two different checkboxes to be drawn in the same place, and function differently? If you are trying to use the CheckBoxCell instance as a way to always draw the checkbox symbol in the grid cell, there are two main choices:

  • Skip the CheckBox field in the inline editing, and just let the cell take care of it. It will not fire the editing events, but it will still directly interact with the store. You can listen to the cell's events if you need to, or just to the record change events from the store, or you can subclass the cell to modify behavior.
  • Removing the event handing guts of the CheckBoxCell to prevent it from handling the event - this may be as simple as overriding onBrowserEvent to do nothing, though I suspect that you actually will want to prevent its check changing behavior entirely so that the Inline Editing version takes care of it

Finally, remember that the purpose of inline editing is to keep the grid from being a mass of fields, and to make it only draw those fields when the user actually interacts with it. This means that the user must first click a field to get something like a checkbox to show up, then interface with the field to change it. Looking one more time at the CheckBox field in an inline editable grid (though this time with a custom cell) at http://www.sencha.com/examples/#ExamplePlace:inlineeditablegrid you'll see that this means two clicks to change a value and get the CompleteEditing event (as well as the various other field change events) that you are after - is this really what you have in mind?

As per the Source Code of CheckBoxCell#isEditing() that says:

A checkbox is never in "edit mode". There is no intermediate state between checked and unchecked.

Find the alternate solution here How to get the row index of selected checkbox on grid GXT .

Please have a look at GXT checkbox in grid

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM