package fr.openwide.core.wicket.more.markup.html.select2;
import java.util.Collections;
import java.util.List;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.form.AbstractTextComponent;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.IObjectClassAwareModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.util.convert.ConversionException;
import org.retzlaff.select2.ISelect2AjaxAdapter;
import org.retzlaff.select2.Select2Behavior;
import org.retzlaff.select2.Select2Settings;
import org.retzlaff.select2.Select2SingleChoice;
import org.springframework.util.StringUtils;
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;
import fr.openwide.core.wicket.more.model.BindingModel;
public class GenericSelect2AjaxDropDownSingleChoice<T> extends Select2SingleChoice<T> {
private static final long serialVersionUID = 6355575209286187233L;
private IDropDownChoiceWidth width = DropDownChoiceWidth.AUTO;
protected GenericSelect2AjaxDropDownSingleChoice(String id, IModel<T> model, ISelect2AjaxAdapter<T> adapter) {
super(id, model, adapter);
fillSelect2Settings(getSettings());
}
@Override
protected void onInitialize() {
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() {
super.onConfigure();
if (isRequired()) {
Select2Utils.setRequiredSettings(getSettings());
}
}
protected void fillSelect2Settings(Select2Settings settings) {
Select2Utils.setDefaultAjaxSettings(settings);
}
public GenericSelect2AjaxDropDownSingleChoice<T> setWidth(IDropDownChoiceWidth width) {
this.width = width;
return this;
}
/**
* Workaround.<br>
* The client method, {@link Select2Behavior#renderHead(org.apache.wicket.Component, org.apache.wicket.markup.head.IHeaderResponse)},
* does not handle input re-rendering when form validation fails.<br>
* Since overloading {@link Select2Behavior#renderHead(org.apache.wicket.Component, org.apache.wicket.markup.head.IHeaderResponse)}
* would be both tedious and dangerous, we handle it here...
*/
@Override
protected List<T> getModelObjects() {
T object = getConvertedInput();
if (object == null) {
return super.getModelObjects();
}
return Collections.singletonList(object);
}
/**
* Workaround.<br>
* When the underlying model is a {@link IObjectClassAwareModel} (a {@link BindingModel} for example),
* the {@link AbstractTextComponent#resolveType()} method will be able to determine the model type.<br>
* As a consequence, the {@link FormComponent#convertInput()} method will totally ignore {@link Select2SingleChoice#convertValue(String[]))},
* which is quite annoying since this is the method that makes use of {@link ISelect2AjaxAdapter#getChoice(String)}...<br>
* That's why we have to force the use of {@link #convertValue(String[])}.
*/
@Override
public void convertInput() {
String[] value = getInputAsArray();
String tmp = value != null && value.length > 0 ? value[0] : null;
if (getConvertEmptyInputStringToNull() && !StringUtils.hasText(tmp)) {
setConvertedInput(null);
} else {
try {
setConvertedInput(convertValue(getInputAsArray()));
} catch (ConversionException e) {
error(newValidationError(e));
}
}
}
}