/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.formio.props;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.formio.ajax.action.AjaxHandler;
import net.formio.common.heterog.AbstractTypedKey;
import net.formio.common.heterog.HeterogCollections;
import net.formio.common.heterog.HeterogMap;
import net.formio.props.types.ButtonType;
import net.formio.props.types.InlinePosition;
/**
* Common form element properties.
* @author Radek Beran
*/
public class FormElementProperty<T> extends AbstractTypedKey<String, T> implements Property<T> {
private static final long serialVersionUID = 4271239940342562765L;
protected static List<FormElementProperty<Object>> props;
private static final AjaxHandler<?>[] EMPTY_AJAX_HANDLERS = new AjaxHandler<?>[0];
static {
props = new ArrayList<FormElementProperty<Object>>();
}
/** Whether the form element should be visible - rendered at all. */
public static final FormElementProperty<Boolean> VISIBLE = register(new FormElementProperty<Boolean>("visible", Boolean.class, Boolean.TRUE));
/** Whether the form element should be rendered in enabled state. */
public static final FormElementProperty<Boolean> ENABLED = register(new FormElementProperty<Boolean>("enabled", Boolean.class, Boolean.TRUE));
/** Whether the form element should be rendered as read-only. */
public static final FormElementProperty<Boolean> READ_ONLY = register(new FormElementProperty<Boolean>("readonly", Boolean.class, Boolean.FALSE));
/** Help/info for the form element. */
public static final FormElementProperty<String> HELP = register(new FormElementProperty<String>("help", String.class, ""));
/** Whether the first "Choose one" option should be rendered in select. */
public static final FormElementProperty<Boolean> CHOOSE_OPTION_DISPLAYED = register(new FormElementProperty<Boolean>("chooseOptionDisplayed", Boolean.class, Boolean.FALSE));
/** Title for the first "Choose one" option of select. */
public static final FormElementProperty<String> CHOOSE_OPTION_TITLE = register(new FormElementProperty<String>("chooseOptionTitle", String.class, "Choose One"));
/** Placeholder text that will appear (as a hint/label) inside the text field. */
public static final FormElementProperty<String> PLACEHOLDER = register(new FormElementProperty<String>("placeholder", String.class, null));
/** Whether the label of form element is visible. */
public static final FormElementProperty<Boolean> LABEL_VISIBLE = register(new FormElementProperty<Boolean>("labelVisible", Boolean.class, Boolean.TRUE));
/** Whether the form field or mapping is independent on the form object, is not filled, nor bound from request. */
public static final FormElementProperty<Boolean> DETACHED = register(new FormElementProperty<Boolean>("detached", Boolean.class, Boolean.FALSE));
/** Type of inlined form field. */
public static final FormElementProperty<InlinePosition> INLINE = register(new FormElementProperty<InlinePosition>("inline", InlinePosition.class, null));
/** Width of input in number of responsive grid columns. */
public static final FormElementProperty<Integer> COL_INPUT_WIDTH = register(new FormElementProperty<Integer>("colInputWidth", Integer.class, null));
/** Width of label in number of responsive grid columns. */
public static final FormElementProperty<Integer> COL_LABEL_WIDTH = register(new FormElementProperty<Integer>("colLabelWidth", Integer.class, null));
// TDI properties
public static final FormElementProperty<AjaxHandler<?>[]> AJAX_HANDLERS = register(new FormElementProperty<AjaxHandler<?>[]>("ajaxHandlers", (Class<AjaxHandler<?>[]>)EMPTY_AJAX_HANDLERS.getClass(), EMPTY_AJAX_HANDLERS));
public static final FormElementProperty<String> AJAX_RELATED_ELEMENT = register(new FormElementProperty<String>("ajaxRelatedElement", String.class, ""));
public static final FormElementProperty<String> AJAX_SOURCE_ANCESTOR_ELEMENT = register(new FormElementProperty<String>("ajaxSourceAncestorElement", String.class, ""));
// Render hints for which there are no convenience accessors or setters in builders
/** HTML multiple attribute. */
public static final FormElementProperty<Boolean> MULTIPLE = new FormElementProperty<Boolean>("multiple", Boolean.class, Boolean.FALSE);
/** HTML size attribute. */
public static final FormElementProperty<Integer> SIZE = new FormElementProperty<Integer>("size", Integer.class, null);
/** HTML cols attribute for textareas. */
public static final FormElementProperty<Integer> COLS = new FormElementProperty<Integer>("cols", Integer.class, null);
/** HTML rows attribute for textareas. */
public static final FormElementProperty<Integer> ROWS = new FormElementProperty<Integer>("rows", Integer.class, null);
/** HTML maxlength attribute for inputs. */
public static final FormElementProperty<Integer> MAX_LENGTH = new FormElementProperty<Integer>("maxlength", Integer.class, null);
/** MIME types accepted by file upload input. */
public static final FormElementProperty<String> ACCEPT = new FormElementProperty<String>("accept", String.class, null);
/** Type of button: submit, reset or button. */
public static final FormElementProperty<ButtonType> BUTTON_TYPE = new FormElementProperty<ButtonType>("buttonType", ButtonType.class, null);
/** Render surrounding fieldset HTML element. */
public static final FormElementProperty<Boolean> FIELDSET_DISPLAYED = new FormElementProperty<Boolean>("fieldsetDisplayed", Boolean.class, null);
/** Confirmation message that should be confirmed before the form field is activated (e.g. before an AJAX action should be performed).
* Serves for both AJAX and non-AJAX actions. */
public static final FormElementProperty<String> CONFIRM_MESSAGE = new FormElementProperty<String>("confirmMessage", String.class, null);
protected static <T> FormElementProperty<T> register(FormElementProperty<T> prop) {
if (props.contains(prop)) {
throw new IllegalArgumentException("Property with name '" + prop.getName() + "' is already registered.");
}
props.add((FormElementProperty<Object>)prop);
return prop;
}
public static List<FormElementProperty<Object>> getValues() {
return Collections.unmodifiableList(props);
}
public static <T> FormElementProperty<T> fromName(String propName) {
FormElementProperty<T> prop = null;
if (propName != null) {
for (FormElementProperty<Object> p : props) {
if (p.getName().equals(propName)) {
prop = (FormElementProperty<T>)p;
break;
}
}
}
return prop;
}
/**
* Returns new heterogeneous map with default formProperties for form field.
* @return
*/
public static HeterogMap<String> createDefaultProperties() {
HeterogMap<String> propMap = HeterogCollections.<String>newLinkedMap();
for (FormElementProperty<Object> p : props) {
if (p.getDefaultValue() != null) {
propMap.putTyped(p, p.getDefaultValue());
}
}
return propMap;
}
private final T defaultValue;
protected FormElementProperty(String name, Class<T> valueClass, T defaultValue) {
super(name, valueClass);
this.defaultValue = defaultValue;
}
@Override
public String getName() {
return getKey();
}
@Override
public T getDefaultValue() {
return defaultValue;
}
}