UIMultiValueSelection.java
package org.exoplatform.social.user.form;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.social.user.portlet.UserProfileHelper;
import org.exoplatform.social.webui.profile.settings.UIValueControl;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIComponent;
import org.exoplatform.webui.core.lifecycle.UIContainerLifecycle;
import org.exoplatform.webui.core.model.SelectItemOption;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.Event.Phase;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.form.UIForm;
import org.exoplatform.webui.form.UIFormInputSet;
import org.exoplatform.webui.form.UIFormSelectBox;
import org.exoplatform.webui.form.UIFormStringInput;
import org.exoplatform.webui.form.validator.SpecialCharacterValidator;
import org.exoplatform.webui.form.validator.Validator;
@ComponentConfig(
lifecycle = UIContainerLifecycle.class,
events = {
@EventConfig(listeners = UIMultiValueSelection.AddValueActionListener.class, phase = Phase.DECODE),
@EventConfig(listeners = UIMultiValueSelection.RemoveValueActionListener.class, phase = Phase.DECODE)
}
)
public class UIMultiValueSelection extends UIFormInputSet {
public static final String FIELD_SELECT_KEY = "selectKey_";
public static final String FIELD_INPUT_KEY = "inputKey_";
private static final Log LOG = ExoLogger.getExoLogger(UIMultiValueSelection.class);
protected List<Validator> validators;
private List<Map<String, String>> values;
private List<Integer> indexs = new LinkedList<Integer>();
private List<String> optionValues = new ArrayList<String>();
/** The option renderer. */
private UIValueControl valueControl;
public UIMultiValueSelection() {
}
public UIMultiValueSelection(String name) {
super(name);
}
public UIMultiValueSelection(String name, String uiFormId, List<String> options) {
super(name);
setComponentConfig(getClass(), null);
//
this.optionValues = options;
}
/**
* Adds value's custom UI control.
*
* @param valueControl the UI value control invoker
* @return this {@link UIMultiValueSelection} instance
*/
public UIMultiValueSelection withValueControl(UIValueControl valueControl) {
this.valueControl = valueControl;
return this;
}
public <E extends Validator> UIMultiValueSelection addValidator(Class<E> clazz, Object... params) throws Exception {
if (validators == null)
validators = new ArrayList<Validator>(3);
if (params.length > 0) {
Class<?>[] classes = new Class[params.length];
for (int i = 0; i < params.length; i++) {
classes[i] = params[i].getClass();
}
Constructor<E> constructor = clazz.getConstructor(classes);
validators.add(constructor.newInstance(params));
return this;
}
validators.add(clazz.newInstance());
return this;
}
public List<Validator> getValidators() {
return validators;
}
private List<SelectItemOption<String>> getOptions() {
String uiFormId = getAncestorOfType(UIForm.class).getId();
List<SelectItemOption<String>> options = new ArrayList<SelectItemOption<String>>();
if (optionValues != null) {
for (String option : optionValues) {
options.add(new SelectItemOption<String>(UserProfileHelper.getLabel(null, uiFormId + ".label." + option), option));
}
}
return options;
}
private String getSelected(String key) {
if (optionValues == null) {
optionValues = new ArrayList<String>();
}
if (optionValues.contains(key)) {
return key;
}
optionValues.add(key);
//
return "";
}
public UIMultiValueSelection setValues(List<Map<String, String>> values) {
this.values = values;
//
try {
//
removeChildren();
//
int index = 0;
if (values != null && !values.isEmpty()) {
for (Map<String, String> map : values) {
String key = map.get("key");
String value = map.get("value");
//
addInput(index, getSelected(key), value);
//
++index;
}
} else {
addInput(index, "", "");
}
} catch (Exception e) {
LOG.warn("Failed to set values for " + getId(), e);
}
return this;
}
private String getInputValue(int indexId) {
return getUIStringInput(getInputId(indexId)).getValue();
}
private String getInputKey(int indexId) {
return getUIFormSelectBox(getSelectId(indexId)).getValue();
}
public List<Map<String, String>> getValues() {
this.values = new ArrayList<Map<String, String>>();
for (Integer indexId : indexs) {
String value = getInputValue(indexId);
if (StringUtils.isNotBlank(value)) {
Map<String, String> map = new HashMap<String, String>();
map.put("key", getInputKey(indexId));
map.put("value", value);
values.add(map);
}
}
return this.values;
}
private String getSelectId(int index) {
return new StringBuilder(FIELD_SELECT_KEY).append(getId()).append(index).toString();
}
private String getInputId(int index) {
return new StringBuilder(FIELD_INPUT_KEY).append(getId()).append(index).toString();
}
private void addInput(int indexId, String selected, String value) throws Exception {
//
int index = indexId;
if (indexs.contains(Integer.valueOf(indexId))) {
index = indexs.indexOf(indexId) + 1;
indexId = index * 10;
}
((LinkedList<Integer>) indexs).add(index, indexId);
//
addUIFormInput(new UIFormSelectBox(getSelectId(indexId), getSelectId(indexId), getOptions()).setValue(selected));
//
UIFormStringInput stringInput = new UIFormStringInput(getInputId(indexId), getInputId(indexId), value);
stringInput.setHTMLAttribute("class", "selectInput");
if (validators != null && !validators.isEmpty()) {
stringInput.addValidator(SpecialCharacterValidator.class);
List<Validator> validators_ = stringInput.getValidators();
validators_.clear();
validators_.addAll(validators);
}
stringInput.setLabel(this.getId());
addUIFormInput(stringInput);
}
private void removeChildren() {
getChildren().clear();
indexs.clear();
}
public void processDecode(WebuiRequestContext context) throws Exception {
super.processDecode(context);
UIForm uiForm = getAncestorOfType(UIForm.class);
//
String indexId = context.getRequestParameter(OBJECTID);
if (indexId == null || !indexId.contains(getId())) {
return;
}
String action = uiForm.getSubmitAction();
Event<UIComponent> event = createEvent(action, Event.Phase.DECODE, context);
if (event == null)
return;
event.broadcast();
}
public void processRender(WebuiRequestContext context) throws Exception {
if (indexs.isEmpty()) {
setValues(null);
}
UIForm uiForm = getAncestorOfType(UIForm.class);
String addItem = UserProfileHelper.getLabel(context, "UIFormMultiValueInputSet.label.add");
String removeItem = UserProfileHelper.getLabel(context, "UIFormMultiValueInputSet.label.remove");
context.getJavascriptManager().require("SHARED/jquery", "jq").require("SHARED/bts_tooltip")
.addScripts("jq('.uiMulti-select').find('a[rel=\"tooltip\"]').tooltip();");
//
Writer w = context.getWriter();
w.append("<div class=\"uiMulti-select\" id=\"").append(getId()).append("\">") ;
int i = 0;
for (Integer indexId : indexs) {
w.append("<div class=\"controls-row\">") ;
UIFormSelectBox select = getUIFormSelectBox(getSelectId(indexId));
renderUIComponent(select);
UIFormStringInput input = getUIStringInput(getInputId(indexId));
renderUIComponent(input);
if(indexs.size() > 1) {
// remove
w.append("<a class=\"actionIcon\" data-placement=\"bottom\" rel=\"tooltip\" title=\"\" data-original-title=\"").append(removeItem)
.append("\" href=\"javascript:void(0)\" onclick=\"").append(uiForm.event("RemoveValue", getId() + String.valueOf(indexId)))
.append("\"><i class=\"uiIconClose uiIconLightGray\"></i></a>");
}
if (valueControl != null) {
// Optional: IM account management control, it will appear after "remove" icon if such one added above
valueControl.render(select.getValue(), input.getValue(), context);
}
if(i == indexs.size() - 1) {
// add
w.append("<a class=\"actionIcon\" data-placement=\"bottom\" rel=\"tooltip\" title=\"\" data-original-title=\"").append(addItem)
.append("\" href=\"javascript:void(0)\" onclick=\"").append(uiForm.event("AddValue", getId() + String.valueOf(indexId)))
.append("\"><i class=\"uiIconPlus uiIconLightGray\"></i></a>");
}
w.append("</div>");
++i;
}
if (this.isMandatory())
w.write(" *");
w.write("</div>");
}
private boolean isMandatory() {
return false;
}
static public class AddValueActionListener extends EventListener<UIMultiValueSelection> {
public void execute(Event<UIMultiValueSelection> event) throws Exception {
UIMultiValueSelection uiSelection = event.getSource();
String indexId = event.getRequestContext().getRequestParameter(OBJECTID);
indexId = indexId.replace(uiSelection.getId(), "");
uiSelection.addInput(Integer.valueOf(indexId.trim()), "", "");
event.getRequestContext().addUIComponentToUpdateByAjax(uiSelection);
}
}
static public class RemoveValueActionListener extends EventListener<UIMultiValueSelection> {
public void execute(Event<UIMultiValueSelection> event) throws Exception {
UIMultiValueSelection uiSelection = event.getSource();
String indexId = event.getRequestContext().getRequestParameter(OBJECTID);
indexId = indexId.replace(uiSelection.getId(), "");
if(uiSelection.indexs.contains(Integer.valueOf(indexId))) {
uiSelection.removeChildById(uiSelection.getSelectId(Integer.valueOf(indexId)));
uiSelection.removeChildById(uiSelection.getInputId(Integer.valueOf(indexId)));
uiSelection.indexs.remove(Integer.valueOf(indexId));
}
event.getRequestContext().addUIComponentToUpdateByAjax(uiSelection);
}
}
}