Handling onClick für ein Kontrollkästchen in einem CellTable-Header
Frage
Ich versuche, eine CellTable zu erstellen, die eine Spalte mit Text und ein Kontrollkästchen enthält, das als Kontrollkästchen "Alle auswählen" verwendet wird (siehe Zeichnung unten, Kontrollkästchen "cb" ist).Derzeit verwende ich eine vom Header abgeleitete Klasse und überschreibe die Rendermethode, um den Text und ein Kontrollkästchen auszugeben.Ich überschreibe onBrowserEvent (), aber es gibt mir nur onChange-Ereignisse, die gut funktionieren würden, außer dass das Kontrollkästchen nicht richtig funktioniert.Hat jemand irgendwelche Ideen dazu?
+-------+------------+
| col 1 | Select All |
| | cb |
+-------+------------+
| row 1 | cb |
+-------+------------+
Das Problem mit dem Kontrollkästchen besteht darin, dass Sie, wenn es nicht aktiviert ist, zweimal darauf klicken müssen, damit das Häkchen angezeigt wird (zumindest in Chrome), obwohl die Eigenschaft "aktiviert" beim ersten Mal wahr ist.Ein Klick deaktiviert es richtig.
Hier ist ein Code:
Richten Sie die CellTable-Spalten ein:
/** 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);
}
/** 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);
}
My Select All Header:
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;
}
}
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;
}
}
Lösung
Es sieht so aus, als würden Sie beim Rendern des Headers ein nicht aktiviertes Kontrollkästchen rendern, wodurch der Auswahlstatus möglicherweise gelöscht wird, wenn das Celltable erneut gerendert wird.
Versuchen Sie, den aktivierten Status zu speichern und das Kontrollkästchen mit dem Status zu rendern. Es sieht so aus, als wären Sie mit allSelected
auf halbem Weg, Sie verwenden ihn einfach nicht.
BEARBEITEN Hier ist eine funktionierende Implementierung, die ich gerade für Zanata geschrieben habe (siehe SearchResultsView.java ). Die HasValue-Schnittstelle ist so implementiert, dass Wertänderungsereignisse auf standardmäßige Weise behandelt werden können. Ich habe die Rendermethode nicht überschrieben. Wenn Sie dies tun möchten, stellen Sie sicher, dass Sie getValue()
verwenden, um zu bestimmen, ob Sie ein aktiviertes oder ein deaktiviertes Kontrollkästchen rendern. Die Auswahl- / Abwahllogik wird in der zugehörigen Präsentationsklasse behandelt (siehe 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;
}
}