MOB-884: Select many control, renders a select list with configurable size (5 by default) and allowing multiple selections

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15086 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2009-07-07 10:38:38 +00:00
parent fc3a3f2a49
commit 47f34d0c10
3 changed files with 152 additions and 22 deletions

View File

@@ -25,8 +25,10 @@
package org.alfresco.repo.forms; package org.alfresco.repo.forms;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -77,16 +79,69 @@ public class FormData implements Iterable<FormData.FieldData>
/** /**
* Adds the given data to the form. * Adds the given data to the form.
* If data for the given field is already present it will be * <p>
* overwritten. * NOTE: Adding the same named data will append the value and
* thereafter return a List containing all added values.
* </p>
* *
* @param fieldName The name of the field * @param fieldName The name of the field
* @param fieldValue The value of the data * @param fieldValue The value of the data
*/ */
public void addFieldData(String fieldName, Object fieldValue) public void addFieldData(String fieldName, Object fieldValue)
{ {
FieldData item = new FieldData(fieldName, fieldValue, false); this.addFieldData(fieldName, fieldValue, false);
this.data.put(fieldName, item); }
/**
* Adds the given data to the form. If data for the field is already
* present the behaviour is controlled by the overwrite property.
* <p>
* If overwrite is true the provided value replaces the existing value
* whereas false will force the creation of a List (if necessary) and the
* provided value will be added to the List.
* </p>
*
* @param fieldName The name of the field
* @param fieldValue The value of the data
* @param overwrite
*/
@SuppressWarnings("unchecked")
public void addFieldData(String fieldName, Object fieldValue, boolean overwrite)
{
// check whether some data already exists
if (this.data.containsKey(fieldName))
{
// if we are overwriting just replace with provided data
if (overwrite)
{
this.data.put(fieldName, new FieldData(fieldName, fieldValue, false));
}
else
{
// pull out the existing value and create a List if necessary
List currentValues = null;
Object currentValue = this.data.get(fieldName).getValue();
if (currentValue instanceof List)
{
currentValues = (List)currentValue;
}
else
{
// a non List value is present, create the new list
// and add the current value to it
currentValues = new ArrayList(4);
currentValues.add(currentValue);
this.data.put(fieldName, new FieldData(fieldName, currentValues, false));
}
// add the provided value to the list
currentValues.add(fieldValue);
}
}
else
{
this.data.put(fieldName, new FieldData(fieldName, fieldValue, false));
}
} }
/** /**

View File

@@ -993,6 +993,45 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
} }
} }
@SuppressWarnings("unchecked")
public void testFormData() throws Exception
{
FormData formData = new FormData();
// test single value goes in and comes out successfully
formData.addFieldData("singleValue", "one");
assertEquals("Expecting value of 'one'", "one", formData.getFieldData("singleValue").getValue());
// test adding multiple values to the same field
formData.addFieldData("multipleValues", "one");
Object value = formData.getFieldData("multipleValues").getValue();
assertTrue("Expecting 'multipleValues' to be a String object", (value instanceof String));
formData.addFieldData("multipleValues", "two");
value = formData.getFieldData("multipleValues").getValue();
assertTrue("Expecting 'multipleValues' to be a List object", (value instanceof List));
formData.addFieldData("multipleValues", "three");
List list = (List)formData.getFieldData("multipleValues").getValue();
assertEquals("Expecting 'multipleValues' List to have 3 items", 3, list.size());
// add a List initially then add a value to it
formData.addFieldData("listValue", new ArrayList());
formData.addFieldData("listValue", "one");
formData.addFieldData("listValue", "two");
list = (List)formData.getFieldData("listValue").getValue();
assertEquals("Expecting 'listValue' List to have 2 items", 2, list.size());
// test overwrite parameter
formData.addFieldData("overwritten", "one", true);
formData.addFieldData("overwritten", "two", true);
formData.addFieldData("overwritten", "three", true);
value = formData.getFieldData("overwritten").getValue();
assertTrue("Expecting 'overwritten' to be a String object", (value instanceof String));
assertEquals("Expecting 'overwritten' value to be 'three'", "three", value);
}
public void testJavascriptAPI() throws Exception public void testJavascriptAPI() throws Exception
{ {
Map<String, Object> model = new HashMap<String, Object>(); Map<String, Object> model = new HashMap<String, Object>();

View File

@@ -72,6 +72,8 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
/** /**
* FormProcessor implementation that can generate and persist Form objects * FormProcessor implementation that can generate and persist Form objects
@@ -991,29 +993,53 @@ public class NodeFormProcessor extends FilteredFormProcessor
Object value = fieldData.getValue(); Object value = fieldData.getValue();
// before persisting check data type of property // before persisting check data type of property
if ((value instanceof String) && ((String)value).length() == 0) if (propDef.isMultiValued())
{ {
// make sure empty strings stay as empty strings, everything else // depending on client the value could be a comma separated
// should be represented as null // string, a List object or a JSONArray object
if (!propDef.getDataType().getName().equals(DataTypeDefinition.TEXT) && if (value instanceof String)
!propDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
{ {
value = null; if (((String)value).length() == 0)
{
// empty string for multi-valued properties
// should be stored as null
value = null;
}
else
{
// if value is a String convert to List of String
StringTokenizer tokenizer = new StringTokenizer((String)value, ",");
List<String> list = new ArrayList<String>(8);
while (tokenizer.hasMoreTokens())
{
list.add(tokenizer.nextToken());
}
// persist the List
value = list;
}
} }
} else if (value instanceof JSONArray)
else if (propDef.isMultiValued())
{
// currently we expect comma separated lists to represent
// the values of a multi valued property, change into List
StringTokenizer tokenizer = new StringTokenizer((String)value, ",");
List<String> list = new ArrayList<String>(8);
while (tokenizer.hasMoreTokens())
{ {
list.add(tokenizer.nextToken()); // if value is a JSONArray convert to List of Object
JSONArray jsonArr = (JSONArray)value;
int arrLength = jsonArr.length();
List<Object> list = new ArrayList<Object>(arrLength);
try
{
for (int x = 0; x < arrLength; x++)
{
list.add(jsonArr.get(x));
}
}
catch (JSONException je)
{
throw new FormException("Failed to convert JSONArray to List", je);
}
// persist the list
value = list;
} }
// persist the List
value = list;
} }
else if (propDef.getDataType().getName().equals(DataTypeDefinition.BOOLEAN)) else if (propDef.getDataType().getName().equals(DataTypeDefinition.BOOLEAN))
{ {
@@ -1027,6 +1053,16 @@ public class NodeFormProcessor extends FilteredFormProcessor
{ {
value = I18NUtil.parseLocale((String)value); value = I18NUtil.parseLocale((String)value);
} }
else if ((value instanceof String) && ((String)value).length() == 0)
{
// make sure empty strings stay as empty strings, everything else
// should be represented as null
if (!propDef.getDataType().getName().equals(DataTypeDefinition.TEXT) &&
!propDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
{
value = null;
}
}
// add the property to the map // add the property to the map
propsToPersist.put(fullQName, (Serializable)value); propsToPersist.put(fullQName, (Serializable)value);