I have a Select Many Ordered Shuttle working in a faces page. The tag
documentation contract for the shuttle states:
------------------------------------------
-- JavaScript proxies --
In some cases, developers will need to use JavaScript to manipulate or use the
contents of the lists. This may be required as actions for the buttons or
icons in the shuttle footers or outside the shuttle all together. Thus, a set
of Javascript utility methods are available that operate on the lists. These
are located in the shuttle.js Javascript library, which is automatically loaded
if you use the shuttle.
These methods can be accessed by creating a ShuttleProxy instance based on the
shuttle client ID and form.
// create the proxy object
var proxy2 = new ShuttleProxy("testShuttle2", "testForm2");
Once the proxy is created, you can use it to gain information about the lists
or to manipulate the lists in the shuttle. The proxy provides the following
functions:
...
addItem(leadingList, index, text, value, description) : adds an item at the
given index to a list. The item is added to the leading list if leadingList is
true, otherwise it is added to the trailing list. The index should be 0 based.
Thus, to insert an item at the end of a list, set index to
shuttleProxy.getItemCount(leadinglist). The text parameter specifies the
display text for the item, while the value parameter specifies the value that
represents this item upon form submission. The description parameter specifies
a description of the item. The description parameter can be omitted
....
-------------------------------------------
I have written the JavaScript code to add an item to the shuttle and this works
at the client end; however, when I try and submit the shuttle lists, the server
end fails when it gets to class
org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SelectManyShuttleRenderer
when it is decoding the submitted list in method getSubmittedValue as shown
below:
protected Object getSubmittedValue(
FacesContext context,
UIComponent component,
String clientId)
{
// Since we override getSubmittedValue() entirely,
// detect auto submit manually
detectAutoSubmit(context, component, clientId);
String trailingId = clientId + ":trailing:items";
String paramValue = (String) context.getExternalContext().
getRequestParameterMap().get(trailingId);
if ((paramValue == null) || "".equals(paramValue))
return new String[0];
List<String> list = new ArrayList<String>();
StringTokenizer tokenizer = new StringTokenizer(paramValue, ";");
// don't let the submitted list get any bigger than the number of
// total items in the shuttle
int availableItems = SelectItemSupport.getSelectItemCount(component);
int numItems = 0;
while (tokenizer.hasMoreElements())
{
numItems++;
if (numItems > availableItems)
{
_LOG.severe("SELECTED_SHUTTLE_ITEMS_EXCEEDED_TOTAL_NUMBER", clientId);
return new String[0];
}
list.add(tokenizer.nextToken());
}
The check to confirm that the number of submitted items is not greater than the
original shuttle list already in existence at the server end, stops any user
from adding an additional item to the shuttle. I understand that this may have
been done to protect against an attack where someone sends in a huge list of
shuttle items, BUT this seems to be in direct conflict with the shuttle
contract above that states that I should be able to add one or more items to a
shuttle at the client end. I don't believe the intention was simply to add
items to the shuttle at the client end without submitting it.
I was unable to find any examples, working or otherwise, anywhere that
demonstrate said functionality.
Given the above, if this getSubmittedValue code is correct and the addItem
contract is also correct, how does one add an item to an existing shuttle AND
submit it to the server?
-=> Gregg <=-