Manejo de onClick para una casilla de verificación en un encabezado CellTable

StackOverflow https://stackoverflow.com/questions/8828271

  •  27-10-2019
  •  | 
  •  

Pregunta

Estoy intentando crear una CellTable que tenga una columna con algo de texto y una casilla de verificación, que se utilizará como una casilla de verificación para seleccionar todo (vea el dibujo a continuación, "cb" es la casilla de verificación).Actualmente estoy usando una clase derivada de Header y anulando su método de renderizado para generar el texto y una casilla de verificación.Estoy anulando onBrowserEvent (), sin embargo, solo me está dando eventos onChange, que funcionarían bien, excepto que la casilla de verificación no funciona correctamente.¿Alguien tiene alguna idea sobre esto?

+-------+------------+
| col 1 | Select All |
|       |     cb     | 
+-------+------------+
| row 1 |     cb     |
+-------+------------+

El problema que tengo con la casilla de verificación es que cuando no está marcada, debes hacer clic en ella dos veces para que aparezca la marca de verificación (al menos en Chrome), aunque la propiedad "marcada" sea verdadera la primera vez.Un clic lo desmarca correctamente.

Aquí hay un código:

Configure las columnas CellTable:

/** Setup the table's columns. */
private void setupTableColumns() {
    // Add the first column:
    TextColumn<MyObject> column1 = new TextColumn<MyObject>() {
        @Override
        public String getValue(final MyObject object) {
            return object.getColumn1Text();
        }
    };
    table.addColumn(macColumn, SafeHtmlUtils.fromSafeConstant("Column1"));

    // the checkbox column for selecting the lease
    Column<MyObject, Boolean> checkColumn = new Column<MyObject, Boolean>(
            new CheckboxCell(true, false)) {
        @Override
        public Boolean getValue(final MyObject object) {
            return selectionModel.isSelected(object);
        }
    };

    SelectAllHeader selectAll = new SelectAllHeader();
    selectAll.setSelectAllHandler(new SelectHandler());
    table.addColumn(checkColumn, selectAll);
}

Mi encabezado Seleccionar todo:

public static class SelectAllHeader extends Header<Boolean> {
    private final String checkboxID = "selectAllCheckbox";
    private ISelectAllHandler handler = null;

    @Override
    public void render(final Context context, final SafeHtmlBuilder sb) {
        String html = "<div>Select All<div><input type=\"checkbox\" id=\"" + checkboxID + "\"/>";

        sb.appendHtmlConstant(html);
    }

    private final Boolean allSelected;

    public SelectAllHeader() {
        super(new CheckboxCell());

        allSelected = false;
    }

    @Override
    public Boolean getValue() {
        Element checkboxElem = DOM.getElementById(checkboxID);

        return checkboxElem.getPropertyBoolean("checked");

    }

    @Override
    public void onBrowserEvent(final Context context, final Element element, final NativeEvent event) {
        Event evt = Event.as(event);
        int eventType = evt.getTypeInt();

        super.onBrowserEvent(context, element, event);

        switch (eventType) {
            case Event.ONCHANGE:
                handler.onSelectAllClicked(getValue());
                event.preventDefault();
                break;

            default:
                break;
        }

    }


    public void setSelectAllHandler(final ISelectAllHandler handler) {
        this.handler = handler;
    }

}
¿Fue útil?

Solución

Parece que está renderizando una casilla de verificación no marcada cada vez que renderiza el encabezado, lo que podría estar borrando el estado de selección cada vez que la tabla de celdas se vuelve a renderizar.

Intente almacenar el estado marcado y renderizar la casilla de verificación con el estado. Parece que estás a mitad de camino con allSelected, simplemente no lo estás usando.

EDIT Aquí hay una implementación funcional que acabo de escribir para Zanata (ver SearchResultsView.java ). La interfaz HasValue está implementada para que los eventos de cambio de valor se puedan manejar de manera estándar. No he anulado el método de renderizado, si quieres hacerlo, asegúrate de usar getValue() para determinar si renderizas una casilla de verificación marcada o no. La lógica de selección / deselección se maneja en la clase de presentador asociada (ver SearchResultsPresenter.java ).

private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {

   private boolean checked;
   private HandlerManager handlerManager;

   public CheckboxHeader()
   {
      //TODO consider custom cell with text
      super(new CheckboxCell());
      checked = false;
   }

   // This method is invoked to pass the value to the CheckboxCell's render method
   @Override
   public Boolean getValue()
   {
      return checked;
   }

   @Override
   public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent)
   {
      int eventType = Event.as(nativeEvent).getTypeInt();
      if (eventType == Event.ONCHANGE)
      {
         nativeEvent.preventDefault();
         //use value setter to easily fire change event to handlers
         setValue(!checked, true);
      }
   }

   @Override
   public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler)
   {
      return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
   }

   @Override
   public void fireEvent(GwtEvent<?> event)
   {
      ensureHandlerManager().fireEvent(event);
   }

   @Override
   public void setValue(Boolean value)
   {
      checked = value;
   }

   @Override
   public void setValue(Boolean value, boolean fireEvents)
   {
      checked = value;
      if (fireEvents)
      {
         ValueChangeEvent.fire(this, value);
      }
   }

   private HandlerManager ensureHandlerManager()
   {
      if (handlerManager == null)
      {
         handlerManager = new HandlerManager(this);
      }
      return handlerManager;
   }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top