diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxSearch.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxSearch.java new file mode 100644 index 000000000..7ed317d8f --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxSearch.java @@ -0,0 +1,165 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.bandboxsearch; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang.StringUtils; +import org.navalplanner.business.labels.entities.Label; +import org.navalplanner.web.common.components.finders.IBandboxFinder; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.HtmlMacroComponent; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.InputEvent; +import org.zkoss.zul.Bandbox; +import org.zkoss.zul.ListModel; +import org.zkoss.zul.Listhead; +import org.zkoss.zul.Listheader; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.SimpleListModel; +import org.zkoss.zul.api.Listbox; + +@SuppressWarnings("serial") +public class BandboxSearch extends HtmlMacroComponent { + + private Listbox listbox; + + private Listhead listhead; + + private Bandbox bandbox; + + private IBandboxFinder finder; + + public void afterCompose() { + super.afterCompose(); + listbox = (Listbox) getFellowIfAny("listbox"); + listbox.setModel(finder.getModel()); + listbox.setItemRenderer(finder.getItemRenderer()); + + listhead = (Listhead) listbox.getFellowIfAny("listhead"); + bandbox = (Bandbox) getFellowIfAny("bandbox"); + + /** + * Search for matching elements while typing on bandbox + */ + bandbox.addEventListener("onChanging", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + clearSelectedElement(); + final String inputText = ((InputEvent) event).getValue(); + listbox.setModel(getSubModel(inputText)); + listbox.invalidate(); + } + }); + + /** + * Pick element from list when selecting + */ + listbox.addEventListener("onSelect", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + final Object object = getSelectedItem().getValue(); + bandbox.setValue(finder.objectToString(object)); + setSelectedElement(object); + bandbox.close(); + } + }); + + addHeaders(); + } + + private void clearSelectedElement() { + setSelectedElement(null); + } + + private void setSelectedElement(Object obj) { + bandbox.setVariable("selectedElement", obj, true); + } + + /** + * Find {@link Label} which name or type start with prefix + * + * @param inputText + */ + @SuppressWarnings("unchecked") + private ListModel getSubModel(String inputText) { + List result = new ArrayList(); + + final SimpleListModel model = finder.getModel(); + for (int i = 0; i < model.getSize(); i++) { + Object obj = model.getElementAt(i); + if (finder.entryMatchesText(obj, inputText)) { + result.add(obj); + } + } + return new SimpleListModel(result); + } + + /** + * Append headers to listbox header list + */ + @SuppressWarnings("unchecked") + public void addHeaders() { + clearHeaderIfNecessary(); + final String[] headers = finder.getHeaders(); + for (int i = 0; i < headers.length; i++) { + listhead.getChildren().add(new Listheader(headers[i])); + } + } + + private void clearHeaderIfNecessary() { + if (listhead.getChildren() != null) { + listhead.getChildren().clear(); + } + } + + private Listitem getSelectedItem() { + return (Listitem) listbox.getSelectedItems().iterator().next(); + } + + public String getFinder() { + return finder.getClass().toString(); + } + + public void setFinder(String classname) { + finder = (IBandboxFinder) getBean(StringUtils.uncapitalize(classname)); + } + + private Object getBean(String classname) { + HttpServletRequest servletRequest = (HttpServletRequest) Executions + .getCurrent().getNativeRequest(); + ServletContext servletContext = servletRequest.getSession() + .getServletContext(); + WebApplicationContext webApplicationContext = WebApplicationContextUtils + .getWebApplicationContext(servletContext); + return webApplicationContext.getBean(classname); + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/BandboxFinder.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/BandboxFinder.java new file mode 100644 index 000000000..b43b3baab --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/BandboxFinder.java @@ -0,0 +1,75 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.finders; + +import org.springframework.transaction.annotation.Transactional; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.ListitemRenderer; +import org.zkoss.zul.SimpleListModel; + +/** + * BandboxFinder implements basic methods for {@link IBandboxFinder} and + * provides a default renderer, the rest of methods for {@link IBandboxFinder} + * should be implement by a concrete class + * + * @author Diego Pino Garcia + * + */ +public abstract class BandboxFinder implements IBandboxFinder { + + @Override + @Transactional(readOnly = true) + public SimpleListModel getModel() { + return new SimpleListModel(getAll()); + } + + @Override + public ListitemRenderer getItemRenderer() { + return _defRend; + } + + /** + * Class for rendering combo items + * + * It's necessary to provide this renderer since by default a combobox sets + * label as Objects.toString(data) which relies on the actual implementation + * of Object.toString. By doing this, it's possible to decouple how an + * object is shown from its Object.toString method. + * + * See Combobox.getDefaultItemRenderer() + * + * In general it won't be necessary to overwrite this Renderer. Use + * _toString() to indicate how an object is shown in the list of matching + * elements + * + * @author Diego Pino Garcia + * + */ + private final ListitemRenderer _defRend = new ListitemRenderer() { + + @Override + public void render(Listitem item, Object data) throws Exception { + item.setLabel(objectToString(data)); + item.setValue(data); + } + }; + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/IBandboxFinder.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/IBandboxFinder.java new file mode 100644 index 000000000..e7301bf34 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/IBandboxFinder.java @@ -0,0 +1,90 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.finders; + +import java.util.List; + +import org.navalplanner.business.common.BaseEntity; +import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch; +import org.zkoss.zul.ListModel; +import org.zkoss.zul.ListitemRenderer; +import org.zkoss.zul.SimpleListModel; + +/** + * Interface for providing, displaying and matching elements for a + * {@link BandboxSearch} + * + * @author Diego Pino Garcia + */ +public interface IBandboxFinder { + + /** + * Specify here how to do the matching between an object and input text + * + * @param entry + * @param text + * @return + */ + boolean entryMatchesText(Object obj, String text); + + /** + * Get list of {@link BaseEntity} to fill {@link BandboxSearch} + * + * Executed once only when {@link BandboxSearch} is rendered for the first + * time + * + * @return + */ + List getAll(); + + /** + * Returns a {@link ListModel} of objects specified by concrete classes + * which implement this interface + * + * @return + */ + SimpleListModel getModel(); + + /** + * Provides headers for {@link BandboxSearch} + * + * @return + */ + String[] getHeaders(); + + /** + * Returns a customize {@link ListitemRenderer} + * + * This renderer knows how to show objects in the list of elements + * + * @return + */ + ListitemRenderer getItemRenderer(); + + /** + * Text displayed for each object in the list of elements + * + * @param value + * @return + */ + String objectToString(Object obj); + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/LabelBandboxFinder.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/LabelBandboxFinder.java new file mode 100644 index 000000000..76549fbfd --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/LabelBandboxFinder.java @@ -0,0 +1,122 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.finders; + +import static org.navalplanner.web.I18nHelper._; + +import java.util.List; + +import org.navalplanner.business.labels.daos.ILabelDAO; +import org.navalplanner.business.labels.entities.Label; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import org.zkoss.zul.Bandbox; +import org.zkoss.zul.Listcell; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.ListitemRenderer; + +/** + * Implements all the methods needed to comply IBandboxFinder + * + * This is a finder for {@link Label}l in a {@link Bandbox}. Provides how many + * columns for {@link Label} will be shown, how to render {@link Label} object , + * how to do the matching, what text to show when an element is selected, etc + * + * @author Diego Pino Garcia + * + */ +@Repository +public class LabelBandboxFinder extends BandboxFinder implements IBandboxFinder { + + @Autowired + private ILabelDAO labelDAO; + + private final String headers[] = { _("Type"), _("Name") }; + + public LabelBandboxFinder() { + + } + + @Override + @Transactional(readOnly = true) + public List