📄 formfield.java
字号:
* <a href="FormControl.html#UserValueControl">user value control</a> with the same name.
* This would nearly always indicate an unintentional error in the HTML source document,
* in which case your application can either log a warning that a poorly designed form has been encountered,
* or take special action to try to interpret the multiple user values that might be submitted.
*
* @return the number of constituent <a href="FormControl.html#UserValueControl">user value controls</a> in this field.
*/
public int getUserValueCount() {
return userValueCount;
}
/**
* Returns a collection of the {@linkplain FormControl#getPredefinedValue() predefined values} of all constituent {@linkplain FormControl controls} in this field.
* <p>
* All objects in the returned collection are of type <code>String</code>, with no <code>null</code> entries.
* <p>
* An interator over this collection returns the values in the order of appearance in the source document.
*
* @return a collection of the {@linkplain FormControl#getPredefinedValue() predefined values} of all constituent {@linkplain FormControl controls} in this field, or <code>null</code> if none.
* @see FormControl#getPredefinedValues()
*/
public Collection<String> getPredefinedValues() {
if (predefinedValues==null) return Collections.emptySet();
return predefinedValues;
}
/**
* Returns a list of the <a href="#FieldSubmissionValues">field submission values</a> in order of appearance.
* <p>
* The term <i><a name="FieldSubmissionValues">field submission values</a></i> is used in this library to refer to the aggregate of all the
* <a href="FormControl.html#SubmissionValue">submission values</a> of a field's constituent {@linkplain #getFormControls() form controls}.
* <p>
* All objects in the returned list are of type <code>String</code>, with no <code>null</code> entries.
* <p>
* The list may contain duplicates if the this field has multiple controls with the same value.
*
* @return a list of the <a href="#FieldSubmissionValues">field submission values</a> in order of appearance, guaranteed not <code>null</code>.
*/
public List<String> getValues() {
final List<String> values=new ArrayList<String>();
for (FormControl formControl : formControls) formControl.addValuesTo(values);
return values;
}
/**
* Clears the <a href="FormControl.html#SubmissionValue">submission values</a> of all the constituent {@linkplain #getFormControls() form controls} in this field.
* @see FormControl#clearValues()
*/
public void clearValues() {
for (FormControl formControl : formControls) formControl.clearValues();
}
/**
* Sets the <a href="#FieldSubmissionValues">field submission values</a> of this field to the specified values.
* <p>
* This is equivalent to calling {@link #clearValues()} followed by {@link #addValue(String) addValue(value)} for each
* value in the specified collection.
* <p>
* The specified collection must not contain any <code>null</code> values.
*
* @param values the new <a href="#FieldSubmissionValues">field submission values</a> of this field.
* @see #addValue(String value)
*/
public void setValues(final Collection<String> values) {
clearValues();
addValues(values);
}
/**
* Sets the <a href="#FieldSubmissionValues">field submission values</a> of this field to the single specified value.
* <p>
* This is equivalent to calling {@link #clearValues()} followed by {@link #addValue(String) addValue(value)}.
* <p>
* The return value indicates whether any of the constituent form controls "accepted" the value.
* A return value of <code>false</code> implies an error condition as the specified value is not compatible with this field.
* <p>
* Specifying a <code>null</code> value is equivalent to calling {@link #clearValues()} alone, and always returns <code>true</code>.
* <p>
* See the {@link #addValue(String value)} method for more information.
*
* @param value the new <a href="#FieldSubmissionValues">field submission value</a> of this field, or <code>null</code> to {@linkplain #clearValues() clear} the field of all submission values.
* @return <code>true</code> if one of the constituent {@linkplain #getFormControls() form controls} accepts the value, otherwise <code>false</code>.
* @see FormFields#setValue(String fieldName, String value)
*/
public boolean setValue(final String value) {
clearValues();
return value!=null ? addValue(value) : true;
}
/**
* Adds the specified value to the <a href="#FieldSubmissionValues">field submission values</a> of this field.
* <p>
* This is achieved internally by attempting to {@linkplain FormControl#addValue(String) add the value} to every constituent
* {@linkplain #getFormControls() form control} until one "accepts" it.
* <p>
* The return value indicates whether any of the constituent form controls accepted the value.
* A return value of <code>false</code> implies an error condition as the specified value is not compatible with this field.
* <p>
* In the unusual case that this field consists of multiple form controls, but not all of them are
* <a href="FormControl.html#PredefinedValueControl">predefined value controls</a>, priority is given to the predefined value controls
* before attempting to add the value to the <a href="FormControl.html#UserValueControl">user value controls</a>.
*
* @param value the new <a href="#FieldSubmissionValues">field submission value</a> to add to this field, must not be <code>null</code>.
* @return <code>true</code> if one of the constituent {@linkplain #getFormControls() form controls} accepts the value, otherwise <code>false</code>.
*/
public boolean addValue(final String value) {
if (value==null) throw new IllegalArgumentException("value argument must not be null");
if (formControls.size()==1) return getFirstFormControl().addValue(value);
List<FormControl> userValueControls=null;
for (FormControl formControl : formControls) {
if (!formControl.getFormControlType().hasPredefinedValue()) {
// A user value control has been found, but is not the only control with this name.
// This shouldn't normally happen in a well designed form, but we will save the user value control
// for later and give all predefined value controls first opportunity to take the value.
if (userValueControls==null) userValueControls=new LinkedList<FormControl>();
userValueControls.add(formControl);
continue;
}
if (formControl.addValue(value)) return true; // return value of true from formControl.addValue(value) means the value was taken by the control
}
if (userValueControls==null) return false;
for (FormControl userFormControl : userValueControls) {
if (userFormControl.addValue(value)) return true;
}
return false;
}
/**
* Returns a string representation of this object useful for debugging purposes.
* @return a string representation of this object useful for debugging purposes.
*/
public String getDebugInfo() {
final StringBuilder sb=new StringBuilder();
sb.append("Field: ").append(name).append(", UserValueCount=").append(userValueCount).append(", AllowsMultipleValues=").append(allowsMultipleValues);
if (predefinedValues!=null) {
for (String predefinedValue : predefinedValues) sb.append(Config.NewLine).append("PredefinedValue: ").append(predefinedValue);
}
for (FormControl formControl : formControls) sb.append(Config.NewLine).append("FormControl: ").append(formControl.getDebugInfo());
sb.append(Config.NewLine).append(Config.NewLine);
return sb.toString();
}
/**
* Returns a string representation of this object useful for debugging purposes.
* <p>
* This is equivalent to {@link #getDebugInfo()}.
*
* @return a string representation of this object useful for debugging purposes.
*/
public String toString() {
return getDebugInfo();
}
void addValues(final Collection<String> values) {
if (values!=null) for (String value : values) addValue(value);
}
void addValues(final String[] values) {
if (values!=null) for (String value : values) addValue(value);
}
void addFormControl(final FormControl formControl, final String predefinedValue) {
// predefinedValue==null if we are adding a user value
if (predefinedValue==null) {
userValueCount++;
} else {
if (predefinedValues==null) predefinedValues=new LinkedHashSet<String>();
predefinedValues.add(predefinedValue);
}
formControls.add(formControl);
allowsMultipleValues=calculateAllowsMultipleValues(formControl);
}
private boolean calculateAllowsMultipleValues(final FormControl newFormControl) {
// false if only one control (unless it is a multiple select with more than one option),
// or all of the controls are radio buttons, or all of the controls are submit buttons
if (allowsMultipleValues || userValueCount>1) return true;
if (userValueCount==1) return predefinedValues!=null;
// at this stage we know userValueCount==0 && predefinedValues.size()>=1
if (predefinedValues.size()==1) return false;
final FormControlType newFormControlType=newFormControl.getFormControlType();
if (formControls.size()==1) return newFormControlType==FormControlType.SELECT_MULTIPLE;
// at this stage we know there are multiple predefined values in multiple controls.
// if all of the controls are radio buttons or all are submit buttons, allowsMultipleValues is false, otherwise true.
// checking only the first control and the new control is equivalent to checking them all because if they weren't all
// the same allowsMultipleValues would already be true.
final FormControlType firstFormControlType=getFirstFormControl().getFormControlType();
if (newFormControlType==FormControlType.RADIO && firstFormControlType==FormControlType.RADIO) return false;
if (newFormControlType.isSubmit() && firstFormControlType.isSubmit()) return false;
return true;
}
FormControl getFirstFormControl() {
// formControls must be ordered collection for this method to work.
// It has to return the first FormControl entered into the collection
// for the algorithm in calculateAllowsMultipleValues() to work.
if (firstFormControl==null) firstFormControl=formControls.iterator().next();
return firstFormControl;
}
/** only called from FormFields class */
void merge(final FormField formField) {
if (formField.userValueCount>userValueCount) userValueCount=formField.userValueCount;
allowsMultipleValues=allowsMultipleValues || formField.allowsMultipleValues;
if (predefinedValues==null) {
predefinedValues=formField.predefinedValues;
} else if (formField.predefinedValues!=null) {
for (String predefinedValue : predefinedValues) predefinedValues.add(predefinedValue);
}
for (FormControl formControl : formField.getFormControls()) formControls.add(formControl);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -