/* * Copyright 2013 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.overlord.rtgov.ui.client.local.widgets.common; import java.util.HashMap; import java.util.Map; import org.overlord.commons.gwt.client.local.widgets.TemplatedWidgetTable; import org.overlord.rtgov.ui.client.local.events.TableSortEvent; import org.overlord.rtgov.ui.client.local.events.TableSortEvent.Handler; import org.overlord.rtgov.ui.client.local.events.TableSortEvent.HasTableSortHandlers; import com.google.gwt.dom.client.NodeList; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; /** * Extends the templated widget table to add support for column sorting. * * @author eric.wittmann@redhat.com */ public abstract class SortableTemplatedWidgetTable extends TemplatedWidgetTable implements HasTableSortHandlers { private String currentSortColumnId; private Map<String, SortableTableHeader> columnIdMap = new HashMap<String, SortableTableHeader>(); /** * Constructor. */ public SortableTemplatedWidgetTable() { } /** * @see org.overlord.sramp.ui.client.local.widgets.common.TemplatedWidgetTable#doAttachInit() */ @Override protected void doAttachInit() { super.doAttachInit(); configureColumnSorting(); } /** * Subclasses have an opportunity here to configure which columns can be used to sort. */ protected void configureColumnSorting() { } /** * @see org.overlord.rtgov.ui.client.local.events.TableSortEvent.HasTableSortHandlers#addTableSortHandler(org.overlord.rtgov.ui.client.local.events.TableSortEvent.Handler) */ @Override public HandlerRegistration addTableSortHandler(Handler handler) { return addHandler(handler, TableSortEvent.getType()); } /** * Sets a column in the table to be sortable. This will convert the content in the * "th" to be something the user can click on. When the user clicks on it, the * internal state of the table will be altered *and* an event will be fired. * @param columnIndex * @param columnId */ public void setColumnSortable(int columnIndex, final String columnId) { Element thElement = null; NodeList<com.google.gwt.dom.client.Element> elementsByTagName = this.thead.getElementsByTagName("th"); //$NON-NLS-1$ if (columnIndex <= elementsByTagName.getLength()) { thElement = elementsByTagName.getItem(columnIndex).cast(); } if (thElement == null) { return; } String columnLabel = thElement.getInnerText(); thElement.setInnerText(""); //$NON-NLS-1$ SortableTableHeader widget = new SortableTableHeader(columnLabel, columnId); widget.removeFromParent(); DOM.appendChild(thElement, widget.getElement()); adopt(widget); widget.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { onColumnHeaderClick(columnId); } }); columnIdMap.put(columnId, widget); } /** * Sets the current sort-by column. Does not trigger an event. * @param columnId * @param ascending */ public void sortBy(String columnId, boolean ascending) { sortBy(columnId, ascending, false); } /** * Sets the current sort-by column. * @param columnId * @param ascending * @param fireEvent */ public void sortBy(String columnId, boolean ascending, boolean fireEvent) { SortableTableHeader newActiveHeader = columnIdMap.get(columnId); if (columnIdMap.containsKey(currentSortColumnId)) { SortableTableHeader oldActiveHeader = columnIdMap.get(currentSortColumnId); oldActiveHeader.setActive(false); oldActiveHeader.refreshHtml(); } newActiveHeader.setAscending(ascending); newActiveHeader.setActive(true); newActiveHeader.refreshHtml(); currentSortColumnId = columnId; if (fireEvent) TableSortEvent.fire(this, columnId, ascending); } /** * Called when the user clicks on one of the column headers. * @param columnId */ protected void onColumnHeaderClick(String columnId) { boolean isAscending = true; SortableTableHeader newActiveHeader = columnIdMap.get(columnId); if (newActiveHeader.isActive()) { isAscending = !newActiveHeader.isAscending(); } sortBy(columnId, isAscending, true); } /** * @return the current sort column */ public SortColumn getCurrentSortColumn() { SortableTableHeader currentSortHeader = this.columnIdMap.get(currentSortColumnId); if (currentSortHeader == null) { return getDefaultSortColumn(); } SortColumn rval = new SortColumn(); rval.columnId = currentSortHeader.getColumnId(); rval.ascending = currentSortHeader.isAscending(); return rval; } /** * @return the default sort column */ protected abstract SortColumn getDefaultSortColumn(); /** * @author eric.wittmann@redhat.com */ public static class SortColumn { public String columnId; public boolean ascending; } }