package fr.openwide.core.wicket.more.markup.html.select2;
import java.util.Collection;
import java.util.List;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
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.model.LoadableDetachableModel;
import org.retzlaff.select2.Select2Behavior;
import org.retzlaff.select2.Select2Settings;
import fr.openwide.core.wicket.more.markup.html.model.ChoicesWrapperModel;
import fr.openwide.core.wicket.more.markup.html.select2.util.DropDownChoiceWidth;
import fr.openwide.core.wicket.more.markup.html.select2.util.IDropDownChoiceWidth;
import fr.openwide.core.wicket.more.markup.html.select2.util.Select2Utils;
public abstract class GenericSelect2DropDownSingleChoice<T> extends DropDownChoice<T> {
private static final long serialVersionUID = -3776700270762640109L;
private IDropDownChoiceWidth width = DropDownChoiceWidth.AUTO;
private ChoicesWrapperModel<T> choicesWrapperModel;
private final Select2Behavior<T, T> select2Behavior;
protected GenericSelect2DropDownSingleChoice(String id, IModel<T> model, IModel<? extends Collection<? extends T>> choicesModel, IChoiceRenderer<? super T> renderer) {
super(id);
setModel(model);
choicesWrapperModel = new ChoicesWrapperModel<T>(model, choicesModel);
setChoices(choicesWrapperModel);
setChoiceRenderer(renderer);
setNullValid(true);
select2Behavior = Select2Behavior.forChoice(this);
fillSelect2Settings(select2Behavior.getSettings());
add(select2Behavior);
}
@SuppressWarnings("unchecked")
protected void ensureChoicesModelIsWrapped() {
/*
* Ideally this wrapping should be done in setChoices(IModel) or in wrap(IModel),
* but those methods cannot be overriden...
*/
IModel<? extends List<? extends T>> choicesModel = getChoicesModel();
if (choicesModel != choicesWrapperModel) {
if (choicesModel instanceof ChoicesWrapperModel) {
this.choicesWrapperModel = (ChoicesWrapperModel<T>) choicesModel;
} else {
this.choicesWrapperModel = new ChoicesWrapperModel<>(getModel(), choicesModel);
setChoices(choicesWrapperModel);
}
}
}
@Override
protected void onInitialize() {
ensureChoicesModelIsWrapped();
super.onInitialize();
add(new AttributeModifier("style", new LoadableDetachableModel<String>() {
private static final long serialVersionUID = 1L;
@Override
protected String load() {
return "width: " + width.getWidth();
}
}) {
private static final long serialVersionUID = 1L;
@Override
public boolean isEnabled(Component component) {
return width != null;
}
});
}
@Override
protected void onConfigure() {
ensureChoicesModelIsWrapped();
super.onConfigure();
if (isRequired()) {
Select2Utils.setRequiredSettings(getSettings());
}
}
protected void fillSelect2Settings(Select2Settings settings) {
Select2Utils.setDefaultSettings(settings);
}
protected final Select2Settings getSettings() {
return select2Behavior.getSettings();
}
public GenericSelect2DropDownSingleChoice<T> setWidth(IDropDownChoiceWidth width) {
this.width = width;
return this;
}
protected String getRootKey() {
return GenericSelect2DropDownSingleChoice.class.getSimpleName() + "." + this.getId();
}
@Override
protected String getNullKey() {
return getRootKey() + ".null";
}
@Override
protected String getNullValidKey() {
return getRootKey() + ".nullValid";
}
public boolean isSelectedObjectForcedInChoices() {
return choicesWrapperModel.isSelectedObjectForcedInChoices();
}
public GenericSelect2DropDownSingleChoice<T> setSelectedObjectForcedInChoices(boolean selectedObjectForcedInChoices) {
choicesWrapperModel.setSelectedObjectForcedInChoices(selectedObjectForcedInChoices);
return this;
}
@Override
protected void onDetach() {
super.onDetach();
if (choicesWrapperModel != null) {
choicesWrapperModel.detach();
}
}
}