/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 ro.nextreports.server.web.common.misc; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.wicket.Component; import org.apache.wicket.extensions.markup.html.form.palette.Palette; import org.apache.wicket.extensions.markup.html.form.palette.component.AbstractOptions; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.MarkupStream; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.IChoiceRenderer; import org.apache.wicket.model.IModel; import org.apache.wicket.request.resource.PackageResourceReference; import org.apache.wicket.util.convert.IConverter; import org.apache.wicket.util.string.AppendingStringBuffer; import org.apache.wicket.util.string.Strings; /** * User: mihai.panaitescu * Date: 11-May-2010 * Time: 10:14:51 */ public class ExtendedPalette<T> extends Palette<T> { private static final long serialVersionUID = 1L; // private static final String SELECTED_HEADER_ID = "selectedHeader"; // private static final String AVAILABLE_HEADER_ID = "availableHeader"; private final IModel<? extends Collection<? extends T>> choicesModel; private final IChoiceRenderer<T> choiceRenderer; private final int rows; /** * if reordering of selected items is allowed in */ private final boolean allowOrder; /** * if add all and remove all are allowed */ private final boolean allowMoveAll; public ExtendedPalette(String id, IModel<List<T>> model, IModel<? extends Collection<? extends T>> choicesModel, IChoiceRenderer<T> choiceRenderer, int rows, boolean allowOrder) { this(id, model, choicesModel, choiceRenderer, rows, allowOrder, false); } /** * @param id Component id * @param choicesModel Model representing collection of all available choices * @param choiceRenderer Render used to render choices. This must use unique IDs for the objects, not the * index. * @param rows Number of choices to be visible on the screen with out scrolling * @param allowOrder Allow user to move selections up and down * @param allowMoveAll Allow user to add or remove all items at once */ public ExtendedPalette(String id, IModel<? extends Collection<? extends T>> choicesModel, IChoiceRenderer<T> choiceRenderer, int rows, boolean allowOrder, boolean allowMoveAll) { this(id, null, choicesModel, choiceRenderer, rows, allowOrder, allowMoveAll); } /** * @param id Component id * @param model Model representing collection of user's selections * @param choicesModel Model representing collection of all available choices * @param choiceRenderer Render used to render choices. This must use unique IDs for the objects, not the * index. * @param rows Number of choices to be visible on the screen with out scrolling * @param allowOrder Allow user to move selections up and down * @param allowMoveAll Allow user to add or remove all items at once */ public ExtendedPalette(String id, IModel<List<T>> model, IModel<? extends Collection<? extends T>> choicesModel, IChoiceRenderer<T> choiceRenderer, int rows, boolean allowOrder, boolean allowMoveAll) { super(id, model, choicesModel, choiceRenderer, rows, allowOrder, allowMoveAll); this.choicesModel = choicesModel; this.choiceRenderer = choiceRenderer; this.rows = rows; this.allowOrder = allowOrder; this.allowMoveAll = allowMoveAll; } /** * factory method for the addAll component * * @return addAll component */ protected Component newAddAllComponent() { return new PaletteButton("addAllButton") { private static final long serialVersionUID = 1L; protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); tag.getAttributes().put("onclick", getAddAllOnClickJS()); } }; } /** * factory method for the removeAll component * * @return removeAll component */ protected Component newRemoveAllComponent() { return new PaletteButton("removeAllButton") { private static final long serialVersionUID = 1L; protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); tag.getAttributes().put("onclick", getRemoveAllOnClickJS()); } }; } @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); response.render(JavaScriptHeaderItem.forReference(new PackageResourceReference(ExtendedPalette.class, "extendedpalette.js"))); } /** * @return addAll action javascript handler */ public String getAddAllOnClickJS() { return buildJSCall("Wicket.Palette.addAll"); } /** * @return removeAll action javascript handler */ public String getRemoveAllOnClickJS() { return buildJSCall("Wicket.Palette.removeAll"); } private class PaletteButton extends WebMarkupContainer { private static final long serialVersionUID = 1L; public PaletteButton(String id) { super(id); } @Override protected void onComponentTag(ComponentTag tag) { if (!isPaletteEnabled()) { tag.getAttributes().put("disabled", "disabled"); } } } public Collection<? extends T> getChoices() { return choicesModel.getObject(); } @Override protected void onDetach() { // we need to manually detach the choices model since it is not attached // to a common // an alternative might be to attach it to one of the subcomponents choicesModel.detach(); super.onDetach(); } public IChoiceRenderer<T> getChoiceRenderer() { return choiceRenderer; } public int getRows() { return rows; } /** * factory method for the remove component * * @return remove component */ protected Component newRemoveComponent() { return new PaletteButton("removeButton") { private static final long serialVersionUID = 1L; @Override protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); tag.getAttributes().put("onclick", getRemoveOnClickJS()); } }; } /** * factory method for the addcomponent * * @return add component */ protected Component newAddComponent() { return new PaletteButton("addButton") { private static final long serialVersionUID = 1L; @Override protected void onComponentTag(ComponentTag tag) { super.onComponentTag(tag); tag.getAttributes().put("onclick", getAddOnClickJS()); } }; } @Override protected Component newChoicesComponent(){ return new ConditionCodeChoices<T>("choices", this); } //overriding the choices class wicket Palette uses so we can inject //tooltips into the palettes options. private class ConditionCodeChoices<T> extends AbstractOptions{ public ConditionCodeChoices(String id, Palette palette){ super(id, palette); } @Override protected Iterator getOptionsIterator(){ return getPalette().getUnselectedChoices(); } @Override public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) { final AppendingStringBuffer buffer = new AppendingStringBuffer(128); Iterator<T> options = getOptionsIterator(); IChoiceRenderer<T> renderer = getPalette().getChoiceRenderer(); boolean localizeDisplayValues = localizeDisplayValues(); while (options.hasNext()) { final T choice = options.next(); final CharSequence id; { String value = renderer.getIdValue(choice, 0); if (getEscapeModelStrings()) { id = Strings.escapeMarkup(value); } else { id = value; } } final CharSequence value; { Object displayValue = renderer.getDisplayValue(choice); Class<?> displayClass = displayValue == null ? null : displayValue.getClass(); @SuppressWarnings("unchecked") IConverter<Object> converter = (IConverter<Object>) getConverter(displayClass); String displayString = converter.convertToString(displayValue, getLocale()); if (localizeDisplayValues) { displayString = getLocalizer().getString(displayString, this, displayString); } if (getEscapeModelStrings()) { value = Strings.escapeMarkup(displayString); } else { value = displayString; } } buffer.append("\n<option title='" + value + "' value=\"").append(id).append("\""); Map<String, String> additionalAttributesMap = getAdditionalAttributes(choice); if (additionalAttributesMap != null) { for (Map.Entry<String, String> entry : additionalAttributesMap.entrySet()) { buffer.append(' ').append(entry.getKey()).append("=\"").append(entry.getValue()).append("\""); } } buffer.append(">").append(value).append("</option>"); } buffer.append("\n"); replaceComponentTagBody(markupStream, openTag, buffer); } } }