package de.alpharogroup.wicket.dropdownchoices.panel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.util.lang.Args;
import de.alpharogroup.collections.ListExtensions;
import de.alpharogroup.wicket.components.i18n.dropdownchoice.LocalisedDropDownChoice;
import lombok.Getter;
import lombok.Setter;
public class DoubleDropDownPanelTest<T> extends FormComponentPanel
{
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The Constant ROOT_CHOICE_ID. */
public static final String ROOT_CHOICE_ID = "rootChoice";
/** The Constant CHILD_CHOICE_ID. */
public static final String CHILD_CHOICE_ID = "childChoice";
/** The root choice. */
@Getter
private DropDownChoice<T> rootChoice;
/** The child choice. */
@Getter
private DropDownChoice<T> childChoice;
/** The root renderer. */
@Getter
private final IChoiceRenderer<T> rootRenderer;
/** The child renderer. */
@Getter
private final IChoiceRenderer<T> childRenderer;
/** The selected root option. */
@Getter
@Setter
private T selectedRootOption;
/** The selected child option. */
@Getter
@Setter
private T selectedChildOption;
/** The models map. */
@Getter
@Setter
private Map<T, List<T>> modelsMap = new HashMap<>();
/** The root choices. */
@Getter
private final List<T> rootChoices;
/** The child choices. */
@SuppressWarnings("unused")
private List<T> childChoices;
public DoubleDropDownPanelTest(String id, final Map<T, List<T>> modelsMap,
final T selectedRootOption, final IChoiceRenderer<T> rootRenderer,
final IChoiceRenderer<T> childRenderer)
{
super(id);
this.modelsMap = Args.notNull(modelsMap, "modelsMap");
this.rootChoices = new ArrayList<>(this.modelsMap.keySet());
this.selectedRootOption = Args.notNull(selectedRootOption, "selectedRootOption");
this.childChoices = getChildChoices();
this.rootRenderer = Args.notNull(rootRenderer, "rootRenderer");
this.childRenderer = Args.notNull(childRenderer, "childRenderer");
}
/**
* Gets the child choices.
*
* @return the child choices
*/
public List<T> getChildChoices()
{
final List<T> childChoices = getModelsMap().get(getSelectedRootOption());
if (ListExtensions.isEmpty(childChoices))
{
return Collections.emptyList();
}
return childChoices;
}
/**
* Factory method for creating the new child {@link DropDownChoice}. This method is invoked in
* the constructor from the derived classes and can be overridden so users can provide their own
* version of a new child {@link DropDownChoice}.
*
* @param id
* the id
* @param model
* the model
* @return the new child {@link DropDownChoice}.
*/
protected DropDownChoice<T> newChildChoice(final String id)
{
final IModel<T> selectedChildOptionModel = new PropertyModel<>(this, "selectedChildOption");
final IModel<List<T>> childChoicesModel = PropertyModel.of(this, "childChoices");
final DropDownChoice<T> cc = new LocalisedDropDownChoice<>(id, selectedChildOptionModel,
childChoicesModel, this.childRenderer);
cc.setOutputMarkupId(true);
cc.add(new AjaxFormComponentUpdatingBehavior("change")
{
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
@Override
protected void onError(AjaxRequestTarget target, RuntimeException e)
{
DoubleDropDownPanelTest.this.onChildChoiceError(target, e);
}
/**
* {@inheritDoc}
*/
@Override
protected void onUpdate(final AjaxRequestTarget target)
{
DoubleDropDownPanelTest.this.onChildChoiceUpdate(target);
}
});
return cc;
}
/**
* Factory method for creating the new root {@link DropDownChoice}. This method is invoked in
* the constructor from the derived classes and can be overridden so users can provide their own
* version of a new root {@link DropDownChoice}.
*
* @param id
* the id
* @param model
* the model
* @return the new root {@link DropDownChoice}.
*/
protected DropDownChoice<T> newRootChoice(final String id)
{
final IModel<T> selectedRootOptionModel = PropertyModel.of(this, "selectedRootOption");
final IModel<List<T>> rootChoicesModel = PropertyModel.of(this, "rootChoices");
final DropDownChoice<T> rc = new LocalisedDropDownChoice<>(id, selectedRootOptionModel,
rootChoicesModel, this.rootRenderer);
rc.add(new AjaxFormComponentUpdatingBehavior("change")
{
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
@Override
protected void onError(AjaxRequestTarget target, RuntimeException e)
{
DoubleDropDownPanelTest.this.onRootChoiceError(target, e);
}
/**
* {@inheritDoc}
*/
@Override
protected void onUpdate(final AjaxRequestTarget target)
{
DoubleDropDownPanelTest.this.onRootChoiceUpdate(target);
}
});
return rc;
}
protected void onChildChoiceError(AjaxRequestTarget target, RuntimeException e)
{
System.err.println("onChildChoiceError:");
}
protected void onChildChoiceUpdate(final AjaxRequestTarget target)
{
target.add(DoubleDropDownPanelTest.this.childChoice);
}
protected void onChildSelectionChanged(Object newSelection)
{
System.err.println("onChildSelectionChanged:" + newSelection);
}
/**
* {@inheritDoc}
*/
@Override
protected void onInitialize()
{
super.onInitialize();
add(rootChoice = newRootChoice(ROOT_CHOICE_ID));
add(childChoice = newChildChoice(CHILD_CHOICE_ID));
}
protected void onRootChoiceError(AjaxRequestTarget target, RuntimeException e)
{
System.err.println("onRootChoiceError:");
}
protected void onRootChoiceUpdate(final AjaxRequestTarget target)
{
DoubleDropDownPanelTest.this.childChoice.modelChanging();
target.add(DoubleDropDownPanelTest.this.childChoice);
DoubleDropDownPanelTest.this.childChoice.modelChanged();
}
protected void onRootSelectionChanged(Object newSelection)
{
T t = rootChoice.getModelObject();
System.err.println("onRootSelectionChanged:" + newSelection);
}
}