org.dominokit.domino.ui.datatable.plugins.HeaderBarPlugin Maven / Gradle / Ivy
/*
* Copyright © 2019 Dominokit
*
* 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.dominokit.domino.ui.datatable.plugins;
import static java.util.Objects.nonNull;
import static org.jboss.elemento.Elements.*;
import elemental2.dom.*;
import java.util.ArrayList;
import java.util.List;
import jsinterop.base.Js;
import org.dominokit.domino.ui.datatable.DataTable;
import org.dominokit.domino.ui.datatable.DataTableStyles;
import org.dominokit.domino.ui.datatable.DefaultColumnShowHideListener;
import org.dominokit.domino.ui.datatable.events.SearchClearedEvent;
import org.dominokit.domino.ui.datatable.events.TableEvent;
import org.dominokit.domino.ui.datatable.model.Category;
import org.dominokit.domino.ui.datatable.model.Filter;
import org.dominokit.domino.ui.datatable.model.SearchContext;
import org.dominokit.domino.ui.dropdown.DropDownMenu;
import org.dominokit.domino.ui.dropdown.DropDownPosition;
import org.dominokit.domino.ui.dropdown.DropdownAction;
import org.dominokit.domino.ui.forms.TextBox;
import org.dominokit.domino.ui.grid.Column;
import org.dominokit.domino.ui.grid.Row;
import org.dominokit.domino.ui.grid.flex.FlexItem;
import org.dominokit.domino.ui.grid.flex.FlexJustifyContent;
import org.dominokit.domino.ui.grid.flex.FlexLayout;
import org.dominokit.domino.ui.icons.Icon;
import org.dominokit.domino.ui.icons.Icons;
import org.dominokit.domino.ui.icons.MdiIcon;
import org.dominokit.domino.ui.style.Style;
import org.dominokit.domino.ui.style.Styles;
import org.dominokit.domino.ui.style.Unit;
import org.dominokit.domino.ui.utils.DominoElement;
import org.dominokit.domino.ui.utils.ElementUtil;
import org.dominokit.domino.ui.utils.TextNode;
import org.gwtproject.timer.client.Timer;
import org.jboss.elemento.EventType;
/**
* This plugin attach an action bar to the table and adds {@link HeaderActionElement}(s) to it
*
* @param the type of the data table records
*/
public class HeaderBarPlugin implements DataTablePlugin {
private Column titleColumn = Column.span6();
private Column actionsBarColumn = Column.span6();
private HTMLHeadingElement title = Style.of(h(2)).setMarginBottom("0px").element();
private FlexLayout actionsBar = FlexLayout.create().setJustifyContent(FlexJustifyContent.END);
private HTMLDivElement element =
DominoElement.of(div())
.add(
Row.create()
.appendChild(titleColumn.appendChild(title))
.appendChild(actionsBarColumn.appendChild(actionsBar))
.element())
.css(DataTableStyles.HEADER)
.style("padding-bottom: 5px;")
.element();
private final List> actionElements = new ArrayList<>();
/**
* creates an instance with a custom title
*
* @param title String title of the header bar
*/
public HeaderBarPlugin(String title) {
this(title, "");
}
/**
* creates an instance with a custom and description
*
* @param title String title of the header bar
* @param description String description of the header bar
*/
public HeaderBarPlugin(String title, String description) {
this.title.appendChild(DomGlobal.document.createTextNode(title));
if (nonNull(description) && !description.isEmpty()) {
this.title.appendChild(small().textContent(description).element());
}
Style.of(titleColumn).setMarginBottom("0px");
Style.of(actionsBarColumn).setMarginBottom("0px");
}
/** {@inheritDoc} */
@Override
public void onBeforeAddTable(DataTable dataTable) {
actionElements.forEach(
actionElement ->
actionsBar.appendChild(
FlexItem.create()
.addCss(Styles.m_r_5)
.addCss(Styles.m_l_5)
.appendChild(actionElement.asElement(dataTable))
.element()));
dataTable.element().appendChild(element);
}
/**
* Adds a new header action to this header bar
*
* @param headerActionElement the {@link HeaderActionElement}
* @return same plugin instance
*/
public HeaderBarPlugin addActionElement(HeaderActionElement headerActionElement) {
actionElements.add(headerActionElement);
return this;
}
/**
* a Predefined {@link HeaderActionElement} that condense/expand the data table rows
*
* @param the type of the data table records
*/
public static class CondenseTableAction implements HeaderActionElement {
private String condenseToolTip = "Condense";
private String expandToolTip = "Expand";
/** {@inheritDoc} */
@Override
public Node asElement(DataTable dataTable) {
Icon condenseIcon =
Icons.ALL
.line_weight()
.clickable()
.setTooltip(condenseToolTip)
.setToggleIcon(Icons.ALL.format_line_spacing())
.toggleOnClick(true)
.apply(
icon ->
icon.addClickListener(
evt -> {
if (dataTable.isCondensed()) {
dataTable.show();
icon.setTooltip(condenseToolTip);
} else {
dataTable.condense();
icon.setTooltip(expandToolTip);
}
}));
return a().add(condenseIcon).element();
}
/**
* Changes the condense icon tooltip
*
* @param condenseToolTip String
* @return same acton instance
*/
public CondenseTableAction setCondenseToolTip(String condenseToolTip) {
this.condenseToolTip = condenseToolTip;
return this;
}
/**
* Changes the expand icon tooltip
*
* @param expandToolTip String
* @return same acton instance
*/
public CondenseTableAction setExpandToolTip(String expandToolTip) {
this.expandToolTip = expandToolTip;
return this;
}
}
/**
* A predefined action to toggle stripes on data table rows
*
* @param the type of the data table records
*/
public static class StripesTableAction implements HeaderActionElement {
private String noStripsToolTip = "No stripes";
private String stripsToolTip = "Stripes";
/** {@inheritDoc} */
@Override
public Node asElement(DataTable dataTable) {
Icon stripesIcon =
Icons.ALL
.format_line_spacing()
.clickable()
.setToggleIcon(Icons.ALL.power_input())
.setTooltip(noStripsToolTip)
.toggleOnClick(true)
.apply(
icon ->
icon.addClickListener(
evt -> {
if (dataTable.isStriped()) {
dataTable.noStripes();
icon.setTooltip(stripsToolTip);
} else {
dataTable.striped();
icon.setTooltip(noStripsToolTip);
}
}));
return a().add(stripesIcon).element();
}
/**
* Changes the no strips icon tooltip
*
* @param noStripsToolTip String
* @return same acton instance
*/
public StripesTableAction setNoStripsToolTip(String noStripsToolTip) {
this.noStripsToolTip = noStripsToolTip;
return this;
}
/**
* Changes the strips icon tooltip
*
* @param stripsToolTip String
* @return same acton instance
*/
public StripesTableAction setStripsToolTip(String stripsToolTip) {
this.stripsToolTip = stripsToolTip;
return this;
}
}
/**
* A predefined action to toggle borders on data table rows
*
* @param the type of the data table records
*/
public static class BordersTableAction implements HeaderActionElement {
private String borderedToolTip = "Bordered";
private String noBprdersToolTip = "No borders";
/** {@inheritDoc} */
@Override
public Node asElement(DataTable dataTable) {
Icon bordersIcon =
Icons.ALL
.border_vertical()
.clickable()
.setToggleIcon(Icons.ALL.border_clear())
.toggleOnClick(true)
.setTooltip(borderedToolTip)
.apply(
icon ->
icon.addClickListener(
evt -> {
if (dataTable.isBordered()) {
dataTable.noBorder();
icon.setTooltip(borderedToolTip);
} else {
dataTable.bordered();
icon.setTooltip(noBprdersToolTip);
}
}));
return a().add(bordersIcon).element();
}
/**
* Changes the borders icon tooltip
*
* @param borderedToolTip String
* @return same acton instance
*/
public BordersTableAction setBorderedToolTip(String borderedToolTip) {
this.borderedToolTip = borderedToolTip;
return this;
}
/**
* Changes the no borders icon tooltip
*
* @param noBordersToolTip String
* @return same acton instance
*/
public BordersTableAction setNoBordersToolTip(String noBordersToolTip) {
this.noBprdersToolTip = noBordersToolTip;
return this;
}
}
/**
* A predefined action to toggle hover on data table rows
*
* @param the type of the data table records
*/
public static class HoverTableAction implements HeaderActionElement {
private String hoverToolTip = "Hover";
private String noHoverToolTip = "No Hover";
/** {@inheritDoc} */
@Override
public Node asElement(DataTable dataTable) {
Icon hoverIcon =
Icons.ALL
.blur_off()
.clickable()
.setToggleIcon(Icons.ALL.blur_on())
.toggleOnClick(true)
.setTooltip(noHoverToolTip)
.apply(
icon ->
icon.addClickListener(
evt -> {
if (dataTable.isHoverable()) {
dataTable.noHover();
icon.setTooltip(hoverToolTip);
} else {
dataTable.hovered();
icon.setTooltip(noHoverToolTip);
}
}));
return a().add(hoverIcon).element();
}
/**
* Changes the hover icon tooltip
*
* @param hoverToolTip String
* @return same acton instance
*/
public HoverTableAction setHoverToolTip(String hoverToolTip) {
this.hoverToolTip = hoverToolTip;
return this;
}
/**
* Changes the no hover icon tooltip
*
* @param noHoverToolTip String
* @return same acton instance
*/
public HoverTableAction setNoHoverToolTip(String noHoverToolTip) {
this.noHoverToolTip = noHoverToolTip;
return this;
}
}
/**
* A predefined action to clear data table search
*
* @param the type of the data table records
*/
public static class ClearSearch implements HeaderActionElement {
private String clearFiltersToolTip = "Clear filters";
/** {@inheritDoc} */
@Override
public Node asElement(DataTable dataTable) {
MdiIcon clearFiltersIcon =
Icons.MDI_ICONS
.filter_remove_mdi()
.setTooltip(clearFiltersToolTip)
.size18()
.clickable()
.addClickListener(evt -> dataTable.getSearchContext().clear().fireSearchEvent());
return a().add(clearFiltersIcon).element();
}
/**
* Changes the clear filters icon tooltip
*
* @param clearFiltersToolTip String
* @return same acton instance
*/
public ClearSearch setClearFiltersToolTip(String clearFiltersToolTip) {
this.clearFiltersToolTip = clearFiltersToolTip;
return this;
}
}
/**
* A predefined action to add a search box the data table
*
* @param the type of the data table records
*/
public static class SearchTableAction implements HeaderActionElement {
private String searchToolTip = "Search";
private String clearSearchToolTip = "Clear search";
private int autoSearchDelay = 200;
private HTMLDivElement element = DominoElement.of(div()).css("search-new").element();
private DataTable dataTable;
private final TextBox textBox;
private boolean autoSearch = true;
private Timer autoSearchTimer;
private EventListener autoSearchEventListener;
private final Icon searchIcon;
private final Icon clearIcon;
/** creates a new instance */
public SearchTableAction() {
searchIcon =
Icons.ALL
.search()
.addClickListener(
evt -> {
autoSearchTimer.cancel();
doSearch();
})
.setTooltip(searchToolTip)
.style()
.setCursor("pointer")
.get();
clearIcon =
Icons.ALL.clear().setTooltip(clearSearchToolTip).style().setCursor("pointer").get();
textBox =
TextBox.create()
.setPlaceholder(searchToolTip)
.addLeftAddOn(searchIcon)
.addRightAddOn(clearIcon)
.addCss("table-search-box")
.setMarginBottom("0px")
.setMaxWidth("300px")
.addCss(Styles.pull_right);
clearIcon.addClickListener(
evt -> {
textBox.clear();
autoSearchTimer.cancel();
doSearch();
});
element.appendChild(textBox.element());
autoSearchTimer =
new Timer() {
@Override
public void run() {
doSearch();
}
};
autoSearchEventListener =
evt -> {
autoSearchTimer.cancel();
autoSearchTimer.schedule(autoSearchDelay);
};
setAutoSearch(true);
}
/** @return boolean, true if the auto search is enabled */
public boolean isAutoSearch() {
return autoSearch;
}
/**
* Enable/Disable auto search when enabled the search will triggered while the user is typing
* with a delay otherwise the search will only be triggered when the user click on search or
* press Enter
*
* @param autoSearch boolean
* @return same action instance
*/
public SearchTableAction setAutoSearch(boolean autoSearch) {
this.autoSearch = autoSearch;
if (autoSearch) {
textBox.addEventListener("input", autoSearchEventListener);
} else {
textBox.removeEventListener("input", autoSearchEventListener);
autoSearchTimer.cancel();
}
textBox.addEventListener(
EventType.keypress.getName(),
evt -> {
if (ElementUtil.isEnterKey(Js.uncheckedCast(evt))) {
doSearch();
}
});
return this;
}
/** @return int search delay in milliseconds */
public int getAutoSearchDelay() {
return autoSearchDelay;
}
/** @param autoSearchDelayInMillies int auto search delay in milliseconds */
public void setAutoSearchDelay(int autoSearchDelayInMillies) {
this.autoSearchDelay = autoSearchDelayInMillies;
}
private void doSearch() {
SearchContext searchContext = dataTable.getSearchContext();
Category search = Category.SEARCH;
searchContext.removeByCategory(search);
searchContext.add(Filter.create("*", textBox.getValue(), Category.SEARCH)).fireSearchEvent();
}
/** {@inheritDoc} */
@Override
public void handleEvent(TableEvent event) {
if (SearchClearedEvent.SEARCH_EVENT_CLEARED.equals(event.getType())) {
textBox.pauseChangeHandlers();
textBox.clear();
textBox.resumeChangeHandlers();
}
}
/** {@inheritDoc} */
@Override
public Node asElement(DataTable dataTable) {
this.dataTable = dataTable;
dataTable.addTableEventListener(SearchClearedEvent.SEARCH_EVENT_CLEARED, this);
return element;
}
/**
* Set the search icon tooltip
*
* @param searchToolTip String
* @return same action instance
*/
public SearchTableAction setSearchToolTip(String searchToolTip) {
this.searchToolTip = searchToolTip;
searchIcon.setTooltip(searchToolTip);
textBox.setPlaceholder(searchToolTip);
return this;
}
/**
* Set the clear search icon tooltip
*
* @param clearSearchToolTip String
* @return same action instance
*/
public SearchTableAction setClearSearchToolTip(String clearSearchToolTip) {
this.clearSearchToolTip = clearSearchToolTip;
clearIcon.setTooltip(clearSearchToolTip);
return this;
}
}
/**
* A predefined action to add a drop down to the data table that allow selecting which columns be
* shown/hidden
*
* @param the type of the data table records
*/
public static class ShowHideColumnsAction implements HeaderActionElement {
/** {@inheritDoc} */
@Override
public Node asElement(DataTable dataTable) {
Icon columnsIcon = Icons.ALL.view_column().clickable();
DropDownMenu dropDownMenu = DropDownMenu.create(columnsIcon);
dropDownMenu
.setPosition(DropDownPosition.BOTTOM_LEFT)
.apply(
columnsMenu ->
dataTable
.getTableConfig()
.getColumns()
.forEach(
columnConfig -> {
Icon checkIcon = Icons.ALL.check();
columnConfig.addShowHideListener(
DefaultColumnShowHideListener.of(checkIcon.element(), true));
FlexLayout itemElement =
FlexLayout.create()
.appendChild(
FlexItem.create()
.styler(style -> style.setWidth(Unit.px.of(24)))
.appendChild(checkIcon))
.appendChild(
FlexItem.create()
.appendChild(TextNode.of(columnConfig.getTitle())));
columnsMenu.addAction(
DropdownAction.create(columnConfig.getName(), itemElement.element())
.setAutoClose(false)
.addSelectionHandler(
value ->
columnConfig.toggleDisplay(columnConfig.isHidden())));
}));
columnsIcon.addClickListener(
evt -> {
dropDownMenu.open();
evt.stopPropagation();
});
return columnsIcon.element();
}
/** {@inheritDoc} */
@Override
public void handleEvent(TableEvent event) {}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy