GWT Celtable: two clicks required to change the state of a checkbox in FireFox

In my project, I have a CellTable with a CheckBoxCell column. It is a regular column to represent (change) values ​​and is not used for row selection (I use SingleSelectionModel for selection). Everything works fine in Chrome, the first time I clicked it gets the checkbox state and the row is selected. In FireFox, when I try to click on a checkbox in a CheckBoxCell column, GWT selects the row and after the second click on the checkbox changes the state of the checkbox. But I need the same behavior as in Chrome (check the checkbox first).

This is how I create the column:

private <C> Column<T, C> addColumn(CellTable<T> itemListTable, Cell<C> cell, String headerText, int columnWidthPct, final IValueGetter<C, T> getter, @Nullable FieldUpdater<T, C> fieldUpdater) {
    Column<T, C> column = new Column<T, C>(cell) {
        @Override
        public C getValue(T object) {
            return getter.getValue(object);
        }
    };
    column.setFieldUpdater(fieldUpdater);
    column.setSortable(false);
    itemListTable.addColumn(column, headerText);
    itemListTable.setColumnWidth(column, columnWidthPct, PCT);
    return column;
}

private void generateExistingSettingsTable() {
    addColumn(existingSettingsTable, new ParameterizedCheckboxCell<T>(), IS_PUBLIC_HEADER, 10, new IValueGetter<Boolean, T>() {
                @Override
                public Boolean getValue(T setting) {
                    return setting.isPublic();
                }
            },
            new FieldUpdater<T, Boolean>() {
                @Override
                public void update(int index, T object, Boolean value) {
                    object.setPublic(value);
                    updatePublicState(object);
                }
            }
    );
}

      

My ParameterizedCheckboxCell extends CheckboxCell and only overrides the render method (to enable / disable the checkbox).

I've already tried everything suggested here here :

  • stopPropagation doesn't work for me
  • Add column to blacklist DefaultSelectionEventManager, this is not an option (very large area left unlocked around the checkbox)
+3


source to share


1 answer


As I found out today, the same thing happens with Chrome (version 45.0.2454.101). I research this more and find out the following. GWT CheckboxCell

only consumes two browser events by default: keydown

and change

. In the old version of Chrome, when you clicked on the checkbox change

, the event fires and everything works fine. In FireFox and newer Chrome, there is no event after click change

(I can't figure out why explanations are welcome ), so I decided to create my own checkbox class that extends AbstractEditableCell<Boolean, Boolean>

and replace the consumed one change

with an click

event. This is what I got:

import java.util.Objects;

import com.google.gwt.cell.client.AbstractEditableCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

import static com.google.gwt.dom.client.BrowserEvents.CLICK;
import static com.google.gwt.dom.client.BrowserEvents.KEYDOWN;

public class ParameterizedCheckboxCell extends AbstractEditableCell<Boolean, Boolean> {

    public ParameterizedCheckboxCell() {
        super(KEYDOWN, CLICK);
    }

    @Override
    public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
        // Here i have some specific logic so i skip this part
        // You can just copy/paste body of this method from original CheckboxCell
    }

    @Override
    public void onBrowserEvent(Context context, Element parent, Boolean value, NativeEvent event, ValueUpdater<Boolean> valueUpdater) {
        final String type = event.getType();
        final boolean enterPressed = KEYDOWN.equals(type) && event.getKeyCode() == KeyCodes.KEY_ENTER;
        if (CLICK.equals(type) || enterPressed) {
            InputElement input = parent.getFirstChild().cast();
            Boolean isChecked = input.isChecked();

            if (enterPressed) {
                isChecked = !isChecked;
                input.setChecked(isChecked);
            }

            if (Objects.equals(value, isChecked)) {
                clearViewData(context.getKey());
            } else {
                setViewData(context.getKey(), isChecked);
            }
            valueUpdater.update(isChecked);
        }
    }

    @Override
    public boolean isEditing(Context context, Element parent, Boolean value) {
        return false;
    }

}

      



I missed dependsOnSelection

and handlesSelection

because I am not using this for a select column.

0


source







All Articles