[richfaces-svn-commits] JBoss Rich Faces SVN: r5042 - in trunk/sandbox/ui: pickList and 17 other directories.

richfaces-svn-commits at lists.jboss.org richfaces-svn-commits at lists.jboss.org
Thu Dec 27 13:32:54 EST 2007


Author: abelevich
Date: 2007-12-27 13:32:54 -0500 (Thu, 27 Dec 2007)
New Revision: 5042

Added:
   trunk/sandbox/ui/pickList/
   trunk/sandbox/ui/pickList/src/
   trunk/sandbox/ui/pickList/src/main/
   trunk/sandbox/ui/pickList/src/main/config/
   trunk/sandbox/ui/pickList/src/main/config/component/
   trunk/sandbox/ui/pickList/src/main/config/component/picklist.xml
   trunk/sandbox/ui/pickList/src/main/java/
   trunk/sandbox/ui/pickList/src/main/java/org/
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/component/
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/component/UIPickList.java
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/picklist/
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/picklist/util/
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/picklist/util/PickListUtils.java
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/renderkit/
   trunk/sandbox/ui/pickList/src/main/java/org/richfaces/renderkit/PickListRenderer.java
   trunk/sandbox/ui/pickList/src/main/resources/
   trunk/sandbox/ui/pickList/src/main/resources/org/
   trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/
   trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/renderkit/
   trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/renderkit/html/
   trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/renderkit/html/scripts/
   trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/renderkit/html/scripts/picklist.js
Log:
initial commit 

Added: trunk/sandbox/ui/pickList/src/main/config/component/picklist.xml
===================================================================
--- trunk/sandbox/ui/pickList/src/main/config/component/picklist.xml	                        (rev 0)
+++ trunk/sandbox/ui/pickList/src/main/config/component/picklist.xml	2007-12-27 18:32:54 UTC (rev 5042)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"  "https://ajax4jsf.dev.java.net/nonav/dtds/component-config.dtd" >
+<components>
+    <component>
+        <name>org.richfaces.PickList</name>
+        <family>org.richfaces.PickList</family>
+        <classname>
+            org.richfaces.component.html.HtmlPickList
+        </classname>
+        <superclass>org.richfaces.component.UIPickList</superclass>
+		<test>
+			<classname>org.richfaces.component.html.HtmlPickListComponentTest</classname>
+			<superclassname>org.ajax4jsf.tests.AbstractAjax4JsfTestCase</superclassname>
+		</test>
+        <description>
+            <![CDATA[  ]]>
+        </description>
+		<renderer  generate="false" override="false">
+			<name>org.richfaces.PickList</name>
+			<classname>org.richfaces.renderkit.PickListRenderer</classname>
+		</renderer>
+       	
+       	<tag>
+       		<name>pickList</name>
+            <classname>org.richfaces.taglib.PickListTag</classname>
+            <superclass>
+				org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
+			</superclass>
+       	</tag>
+       	
+       	<properties>
+       		<property>
+       			<name>displayValueOnly</name>
+       			<classname>boolean</classname>
+       			<defaultvalue>false</defaultvalue>
+       		</property>       	
+       		<property>
+       			<name>displayValueOnlyStyle</name>
+       			<classname>java.lang.String</classname>
+       			<defaultvalue>""</defaultvalue>
+       		</property>
+       		<property>
+       			<name>displayValueOnlyStyleClass</name>
+       			<classname>java.lang.String</classname>
+       			<defaultvalue>""</defaultvalue>
+       		</property>
+       		<property>
+       			<name>size</name>
+       			<classname>int</classname>
+       		</property>
+       		<property hidden="true">
+       			<name>selectedValues</name>
+       			<classname>java.lang.Object</classname>
+       		</property>
+       		
+       	</properties>
+       
+    </component>
+</components>

Added: trunk/sandbox/ui/pickList/src/main/java/org/richfaces/component/UIPickList.java
===================================================================
--- trunk/sandbox/ui/pickList/src/main/java/org/richfaces/component/UIPickList.java	                        (rev 0)
+++ trunk/sandbox/ui/pickList/src/main/java/org/richfaces/component/UIPickList.java	2007-12-27 18:32:54 UTC (rev 5042)
@@ -0,0 +1,35 @@
+package org.richfaces.component;
+
+import javax.faces.component.UISelectMany;
+import javax.faces.context.FacesContext;
+
+public abstract class UIPickList extends UISelectMany{
+
+	@Override
+	public String getClientId(FacesContext context) {
+		//TODO forceId?	
+		return super.getClientId(context);
+	}
+	
+	@Override
+	public boolean isRendered() {
+		// TODO userRoles?
+		return super.isRendered();
+	}
+	
+	public abstract boolean isDisplayValueOnly();
+	public abstract void setDisplayValueOnly(boolean displayValueOnly);
+	 
+	public abstract String getDisplayValueOnlyStyle();
+	public abstract void setDisplayValueOnlyStyle(String style);
+		
+	public abstract String getDisplayValueOnlyStyleClass();
+	public abstract void setDisplayValueOnlyStyleClass(String styleClass);
+	 
+	public abstract int getSize();
+	public abstract void setSize(int size);
+	
+	public abstract boolean isDisabled();
+	public abstract void setDisabled(boolean disabled);
+	
+}

Added: trunk/sandbox/ui/pickList/src/main/java/org/richfaces/picklist/util/PickListUtils.java
===================================================================
--- trunk/sandbox/ui/pickList/src/main/java/org/richfaces/picklist/util/PickListUtils.java	                        (rev 0)
+++ trunk/sandbox/ui/pickList/src/main/java/org/richfaces/picklist/util/PickListUtils.java	2007-12-27 18:32:54 UTC (rev 5042)
@@ -0,0 +1,281 @@
+package org.richfaces.picklist.util;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UISelectMany;
+import javax.faces.component.UISelectOne;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.el.ValueBinding;
+import javax.faces.model.SelectItem;
+
+import org.ajax4jsf.util.SelectUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+
+
+
+public class PickListUtils {
+	 
+	private static final Log log = LogFactory.getLog(PickListUtils.class);
+	public static final Object NOTHING = new Serializable() {};
+
+	public static Converter findUISelectManyConverter(FacesContext context, UISelectMany component) {
+		
+		Converter converter = component.getConverter();
+		 
+		if (converter != null) return converter;
+		 //Try to find out by value binding
+		ValueBinding vb = component.getValueBinding("value");
+		if (vb == null) return null;
+
+		Class valueType = vb.getType(context);
+		if (valueType == null) return null;
+
+		if (List.class.isAssignableFrom(valueType)) {
+			List selectItems = SelectUtils.getSelectItems(context, component);
+
+			if (selectItems != null && selectItems.size() > 0) {
+				SelectItem selectItem = (SelectItem) selectItems.get(0);
+				Class listComponentType = selectItem.getValue().getClass();
+	
+				if (!(String.class.equals(listComponentType))) {
+					try {
+						return context.getApplication().createConverter(listComponentType);
+					}
+					catch (FacesException e) {
+						log.error("No Converter for type " + listComponentType.getName() + " found", e);
+						return null;
+					}
+				}
+			}
+
+			return null;
+		}
+
+		if (!valueType.isArray()) {
+			throw new IllegalArgumentException("ValueBinding for UISelectMany :  must be of type List or Array");
+		}	
+
+		Class arrayComponentType = valueType.getComponentType();
+		if (String.class.equals(arrayComponentType)) return null;    //No converter needed for String type
+		if (Object.class.equals(arrayComponentType)) return null;    //There is no converter for Object class
+
+		try {
+			return context.getApplication().createConverter(arrayComponentType);
+		} catch (FacesException e) {
+			log.error("No Converter for type " + arrayComponentType.getName() + " found", e);
+			return null;
+		}
+	}	
+	
+	public static Converter findUISelectManyConverterFailsafe(FacesContext facesContext, UIComponent uiComponent) {
+        Converter converter;
+        try {
+            converter = findUISelectManyConverter(
+                facesContext, (UISelectMany) uiComponent);
+        }
+        catch (FacesException e) {
+            log.error("Error finding Converter for component with id "
+                + uiComponent.getClientId(facesContext), e);
+            converter = null;
+        }
+        return converter;
+    }
+	
+	public static Set getSubmittedOrSelectedValuesAsSet(boolean selectMany, UIComponent uiComponent, FacesContext facesContext, Converter converter) {
+        Set lookupSet;
+
+        if (selectMany) {
+            UISelectMany uiSelectMany = (UISelectMany) uiComponent;
+            lookupSet = getSubmittedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
+            if (lookupSet == null) {
+                lookupSet = getSelectedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
+            }
+        }
+        else {
+            UISelectOne uiSelectOne = (UISelectOne) uiComponent;
+            Object lookup = uiSelectOne.getSubmittedValue();
+            if (lookup == null) {
+                lookup = uiSelectOne.getValue();
+                String lookupString = getConvertedStringValue(facesContext, uiComponent, converter, lookup);
+                lookupSet = Collections.singleton(lookupString);
+            }
+            else if (NOTHING.equals(lookup)) {
+                lookupSet = Collections.EMPTY_SET;
+            }
+            else {
+                lookupSet = Collections.singleton(lookup);
+            }
+        }
+        return lookupSet;
+    }
+	
+	public static Set getSubmittedValuesAsSet(FacesContext context, UIComponent component, Converter converter, UISelectMany uiSelectMany) {
+        Object submittedValues = uiSelectMany.getSubmittedValue();
+        if (submittedValues == null) {
+            return null;
+        }
+        
+        if(converter != null) {
+            converter = new PassThroughAsStringConverter(converter);
+        }
+
+        return internalSubmittedOrSelectedValuesAsSet(context, component, converter, uiSelectMany, submittedValues);
+    }
+	
+	private static class PassThroughAsStringConverter implements Converter {
+	        private final Converter converter;
+
+	        public PassThroughAsStringConverter(Converter converter) {
+	            this.converter = converter;
+	        }
+
+	        public Object getAsObject(FacesContext context, UIComponent component,
+	                String value) throws ConverterException {
+	            return converter.getAsObject(context, component, value);
+	        }
+
+	        public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException {
+	            return (String)value;
+	        }
+
+	}
+	  
+	  public static Set getSelectedValuesAsSet(FacesContext context, UIComponent component, Converter converter, UISelectMany uiSelectMany) {
+	        Object selectedValues = uiSelectMany.getValue();
+	        return internalSubmittedOrSelectedValuesAsSet(context, component, converter, uiSelectMany, selectedValues);
+	   }
+	  
+	  private static Set internalSubmittedOrSelectedValuesAsSet(FacesContext context, UIComponent component, Converter converter, UISelectMany uiSelectMany,Object values) {
+		
+		  if (values == null || "".equals(values)) {
+			  return Collections.EMPTY_SET;
+		  } else if (values instanceof Object[]) {
+			//Object array
+			  Object[] ar = (Object[]) values;
+			  if (ar.length == 0) {
+				  return Collections.EMPTY_SET;
+			  }
+		
+			  HashSet set = new HashSet(calcCapacity(ar.length));
+			  for (int i = 0; i < ar.length; i++) {
+				  set.add(getConvertedStringValue(context, component, converter, ar[i]));
+			  }
+			  return set;
+		  } else if (values.getClass().isArray()) {
+			  //primitive array
+			  int len = Array.getLength(values);
+			  HashSet set = new HashSet(calcCapacity(len));
+			  for (int i = 0; i < len; i++) {
+				  set.add(getConvertedStringValue(context, component, converter, Array.get(values, i)));
+			  }
+			  return set;
+		  }	else if (values instanceof List) {
+			  List lst = (List) values;
+			  if (lst.size() == 0) {
+				  return Collections.EMPTY_SET;
+			  } else {
+				  HashSet set = new HashSet(calcCapacity(lst.size()));
+				  for (Iterator i = lst.iterator(); i.hasNext();) {
+					  set.add(getConvertedStringValue(context, component, converter, i.next()));
+				  }	   
+				  return set;
+			  }
+		  } else {
+			  throw new IllegalArgumentException("Value of UISelectMany component : is not of type Array or List");
+		  }
+	  }
+		
+	  public static final int calcCapacity(int size) {
+		  return ((size * 4) + 3) / 3;
+	  }
+	  
+	  public static String getConvertedStringValue(FacesContext context, UIComponent component, Converter converter, Object value) {
+			if (converter == null) {
+				if (value == null) {
+					return "";
+				} else if (value instanceof String) {
+					return (String) value;
+				} else {
+					throw new IllegalArgumentException(
+							"Value is not String (class=" + value.getClass().getName() + ", value=" + value + ") and component "
+							+ component.getClientId(context) + " does not have a Converter");
+				}
+			}
+			
+			return converter.getAsString(context, component, value);
+	  }
+//	  public static boolean renderHTMLAttributes(ResponseWriter writer,
+//              UIComponent component, String[] attributes) throws IOException {
+//		boolean somethingDone = false;
+//		for (int i = 0, len = attributes.length; i < len; i++) {
+//		String attrName = attributes[i];
+//		if (renderHTMLAttribute(writer, component, attrName, attrName)) {
+//		somethingDone = true;
+//		}
+//		}
+//		return somethingDone;
+//	  } 
+//	  
+//	  public static boolean renderHTMLAttribute(ResponseWriter writer,
+//              UIComponent component, String componentProperty, String htmlAttrName) throws IOException {
+//			Object value = component.getAttributes().get(componentProperty);
+//			return renderHTMLAttribute(writer, componentProperty, htmlAttrName, value);
+//	  }
+//	  
+//	  public static boolean renderHTMLAttribute(ResponseWriter writer,
+//              String componentProperty, String attrName, Object value) throws IOException {
+//			if (!isDefaultAttributeValue(value)) {
+//			// render JSF "styleClass" and "itemStyleClass" attributes as "class"
+//			String htmlAttrName =
+//			attrName.equals("styleClass") ? "class" : attrName;
+//			writer.writeAttribute(htmlAttrName, value, componentProperty);
+//			return true;
+//			}
+//			
+//			return false;
+//	  }
+//	  
+//	  public static boolean isDefaultAttributeValue(Object value) {
+//	        if (value == null) {
+//	            return true;
+//	        }
+//	        else if (value instanceof Boolean) {
+//	            return !((Boolean) value).booleanValue();
+//	        }
+//	        else if (value instanceof Number) {
+//	            if (value instanceof Integer) {
+//	                return ((Number) value).intValue() == Integer.MIN_VALUE;
+//	            }
+//	            else if (value instanceof Double) {
+//	                return ((Number) value).doubleValue() == Double.MIN_VALUE;
+//	            }
+//	            else if (value instanceof Long) {
+//	                return ((Number) value).longValue() == Long.MIN_VALUE;
+//	            }
+//	            else if (value instanceof Byte) {
+//	                return ((Number) value).byteValue() == Byte.MIN_VALUE;
+//	            }
+//	            else if (value instanceof Float) {
+//	                return ((Number) value).floatValue() == Float.MIN_VALUE;
+//	            }
+//	            else if (value instanceof Short) {
+//	                return ((Number) value).shortValue() == Short.MIN_VALUE;
+//	            }
+//	        }
+//	        return false;
+//	   }
+
+}

Added: trunk/sandbox/ui/pickList/src/main/java/org/richfaces/renderkit/PickListRenderer.java
===================================================================
--- trunk/sandbox/ui/pickList/src/main/java/org/richfaces/renderkit/PickListRenderer.java	                        (rev 0)
+++ trunk/sandbox/ui/pickList/src/main/java/org/richfaces/renderkit/PickListRenderer.java	2007-12-27 18:32:54 UTC (rev 5042)
@@ -0,0 +1,238 @@
+package org.richfaces.renderkit;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+import javax.faces.model.SelectItem;
+import javax.faces.model.SelectItemGroup;
+
+import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+import org.ajax4jsf.resource.InternetResource;
+import org.ajax4jsf.util.SelectUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.richfaces.component.UIPickList;
+import org.richfaces.picklist.util.PickListUtils;
+
+public class PickListRenderer extends HeaderResourcesRendererBase {
+	
+	private static final String AVAILABLE_SUFFIX = "_AVAILABLE";
+	private static final String SELECTED_SUFFIX = "_SELECTED";
+	private static final String HIDDEN_SUFFIX = "_HIDDEN";
+	private static final String FUNCTION_ADD_TO_SELECTED = "myfaces_picklist_addToSelected";
+    private static final String FUNCTION_REMOVE_FROM_SELECTED = "myfaces_picklist_removeFromSelected";
+    private final InternetResource[] scripts = {getResource("/org/richfaces/renderkit/html/scripts/picklist.js")};
+  
+
+    protected InternetResource[] getScripts() {
+    	return scripts;
+    }
+    
+    protected List selectItemsForSelectedList(FacesContext facesContext,UIComponent uiComponent, List selectItemList, Converter converter, Set lookupSet) {
+		List selectItemForSelectedValues = new ArrayList(lookupSet.size());
+		for (Iterator i = selectItemList.iterator(); i.hasNext();) {
+			SelectItem selectItem = (SelectItem) i.next();
+			String itemStrValue = PickListUtils.getConvertedStringValue(facesContext, uiComponent,converter, selectItem.getValue());
+			for (Iterator i2 = lookupSet.iterator(); i2.hasNext();) {
+				Object value = i2.next();
+				if (value.equals(itemStrValue)) {
+					selectItemForSelectedValues.add(selectItem);
+				}
+			}
+		}
+		return selectItemForSelectedValues;
+	}
+
+	protected List selectItemsForAvailableList(FacesContext facesContext, UIComponent uiComponent, List selectItemList, List selectItemsForSelectedList, Converter converter) {
+		return new ArrayList(CollectionUtils.subtract(selectItemList, selectItemsForSelectedList));
+	}
+	 
+	protected List getSelectItemsList(FacesContext context,UIComponent component) {
+		return SelectUtils.getSelectItems(context, component);
+	}
+	
+	private void encodeSelect(FacesContext facesContext, UIComponent uiComponent, String clientId, boolean disabled,
+	             		int size, List selectItemsToDisplay, Converter converter, ResponseWriter writer) throws IOException {
+	
+		writer.startElement("select", uiComponent);
+		writer.writeAttribute("id", clientId, "id");
+		writer.writeAttribute("name", clientId, null);
+		writer.writeAttribute("multiple", "true", null);
+	
+		if (size == 0) {
+			writer.writeAttribute("size", Integer.toString(selectItemsToDisplay.size()), null);
+		} else {
+			writer.writeAttribute("size", Integer.toString(size), null);
+		}
+		if (disabled) {
+			writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
+		}
+	
+		renderSelectOptions(facesContext, uiComponent, converter, Collections.EMPTY_SET, selectItemsToDisplay);
+		writer.writeText("", null);
+		writer.endElement("select");
+	}
+	
+	public void renderSelectOptions(FacesContext context, UIComponent component, Converter converter, Set lookupSet,
+             								List selectItemList) throws IOException {
+		 ResponseWriter writer = context.getResponseWriter();
+				
+		 for (Iterator it = selectItemList.iterator(); it.hasNext();) {
+			 SelectItem selectItem = (SelectItem) it.next();
+				
+			 if (selectItem instanceof SelectItemGroup) {
+				 writer.startElement("optgroup", component);
+				 writer.writeAttribute("label", selectItem.getLabel(), null);
+				 SelectItem[] selectItems = ((SelectItemGroup) selectItem).getSelectItems();
+				 renderSelectOptions(context, component, converter, lookupSet, Arrays.asList(selectItems));
+				 writer.endElement("optgroup");
+			} else {
+				String itemStrValue = PickListUtils.getConvertedStringValue(context, component, converter, selectItem.getValue());
+				writer.write('\t');
+				writer.startElement("option", component);
+				
+				if (itemStrValue != null) {
+					writer.writeAttribute(HTML.value_ATTRIBUTE, itemStrValue, null);
+				}
+				
+				if (lookupSet.contains(itemStrValue))
+				{  //TODO/FIX: we always compare the String vales, better fill lookupSet with Strings only when useSubmittedValue==true, else use the real item value Objects
+					writer.writeAttribute("selected", "selected", null);
+				}
+				
+				boolean disabled = selectItem.isDisabled();
+				if (disabled) {
+					writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
+				}
+				
+				String labelClass;
+				boolean componentDisabled = ((Boolean)component.getAttributes().get("disabled")).booleanValue();
+				
+				if (componentDisabled || disabled) {
+					labelClass = (String) component.getAttributes().get("disabledClass");
+				} else {
+					labelClass = (String) component.getAttributes().get("enabled");
+				}
+				
+				if (labelClass != null) {
+					writer.writeAttribute("class", labelClass, "labelClass");
+				}
+							
+				Boolean booleanValue = (Boolean)component.getAttributes().get("escape");
+				boolean escape = booleanValue != null ? booleanValue.booleanValue():true;   //default is to escape
+								
+				if (escape) {
+					writer.writeText(selectItem.getLabel(), null);
+				} else {
+					writer.write(selectItem.getLabel());
+				}
+				
+				writer.endElement("option");
+			}
+		}
+	}
+	
+	 @Override
+	protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
+
+		 UIPickList picklist = (UIPickList) component;
+
+		 String availableListClientId = picklist.getClientId(context) + AVAILABLE_SUFFIX;
+		 String selectedListClientId = picklist.getClientId(context) + SELECTED_SUFFIX;
+		 String hiddenFieldCliendId = picklist.getClientId(context) + HIDDEN_SUFFIX;
+
+		 List selectItemList = SelectUtils.getSelectItems(context,picklist);
+		 Converter converter = PickListUtils.findUISelectManyConverterFailsafe(context, picklist);
+		 Set lookupSet = PickListUtils.getSubmittedOrSelectedValuesAsSet(true, picklist, context, converter);
+		 List selectItemsForSelectedValues = selectItemsForSelectedList(context, picklist, selectItemList, converter, lookupSet);
+		 List selectItemsForAvailableList = selectItemsForAvailableList(context, picklist, selectItemList, selectItemsForSelectedValues, converter);
+
+		 writer.startElement("table", picklist);
+		 writer.startElement(HTML.TR_ELEMENT, picklist);
+		 writer.startElement(HTML.td_ELEM, picklist);
+		 
+		 encodeSelect(context, picklist, availableListClientId, picklist.isDisabled(), picklist.getSize(), selectItemsForAvailableList, converter, writer);
+
+		 writer.endElement(HTML.td_ELEM);
+
+		 // encode buttons
+		 writer.startElement(HTML.td_ELEM, picklist);
+
+		 String javascriptAddToSelected = FUNCTION_ADD_TO_SELECTED + "('"
+		                                  + availableListClientId + "','" + selectedListClientId + "','"
+		                                  + hiddenFieldCliendId + "')";
+		 String javascriptRemoveFromSelected = FUNCTION_REMOVE_FROM_SELECTED
+		                                       + "('" + availableListClientId + "','" + selectedListClientId
+		                                       + "','" + hiddenFieldCliendId + "')";
+
+		 encodeSwapButton(context, picklist, javascriptAddToSelected,">",writer);
+
+		 writer.startElement("br", picklist);
+		 writer.endElement("br");
+
+		 encodeSwapButton(context, picklist, javascriptRemoveFromSelected, "<", writer);
+
+		 writer.endElement(HTML.td_ELEM);
+
+		 // encode selected list
+		 writer.startElement(HTML.td_ELEM, picklist);
+
+		 encodeSelect(context, picklist, selectedListClientId, picklist.isDisabled(), picklist.getSize(),
+		                                     selectItemsForSelectedValues, converter, writer);
+
+		 // hidden field with the selected values
+		 encodeHiddenField(context, picklist, hiddenFieldCliendId, lookupSet,writer);
+
+		 writer.endElement(HTML.td_ELEM);
+		 writer.endElement(HTML.TR_ELEMENT);
+		 writer.endElement("table");
+	 }
+	
+	 private void encodeSwapButton(FacesContext facesContext, UIComponent uiComponent, String javaScriptFunction, 
+			 	  String text,ResponseWriter writer) throws IOException {
+
+		writer.startElement(HTML.INPUT_ELEM, uiComponent);
+		writer.writeAttribute(HTML.TYPE_ATTR,"button","type");
+		writer.writeAttribute(HTML.onclick_ATTRIBUTE, javaScriptFunction, null);
+		writer.writeAttribute(HTML.value_ATTRIBUTE, text, null);
+		writer.endElement(HTML.INPUT_ELEM);
+	 }
+	 
+	 private void encodeHiddenField(FacesContext facesContext, UIComponent component, 
+			 String hiddenFieldCliendId, Set lookupSet, ResponseWriter writer) throws IOException {
+		 
+		 writer.startElement(HTML.INPUT_ELEM, component);
+		 writer.writeAttribute(HTML.TYPE_ATTR, "hidden",  "type");
+		 writer.writeAttribute(HTML.id_ATTRIBUTE, hiddenFieldCliendId, "id");
+		 writer.writeAttribute("name", hiddenFieldCliendId, null);
+
+		 StringBuffer sb = new StringBuffer();
+		 int n = 0;
+		 for (Iterator i = lookupSet.iterator(); i.hasNext();) {
+			 if (n > 0) {
+				 sb.append(",");
+			 }
+			 String value = (String) i.next();
+			 sb.append(value);
+			 n++;
+		 }
+
+		 writer.writeAttribute(HTML.value_ATTRIBUTE, sb.toString(), null);
+		 writer.endElement(HTML.INPUT_ELEM);
+
+	}
+	 
+	protected Class<? extends UIComponent> getComponentClass() {
+		return UIPickList.class;
+	}	
+ }

Added: trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/renderkit/html/scripts/picklist.js
===================================================================
--- trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/renderkit/html/scripts/picklist.js	                        (rev 0)
+++ trunk/sandbox/ui/pickList/src/main/resources/org/richfaces/renderkit/html/scripts/picklist.js	2007-12-27 18:32:54 UTC (rev 5042)
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+ 
+ /**
+ * @author Bruno Aranda (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+ 
+// moves an item to the selected list
+function myfaces_picklist_addToSelected(availableListId, selectedListId, hiddenId)
+{
+	var availableList = document.getElementById(availableListId);
+    var selectedList = document.getElementById(selectedListId);
+
+	myfaces_picklist_move(availableList, selectedList, hiddenId);
+	myfaces_picklist_updateHidden(selectedList, hiddenId);
+}
+
+// removes an item from the selected list
+function myfaces_picklist_removeFromSelected(availableListId, selectedListId, hiddenId)
+{
+    var availableList = document.getElementById(availableListId);
+    var selectedList = document.getElementById(selectedListId);
+
+	myfaces_picklist_move(selectedList, availableList, hiddenId);
+	myfaces_picklist_updateHidden(selectedList, hiddenId);
+}
+
+function myfaces_picklist_move(fromList, toList, hiddenId) {
+	// Return, if no items selected
+	var selectedIndex = fromList.selectedIndex;
+	if(selectedIndex < 0) { return; }
+
+	// Decremental loop, so the index is not affected in the moves
+	for(var i = fromList.length - 1; i >= 0; i--) {
+		if(fromList.options.item(i).selected) {
+			toList.appendChild(fromList.options.item(i));
+		}
+	}
+
+}
+
+// Selection - invoked on submit
+function myfaces_picklist_updateHidden(selectedList, hiddenId) {
+	var hiddenField = document.getElementById(hiddenId);
+	
+	var arrValues = new Array(selectedList.options.length);
+	for (var i = 0; i<selectedList.options.length; i++) {
+	    arrValues[i] = selectedList.options[i].value;
+	}
+	
+	hiddenField.value = arrValues.join();
+}
\ No newline at end of file




More information about the richfaces-svn-commits mailing list