Gestione onClick per una casella di controllo in un'intestazione di CellTable

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

  •  27-10-2019
  •  | 
  •  

Domanda

Sto cercando di creare un CellTable che abbia una colonna con del testo e una casella di controllo, che verrà utilizzata come casella di selezione di tutto (vedere il disegno sotto, "cb" è la casella di controllo).Attualmente sto usando una classe derivata da Header e sovrascrivendo il suo metodo di rendering per produrre il testo e una casella di controllo.Sto sovrascrivendo onBrowserEvent (), tuttavia mi dà solo eventi onChange, che funzionerebbero bene tranne per il fatto che la casella di controllo non funziona correttamente.Qualcuno ha qualche idea su questo?

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

Il problema che ho con la casella di controllo è che quando non è selezionata, devi fare clic due volte per far apparire il segno di spunta (almeno su Chrome), anche se la proprietà "selezionata" è vera la prima volta.Un clic lo deseleziona correttamente.

Ecco del codice:

Imposta le colonne di 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);
}

Intestazione Seleziona tutto personale:

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;
    }

}
È stato utile?

Soluzione

Sembra che tu visualizzi una casella di controllo non selezionata ogni volta che esegui il rendering dell'intestazione, il che potrebbe cancellare lo stato di selezione ogni volta che viene eseguito nuovamente il rendering della tabella delle celle.

Prova a memorizzare lo stato selezionato e a visualizzare la casella di controllo con lo stato. Sembra che tu sia a metà strada con allSelected, semplicemente non lo stai usando.

MODIFICA Ecco un'implementazione funzionante che ho appena scritto per Zanata (vedi SearchResultsView.java ). L'interfaccia HasValue è implementata in modo che gli eventi di modifica del valore possano essere gestiti in modo standard. Non ho sovrascritto il metodo di rendering, se vuoi farlo assicurati di usare getValue() per determinare se renderizzare una casella di controllo selezionata o deselezionata. La logica di selezione / deselezione è gestita nella classe relatore associata (vedere 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;
   }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top