Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of https://github.com/Evolveum/midpoint
- Loading branch information
Showing
85 changed files
with
10,147 additions
and
8,919 deletions.
There are no files selected for viewing
371 changes: 164 additions & 207 deletions
371
...main/java/com/evolveum/midpoint/gui/api/component/autocomplete/AutoCompleteTextPanel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,207 +1,164 @@ | ||
/* | ||
* Copyright (c) 2010-2020 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.gui.api.component.autocomplete; | ||
|
||
import java.util.Iterator; | ||
import java.util.Locale; | ||
|
||
import org.apache.wicket.ajax.AjaxRequestTarget; | ||
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; | ||
import org.apache.wicket.ajax.attributes.ThrottlingSettings; | ||
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSettings; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.IAutoCompleteRenderer; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.StringAutoCompleteRenderer; | ||
import org.apache.wicket.markup.html.form.FormComponent; | ||
import org.apache.wicket.model.IModel; | ||
import org.apache.wicket.util.convert.ConversionException; | ||
import org.apache.wicket.util.convert.IConverter; | ||
import org.apache.wicket.util.time.Duration; | ||
|
||
import com.evolveum.midpoint.gui.api.util.WebComponentUtil; | ||
import com.evolveum.midpoint.web.model.LookupPropertyModel; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; | ||
|
||
/** | ||
* Autocomplete field for Strings. | ||
* | ||
* TODO: may need some work to properly support non-string values. | ||
* | ||
* @author shood | ||
* @author semancik | ||
* */ | ||
public abstract class AutoCompleteTextPanel<T> extends AbstractAutoCompletePanel { | ||
private static final long serialVersionUID = 1L; | ||
|
||
private static final String ID_INPUT = "input"; | ||
|
||
private LookupTableType lookupTable = null; | ||
private boolean strict; | ||
|
||
// public AutoCompleteTextPanel(String id, final IModel<T> model, Class<T> type) { | ||
// this(id, model, type, StringAutoCompleteRenderer.INSTANCE); | ||
// } | ||
|
||
public AutoCompleteTextPanel(String id, final IModel<T> model, Class<T> type, boolean strict, LookupTableType lookuptable) { | ||
this(id, model, type, StringAutoCompleteRenderer.INSTANCE); | ||
this.lookupTable = lookuptable; | ||
this.strict = strict; | ||
} | ||
|
||
public AutoCompleteTextPanel(String id, final IModel<T> model, Class<T> type, IAutoCompleteRenderer<T> renderer) { | ||
super(id); | ||
|
||
AutoCompleteSettings autoCompleteSettings = createAutoCompleteSettings(); | ||
|
||
// this has to be copied because the AutoCompleteTextField dies if renderer=null | ||
final AutoCompleteTextField<T> input = new AutoCompleteTextField<T>(ID_INPUT, model, type, renderer, autoCompleteSettings) { | ||
private static final long serialVersionUID = 1L; | ||
|
||
@Override | ||
protected Iterator<T> getChoices(String input) { | ||
return getIterator(input); | ||
} | ||
|
||
@Override | ||
protected void updateAjaxAttributes(AjaxRequestAttributes attributes){ | ||
super.updateAjaxAttributes(attributes); | ||
attributes.setThrottlingSettings(new ThrottlingSettings(Duration.ONE_SECOND, true)); //TODO move to the autocompelete settings | ||
} | ||
|
||
@Override | ||
public <C> IConverter<C> getConverter(Class<C> type) { | ||
IConverter<C> converter = super.getConverter(type); | ||
if (lookupTable == null) { | ||
return converter; | ||
} | ||
|
||
return new LookupTableConverter<>(converter); | ||
|
||
} | ||
}; | ||
|
||
input.setType(type); | ||
if (model instanceof LookupPropertyModel) { | ||
input.add(new OnChangeAjaxBehavior() { | ||
private static final long serialVersionUID = 1L; | ||
|
||
@Override | ||
protected void onUpdate(AjaxRequestTarget target) { | ||
checkInputValue(input, target, (LookupPropertyModel<T>)model); | ||
} | ||
|
||
@Override | ||
protected void updateAjaxAttributes(AjaxRequestAttributes attributes){ | ||
super.updateAjaxAttributes(attributes); | ||
attributes.setThrottlingSettings(new ThrottlingSettings(Duration.ONE_SECOND, true)); | ||
} | ||
}); | ||
} | ||
add(input); | ||
} | ||
|
||
/** | ||
* This method takes care of retrieving an iterator over all | ||
* options that can be completed. The generation of options can be | ||
* affected by using current users input in 'input' variable. | ||
* */ | ||
public abstract Iterator<T> getIterator(String input); | ||
|
||
@Override | ||
public FormComponent<T> getBaseFormComponent() { | ||
return (FormComponent<T>) get(ID_INPUT); | ||
} | ||
|
||
//by default the method will check if AutoCompleteTextField input is empty | ||
// and if yes, set empty value to model. This method is necessary because | ||
// AutoCompleteTextField doesn't set value to model until it is unfocused | ||
public void checkInputValue(AutoCompleteTextField input, AjaxRequestTarget target, LookupPropertyModel model){ | ||
if (input.getInput() == null || input.getInput().trim().equals("")){ | ||
model.setObject(input.getInput()); | ||
} | ||
if (!getIterator(input.getInput()).hasNext()) { | ||
updateFeedbackPanel(input, true, target); | ||
} else { | ||
Iterator<String> lookupTableValuesIterator = (Iterator<String>) getIterator(input.getInput()); | ||
|
||
String value = input.getInput(); | ||
boolean isValueExist = false; | ||
String existingValue = ""; | ||
if (value != null) { | ||
if (value.trim().equals("")) { | ||
isValueExist = true; | ||
} else { | ||
while (lookupTableValuesIterator.hasNext()) { | ||
String lookupTableValue = lookupTableValuesIterator.next(); | ||
if (value.trim().equalsIgnoreCase(lookupTableValue)) { | ||
isValueExist = true; | ||
existingValue = lookupTableValue; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
if (isValueExist) { | ||
input.setModelValue(new String[]{existingValue}); | ||
updateFeedbackPanel(input, false, target); | ||
} else { | ||
updateFeedbackPanel(input, true, target); | ||
} | ||
} | ||
} | ||
|
||
class LookupTableConverter<C> implements IConverter<C> { | ||
|
||
private static final long serialVersionUID = 1L; | ||
IConverter<C> originConverter; | ||
|
||
public LookupTableConverter(IConverter<C> originConverter) { | ||
this.originConverter = originConverter; | ||
} | ||
|
||
@Override | ||
public C convertToObject(String value, Locale locale) throws ConversionException { | ||
for (LookupTableRowType row : lookupTable.getRow()) { | ||
if (value.equals(WebComponentUtil.getLocalizedOrOriginPolyStringValue(row.getLabel() != null ? row.getLabel().toPolyString() : null))) { | ||
return originConverter.convertToObject(row.getKey(), locale); | ||
} | ||
} | ||
boolean differentValue = true; | ||
if (getBaseFormComponent() != null && getBaseFormComponent().getModelObject() != null | ||
&& getBaseFormComponent().getModelObject().equals(value)) { | ||
differentValue = false; | ||
} | ||
|
||
if (differentValue && strict) { | ||
throw new ConversionException("Cannot convert " + value); | ||
} | ||
|
||
return originConverter.convertToObject(value, locale); | ||
|
||
} | ||
|
||
@Override | ||
public String convertToString(C key, Locale arg1) { | ||
if (lookupTable != null) { | ||
for (LookupTableRowType row : lookupTable.getRow()) { | ||
if (key.toString().equals(row.getKey())) { | ||
return WebComponentUtil.getLocalizedOrOriginPolyStringValue(row.getLabel() != null ? row.getLabel().toPolyString() : null); | ||
} | ||
} | ||
} | ||
return key.toString(); | ||
} | ||
} | ||
|
||
protected void updateFeedbackPanel(AutoCompleteTextField input, boolean isError, AjaxRequestTarget target){ | ||
|
||
} | ||
} | ||
|
||
/* | ||
* Copyright (c) 2010-2020 Evolveum and contributors | ||
* | ||
* This work is dual-licensed under the Apache License 2.0 | ||
* and European Union Public License. See LICENSE file for details. | ||
*/ | ||
|
||
package com.evolveum.midpoint.gui.api.component.autocomplete; | ||
|
||
import java.util.Iterator; | ||
import java.util.Locale; | ||
|
||
import org.apache.wicket.ajax.AjaxRequestTarget; | ||
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; | ||
import org.apache.wicket.ajax.attributes.ThrottlingSettings; | ||
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteSettings; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.IAutoCompleteRenderer; | ||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.StringAutoCompleteRenderer; | ||
import org.apache.wicket.markup.html.form.FormComponent; | ||
import org.apache.wicket.model.IModel; | ||
import org.apache.wicket.util.convert.ConversionException; | ||
import org.apache.wicket.util.convert.IConverter; | ||
import org.apache.wicket.util.time.Duration; | ||
|
||
import com.evolveum.midpoint.gui.api.util.WebComponentUtil; | ||
import com.evolveum.midpoint.web.model.LookupPropertyModel; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType; | ||
import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; | ||
|
||
/** | ||
* Autocomplete field for Strings. | ||
* | ||
* TODO: may need some work to properly support non-string values. | ||
* | ||
* @author shood | ||
* @author semancik | ||
* */ | ||
public abstract class AutoCompleteTextPanel<T> extends AbstractAutoCompletePanel { | ||
private static final long serialVersionUID = 1L; | ||
|
||
private static final String ID_INPUT = "input"; | ||
|
||
private LookupTableType lookupTable = null; | ||
private boolean strict; | ||
|
||
// public AutoCompleteTextPanel(String id, final IModel<T> model, Class<T> type) { | ||
// this(id, model, type, StringAutoCompleteRenderer.INSTANCE); | ||
// } | ||
|
||
public AutoCompleteTextPanel(String id, final IModel<T> model, Class<T> type, boolean strict, LookupTableType lookuptable) { | ||
this(id, model, type, StringAutoCompleteRenderer.INSTANCE); | ||
this.lookupTable = lookuptable; | ||
this.strict = strict; | ||
} | ||
|
||
public AutoCompleteTextPanel(String id, final IModel<T> model, Class<T> type, IAutoCompleteRenderer<T> renderer) { | ||
super(id); | ||
|
||
AutoCompleteSettings autoCompleteSettings = createAutoCompleteSettings(); | ||
|
||
// this has to be copied because the AutoCompleteTextField dies if renderer=null | ||
final AutoCompleteTextField<T> input = new AutoCompleteTextField<T>(ID_INPUT, model, type, renderer, autoCompleteSettings) { | ||
private static final long serialVersionUID = 1L; | ||
|
||
@Override | ||
protected Iterator<T> getChoices(String input) { | ||
return getIterator(input); | ||
} | ||
|
||
@Override | ||
protected void updateAjaxAttributes(AjaxRequestAttributes attributes){ | ||
super.updateAjaxAttributes(attributes); | ||
attributes.setThrottlingSettings(new ThrottlingSettings(Duration.ONE_SECOND, true)); //TODO move to the autocompelete settings | ||
} | ||
|
||
@Override | ||
public <C> IConverter<C> getConverter(Class<C> type) { | ||
IConverter<C> converter = super.getConverter(type); | ||
if (lookupTable == null) { | ||
return converter; | ||
} | ||
|
||
return new LookupTableConverter<>(converter, lookupTable, getBaseFormComponent(), strict); | ||
|
||
} | ||
}; | ||
|
||
input.setType(type); | ||
if (model instanceof LookupPropertyModel) { | ||
input.add(new OnChangeAjaxBehavior() { | ||
private static final long serialVersionUID = 1L; | ||
|
||
@Override | ||
protected void onUpdate(AjaxRequestTarget target) { | ||
checkInputValue(input, target, (LookupPropertyModel<T>)model); | ||
} | ||
|
||
@Override | ||
protected void updateAjaxAttributes(AjaxRequestAttributes attributes){ | ||
super.updateAjaxAttributes(attributes); | ||
attributes.setThrottlingSettings(new ThrottlingSettings(Duration.ONE_SECOND, true)); | ||
} | ||
}); | ||
} | ||
add(input); | ||
} | ||
|
||
/** | ||
* This method takes care of retrieving an iterator over all | ||
* options that can be completed. The generation of options can be | ||
* affected by using current users input in 'input' variable. | ||
* */ | ||
public abstract Iterator<T> getIterator(String input); | ||
|
||
@Override | ||
public FormComponent<T> getBaseFormComponent() { | ||
return (FormComponent<T>) get(ID_INPUT); | ||
} | ||
|
||
//by default the method will check if AutoCompleteTextField input is empty | ||
// and if yes, set empty value to model. This method is necessary because | ||
// AutoCompleteTextField doesn't set value to model until it is unfocused | ||
public void checkInputValue(AutoCompleteTextField input, AjaxRequestTarget target, LookupPropertyModel model){ | ||
if (input.getInput() == null || input.getInput().trim().equals("")){ | ||
model.setObject(input.getInput()); | ||
} | ||
if (!getIterator(input.getInput()).hasNext()) { | ||
updateFeedbackPanel(input, true, target); | ||
} else { | ||
Iterator<String> lookupTableValuesIterator = (Iterator<String>) getIterator(input.getInput()); | ||
|
||
String value = input.getInput(); | ||
boolean isValueExist = false; | ||
String existingValue = ""; | ||
if (value != null) { | ||
if (value.trim().equals("")) { | ||
isValueExist = true; | ||
} else { | ||
while (lookupTableValuesIterator.hasNext()) { | ||
String lookupTableValue = lookupTableValuesIterator.next(); | ||
if (value.trim().equalsIgnoreCase(lookupTableValue)) { | ||
isValueExist = true; | ||
existingValue = lookupTableValue; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
if (isValueExist) { | ||
input.setModelValue(new String[]{existingValue}); | ||
updateFeedbackPanel(input, false, target); | ||
} else { | ||
updateFeedbackPanel(input, true, target); | ||
} | ||
} | ||
} | ||
|
||
protected void updateFeedbackPanel(AutoCompleteTextField input, boolean isError, AjaxRequestTarget target){ | ||
|
||
} | ||
} | ||
|
Oops, something went wrong.