/** * Copyright (C) 2010 Asterios Raptis * * 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 de.alpharogroup.wicket.components.form.dropdown; import java.util.List; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.IChoiceRenderer; import org.apache.wicket.model.IModel; import org.apache.wicket.util.string.AppendingStringBuffer; import org.apache.wicket.util.string.Strings; /** * The Class {@link OptGroupDropDownChoice} is for use with select and optgroup. * * @param <T> * the generic type */ public abstract class OptGroupDropDownChoice<T extends OptGroup> extends DropDownChoice<T> { /** The Constant CLOSE_OPTGROUP_TAG. */ private static final String CLOSE_OPTGROUP_TAG = "\n</optgroup>"; /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The last. */ private T last; /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id */ public OptGroupDropDownChoice(final String id) { super(id); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param choices * the choices */ public OptGroupDropDownChoice(final String id, final IModel<? extends List<? extends T>> choices) { super(id, choices); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param choices * the choices * @param renderer * the renderer */ public OptGroupDropDownChoice(final String id, final IModel<? extends List<? extends T>> choices, final IChoiceRenderer<? super T> renderer) { super(id, choices, renderer); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param model * the model * @param choices * the choices */ public OptGroupDropDownChoice(final String id, final IModel<T> model, final IModel<? extends List<? extends T>> choices) { super(id, model, choices); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param model * the model * @param choices * the choices * @param renderer * the renderer */ public OptGroupDropDownChoice(final String id, final IModel<T> model, final IModel<? extends List<? extends T>> choices, final IChoiceRenderer<? super T> renderer) { super(id, model, choices, renderer); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param model * the model * @param choices * the choices */ public OptGroupDropDownChoice(final String id, final IModel<T> model, final List<? extends T> choices) { super(id, model, choices); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param model * the model * @param choices * the choices * @param renderer * the renderer */ public OptGroupDropDownChoice(final String id, final IModel<T> model, final List<? extends T> choices, final IChoiceRenderer<? super T> renderer) { super(id, model, choices, renderer); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param choices * the choices */ public OptGroupDropDownChoice(final String id, final List<? extends T> choices) { super(id, choices); } /** * Instantiates a new {@link OptGroupDropDownChoice}. * * @param id * the id * @param choices * the choices * @param renderer * the renderer */ public OptGroupDropDownChoice(final String id, final List<? extends T> choices, final IChoiceRenderer<? super T> renderer) { super(id, choices, renderer); } /** * Appends the label of the given opt group object to the given {@link AppendingStringBuffer} * object. * * @param buffer * the buffer * @param optGroup * the opt group to append. */ private void appendOptGroupLabel(final AppendingStringBuffer buffer, final T optGroup) { buffer.append("\n<optgroup label='") .append(Strings.escapeMarkup(getOptGroupLabel(optGroup))).append("'>"); } /** * {@inheritDoc} */ @Override protected void appendOptionHtml(final AppendingStringBuffer buffer, final T choice, final int index, final String selected) { final T currentOptGroup = choice; if (isNewGroup(currentOptGroup)) { if (!isFirst(index)) { buffer.append(CLOSE_OPTGROUP_TAG); } appendOptGroupLabel(buffer, currentOptGroup); } super.appendOptionHtml(buffer, choice, index, selected); if (isLast(index)) { buffer.append(CLOSE_OPTGROUP_TAG); } last = currentOptGroup; } /** * Abstract method that have to be overwritten to get the label of the given opt group object. * * @param optGroup * the opt group * @return the label of the given opt group object. */ protected abstract String getOptGroupLabel(final T optGroup); /** * Checks if it is first. * * @param index * the index * @return true, if is first */ private boolean isFirst(final int index) { return index == 0; } /** * Checks if it is last. * * @param index * the index * @return true, if is last */ private boolean isLast(final int index) { return (index - 1) == getChoices().size(); } /** * Checks if it is new group. * * @param currentOptGroup * the current opt group * @return true, if is new group */ private boolean isNewGroup(final OptGroup currentOptGroup) { return (last == null) || !currentOptGroup.getLabel().equals(last.getLabel()); } /** * {@inheritDoc} */ @Override protected void onDetach() { super.onDetach(); last = null; } }