Gestione onClick per una casella di controllo in un'intestazione di CellTable
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;
}
}
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;
}
}