Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
tools.dynamia.zk.crud.ui.EntityPickerBox Maven / Gradle / Ivy
/*
* Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1
* Colombia / South America
*
* 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 tools.dynamia.zk.crud.ui;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zk.ui.event.SelectEvent;
import org.zkoss.zul.A;
import org.zkoss.zul.AbstractListModel;
import org.zkoss.zul.Bandbox;
import org.zkoss.zul.Bandpopup;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Span;
import tools.dynamia.commons.BeanUtils;
import tools.dynamia.commons.Messages;
import tools.dynamia.commons.StringUtils;
import tools.dynamia.commons.logger.LoggingService;
import tools.dynamia.commons.logger.SLF4JLoggingService;
import tools.dynamia.domain.query.QueryParameters;
import tools.dynamia.domain.services.CrudService;
import tools.dynamia.integration.Containers;
import tools.dynamia.viewers.Field;
import tools.dynamia.viewers.ViewCustomizer;
import tools.dynamia.viewers.ViewDescriptor;
import tools.dynamia.viewers.impl.DefaultViewDescriptor;
import tools.dynamia.viewers.util.Viewers;
import tools.dynamia.web.util.HttpUtils;
import tools.dynamia.zk.BindingComponentIndex;
import tools.dynamia.zk.ComponentAliasIndex;
import tools.dynamia.zk.crud.CrudView;
import tools.dynamia.zk.crud.actions.FastCrudAction;
import tools.dynamia.zk.ui.CanBeReadonly;
import tools.dynamia.zk.util.ZKUtil;
import tools.dynamia.zk.viewers.ZKWrapperView;
import tools.dynamia.zk.viewers.table.TableView;
import tools.dynamia.zk.viewers.table.TableViewRowRenderer;
import tools.dynamia.zk.viewers.ui.Viewer;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import static java.util.function.Predicate.not;
/**
* @author Mario A. Serrano Leones
*/
@SuppressWarnings("rawtypes")
public class EntityPickerBox extends Span implements CanBeReadonly {
/**
*
*/
private static final long serialVersionUID = 6708107320014456649L;
public static final String ENTITYPICKER = "entitypicker";
static {
BindingComponentIndex.getInstance().put("selected", EntityPickerBox.class);
ComponentAliasIndex.getInstance().add(ENTITYPICKER, EntityPickerBox.class);
}
private static final LoggingService logger = new SLF4JLoggingService(EntityPickerBox.class);
private final QueryParameters defaultParameters = new QueryParameters();
private final CrudService crudService = Containers.get().findObject(CrudService.class);
private String[] fields;
private Class entityClass;
private String entityProperty;
private String entityName;
private Object selected;
private boolean autoboxed;
private Bandbox inputField;
private TableView resultTable;
private A tableButton;
private boolean autoselect;
private long lastSearchTimestamp;
private String lastSearchText;
private List result;
private String defaultItemLabel;
private int maxResults = 20;
private boolean autosearch = true;
private String emptyMessage;
private int requiredTextSize = 0;
public EntityPickerBox() {
init();
}
public EntityPickerBox(Class entityClass) {
setEntityClass(entityClass);
init();
}
public EntityPickerBox(Class entityClass, Object selected) {
setEntityClass(entityClass);
setSelected(selected);
init();
}
private static boolean isSearcheable(Field f) {
return !Boolean.FALSE.equals(f.getParams().get("searcheable"));
}
private void init() {
String writeMoreText = Messages.get(EntityPickerBox.class, "writeMore");
String selectText = Messages.get(EntityPickerBox.class, "select");
setTooltiptext(writeMoreText);
setZclass("entitypickerbox");
initInputField();
initCrudView(selectText);
}
private void initInputField() {
inputField = new Bandbox();
tableButton = new A();
appendChild(inputField);
appendChild(tableButton);
tableButton.setZclass("entitypickerbox-button");
tableButton.setIconSclass("z-icon-search");
inputField.setAutodrop(true);
Bandpopup popup = new Bandpopup();
inputField.appendChild(popup);
inputField.setPopupWidth("110%");
inputField.setSclass("entitypickerbox-popup");
inputField.addEventListener(Events.ON_CHANGING, evt -> {
InputEvent event = (InputEvent) evt;
String newValue = event.getValue();
if (newValue != null && newValue.length() >= requiredTextSize) {
search(newValue);
}
});
inputField.addEventListener(Events.ON_OPEN, evt -> {
if (resultTable.getModel() == null || resultTable.getModel().getSize() == 0) {
if (isAutosearch()) {
search("%");
}
}
});
inputField.addEventListener(Events.ON_OK, evt -> {
if (result != null && result.size() == 1) {
setSelected(result.get(0));
Events.postEvent(Events.ON_SELECT, this, getSelected());
close();
}
});
}
private void initTableView() {
String noneText = Messages.get(EntityPickerBox.class, "none");
ViewDescriptor descriptor = Viewers.findViewDescriptor(entityClass, HttpUtils.detectDevice(), ENTITYPICKER);
if (descriptor == null || HttpUtils.isSmartphone()) {
resultTable = new TableView();
resultTable.setItemRenderer((ListitemRenderer) (item, data, index) -> {
String noneLabel = defaultItemLabel != null ? defaultItemLabel : noneText;
item.setValue(data);
item.setLabel(data != null ? BeanUtils.getInstanceName(data) : noneLabel);
});
} else {
DefaultViewDescriptor resultDescriptor = new DefaultViewDescriptor(entityClass, "table", false);
resultDescriptor.addParam("sizedByContent", true);
resultDescriptor.merge(descriptor);
resultTable = (TableView) Viewers.getView(resultDescriptor);
resultTable.setItemRenderer(new TableViewRowRenderer() {
@Override
public void render(Listitem item, Object data, int index) {
String noneLabel = defaultItemLabel != null ? defaultItemLabel : noneText;
if (data == null) {
Listcell noneCell = new Listcell(noneLabel);
noneCell.setParent(item);
int fields = descriptor.getFields().size();
noneCell.setSpan(fields);
} else {
super.render(item, data, index);
}
}
});
resultTable.setHeight(null);
resultTable.setVflex(null);
resultTable.setHflex(null);
}
resultTable.setMold("default");
resultTable.setAutopaging(false);
resultTable.setHeight("250px");
resultTable.setHflex("1");
resultTable.setEmptyMessage(emptyMessage);
inputField.getDropdown().appendChild(resultTable);
resultTable.addEventListener(Events.ON_SELECT, evt -> {
Events.postEvent(this, evt);
if (HttpUtils.isSmartphone()) {
close();
}
});
resultTable.addEventListener(Events.ON_OK, evt -> close());
inputField.setWidgetListener("onKeyDown", "event.keyCode==40?this.lastChild.lastChild.firstItem.focus():''");
}
private void initCrudView(String selectText) {
tableButton.addEventListener(Events.ON_CLICK, e -> {
Viewer viewer = new Viewer("crud", entityClass);
viewer.setVflex("1");
viewer.setContentVflex("1");
CrudView crudView = (CrudView) viewer.getView();
FastCrudAction selectAction = new FastCrudAction(selectText + " " + entityName, "check", ce -> {
setSelected(ce.getData());
viewer.getParent().detach();
Set selecteds = new HashSet();
//noinspection unchecked
selecteds.add(selected);
//noinspection unchecked
Events.postEvent(new SelectEvent(Events.ON_SELECT, this, selecteds));
});
selectAction.setColor("white");
selectAction.setBackground("#00C851");
crudView.addAction(selectAction);
ZKUtil.showDialog(entityName, viewer, "80%", "80%");
crudView.getController().setDefaultParameters(defaultParameters);
if (defaultParameters != null && !defaultParameters.isEmpty()) {
crudView.getController().doQuery();
}
});
}
private void search(String param) {
//ms
long DELAY = 500;
if (lastSearchTimestamp > 0 && (System.currentTimeMillis() - lastSearchTimestamp) < DELAY) {
return;
}
if (entityClass != null && !Objects.equals(lastSearchText, param) || lastSearchTimestamp == 0) {
defaultParameters.setMaxResults(maxResults);
//noinspection unchecked
this.result = crudService.findByFields(entityClass, param, defaultParameters, getFields());
if (result != null && !result.isEmpty()) {
autoboxed = false;
inputField.open();
}
//noinspection unchecked
result.add(0, null);
ZKUtil.fillListbox(resultTable, result, true);
if ((param == null || param.isEmpty()) && selected != null) {
setSelected(null);
Events.postEvent(Events.ON_SELECT, this, null);
}
lastSearchTimestamp = System.currentTimeMillis();
lastSearchText = param;
}
}
public Object getSelected() {
if (resultTable.getSelectedItem() != null) {
selected = resultTable.getSelectedItem().getValue();
} else if (entityClass == null && entityProperty != null) {
selected = inputField.getValue();
}
autoboxSelected();
return selected;
}
public void setSelected(Object object) {
this.selected = object;
if (object != null) {
inputField.setValue(object.toString());
} else {
inputField.setValue(null);
}
if (resultTable.getModel() instanceof AbstractListModel model) {
if (object != null) {
//noinspection unchecked
model.addToSelection(object);
} else {
model.clearSelection();
}
}
}
public final void setEntityClass(String entityClass) {
try {
Class clazz = Class.forName(entityClass);
setEntityClass(clazz);
} catch (ClassNotFoundException e) {
logger.warn("EntityPickerBox: [" + entityClass + "] class not found. " + e.getMessage() + " - COMPONENT AUTODISABLED");
setDisabled(true);
resultTable = new TableView();
}
}
public final void setEntityClass(Class entityClass) {
this.entityClass = entityClass;
if (entityClass != null) {
entityName = StringUtils.addSpaceBetweenWords(entityClass.getSimpleName());
entityName = StringUtils.capitalizeAllWords(entityName);
inputField.setPlaceholder(entityName);
inputField.setTooltiptext(entityName);
initTableView();
}
}
public void setFields(String fields) {
if (fields != null) {
String[] fieldsNames = fields.trim().replace(" ", "").split(",");
setFields(fieldsNames);
}
}
public void setFields(String... fields) {
if (fields != null) {
this.fields = fields;
}
}
public String[] getFields() {
if (fields == null) {
loadFields();
}
return fields;
}
private void loadFields() {
ViewDescriptor descriptor = Viewers.getViewDescriptor(entityClass, ENTITYPICKER);
DefaultViewDescriptor tableDescriptor = new DefaultViewDescriptor(entityClass, "table", false);
tableDescriptor.merge(descriptor);
if (descriptor.getViewCustomizerClass() != null) {
try {
ViewCustomizer customizer = BeanUtils.newInstance(descriptor.getViewCustomizerClass());
//noinspection unchecked
customizer.customize(new ZKWrapperView(this));
} catch (Exception ignored) {
}
}
if (fields != null && fields.length > 0) {
setFields(fields);
} else {
fields = Viewers.getFields(descriptor).stream()
.filter(Field::isProperty)
.filter(Field::isVisible)
.filter(Field::isReadWrite)
.filter(not(Field::isCollection))
.filter(EntityPickerBox::isSearcheable)
.map(Field::getName)
.toArray(String[]::new);
}
}
public void addDefaultParameter(String name, Object value) {
defaultParameters.add(name, value);
}
public void removeDefaultParameter(String name) {
defaultParameters.remove(name);
}
public void setOrderBy(String orderBy) {
defaultParameters.orderBy(orderBy, true);
}
public Class getEntityClass() {
return entityClass;
}
public String getEntityProperty() {
return entityProperty;
}
public void setEntityProperty(String entityProperty) {
this.entityProperty = entityProperty;
}
private void autoboxSelected() {
if (!autoboxed && entityProperty != null && selected != null) {
selected = BeanUtils.invokeGetMethod(selected, BeanUtils.getPropertyInfo(entityClass, entityProperty));
autoboxed = true;
}
}
@Override
public boolean isReadonly() {
return inputField.isReadonly();
}
@Override
public void setReadonly(boolean readonly) {
inputField.setReadonly(readonly);
tableButton.setVisible(!readonly);
inputField.setButtonVisible(!readonly);
}
public ListModel getModel() {
return resultTable.getModel();
}
public void setModel(ListModel> model) {
resultTable.setModel(model);
}
public void setEmptySearchMessage(String msg) {
resultTable.setEmptyMessage(msg);
}
public ListitemRenderer getItemRenderer() {
return resultTable.getItemRenderer();
}
public void setItemRenderer(ListitemRenderer> renderer) {
resultTable.setItemRenderer(renderer);
}
public void setItemRenderer(String clsnm) throws
ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
resultTable.setItemRenderer(clsnm);
}
public boolean isAutodrop() {
return inputField.isAutodrop();
}
public void setAutodrop(boolean autodrop) {
inputField.setAutodrop(autodrop);
}
public boolean isAutocomplete() {
return inputField.isAutodrop();
}
public void setAutocomplete(boolean autocomplete) {
inputField.setAutodrop(autocomplete);
}
public boolean isOpen() {
return inputField.isOpen();
}
public void setOpen(boolean open) {
inputField.setOpen(open);
}
public void open() {
inputField.open();
}
public void close() {
inputField.close();
}
public void setMultiline(boolean multiline) {
inputField.setMultiline(multiline);
}
public void setRows(int rows) {
inputField.setRows(rows);
}
public boolean isSubmitByEnter() {
return inputField.isSubmitByEnter();
}
public void setSubmitByEnter(boolean submitByEnter) {
inputField.setSubmitByEnter(submitByEnter);
}
public String getPlaceholder() {
return inputField.getPlaceholder();
}
public void setPlaceholder(String placeholder) {
inputField.setPlaceholder(placeholder);
}
public void setInplace(boolean inplace) {
inputField.setInplace(inplace);
}
public boolean isInplace() {
return inputField.isInplace();
}
public void setDisabled(boolean disabled) {
inputField.setDisabled(disabled);
if (tableButton != null) {
tableButton.setDisabled(disabled);
}
}
public boolean isAutoselect() {
return autoselect;
}
public void setAutoselect(boolean autoselect) {
this.autoselect = autoselect;
}
public String getPopupWidth() {
return inputField.getPopupWidth();
}
public void setPopupWidth(String popupWidth) {
inputField.setPopupWidth(popupWidth);
}
public String getDefaultItemLabel() {
return defaultItemLabel;
}
public void setDefaultItemLabel(String defaultItemLabel) {
this.defaultItemLabel = defaultItemLabel;
}
public int getMaxResults() {
return maxResults;
}
public void setMaxResults(int maxResults) {
this.maxResults = maxResults;
}
public QueryParameters getDefaultParameters() {
return defaultParameters;
}
public boolean isAutosearch() {
return autosearch;
}
public void setAutosearch(boolean autosearch) {
this.autosearch = autosearch;
}
public String getEmptyMessage() {
return emptyMessage;
}
public void setEmptyMessage(String emptyMessage) {
this.emptyMessage = emptyMessage;
if (resultTable != null) {
resultTable.setEmptyMessage(emptyMessage);
}
}
public int getRequiredTextSize() {
return requiredTextSize;
}
public void setRequiredTextSize(int requiredTextSize) {
this.requiredTextSize = requiredTextSize;
}
}