You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Ron Piterman <rp...@gmx.net> on 2006/12/12 20:33:41 UTC

Re: Optgroup

There is a renderer parameter to the PropertySelection component, which 
sadly is being ignored.

here are the classes, you can just copy, set the package and use. They 
are a modified version of the PropertySelection component

cheers,
Ron

==============================================


import org.apache.tapestry.*;
import org.apache.tapestry.form.*;
import org.apache.tapestry.valid.ValidatorException;

/**
  * A component used to render a drop-down list of options that the user 
may select. [ <a
  * 
href="../../../../../ComponentReference/PropertySelection.html">Component 
Reference </a>]
  * <p>
  * Earlier versions of PropertySelection (through release 2.2) were 
more flexible, they included a
  * <b>renderer </b> property that controlled how the selection was 
rendered. Ultimately, this proved
  * of little value and this portion of functionality was deprecated in 
2.3 and will be removed in
  * 2.3.
  * <p>
  * Typically, the values available to be selected are defined using an
  * {@link org.apache.commons.lang.enum.Enum}. A PropertySelection is 
dependent on an
  * {@link IPropertySelectionModel} to provide the list of possible values.
  * <p>
  * Often, this is used to select a particular {@link 
org.apache.commons.lang.enum.Enum} to assign to
  * a property; the {@link EnumPropertySelectionModel} class simplifies 
this.
  * <p>
  * Often, a drop-down list will contain an initial option that serves 
both as a label and to represent
  * that nothing is selected. This can behavior can easily be achieved 
by decorating an existing
  * {@link IPropertySelectionModel} with a {@link 
LabeledPropertySelectionModel}.
  * <p>
  * As of 4.0, this component can be validated.
  *
  * @author Howard Lewis Ship
  * @author Paul Ferraro
  */
public abstract class RendererPropertySelection extends 
PropertySelection implements ValidatableField
{
     /**
      * @see 
org.apache.tapestry.form.AbstractFormComponent#renderFormComponent(org.apache.tapestry.IMarkupWriter, 
org.apache.tapestry.IRequestCycle)
      */
     protected void renderFormComponent(IMarkupWriter writer, 
IRequestCycle cycle)
     {
         renderDelegatePrefix(writer, cycle);

         writer.begin("select");
         writer.attribute("name", getName());

         if (isDisabled())
             writer.attribute("disabled", "disabled");

         if (getSubmitOnChange())
             writer.attribute("onchange", "javascript: 
this.form.events.submit();");

         renderIdAttribute(writer, cycle);

         renderDelegateAttributes(writer, cycle);

         getValidatableFieldSupport().renderContributions(this, writer, 
cycle);

         // Apply informal attributes.
         renderInformalParameters(writer, cycle);

         writer.println();

         IPropertySelectionModel model = getModel();

         if (model == null)
             throw Tapestry.createRequiredParameterException(this, "model");

         int count = model.getOptionCount();
         boolean foundSelected = false;
         Object value = getValue();

         IPropertySelectionRenderer renderer = getRenderer();
         if ( renderer == null && ( model instanceof 
IPropertySelectionRenderer ) )
         	if ( ! isDefaultRenderer() )
         		renderer = (IPropertySelectionRenderer) model;

         for (int i = 0; i < count; i++)
         {
             Object option = model.getOption(i);
             boolean isSelected = !foundSelected && isEqual(option, value);

             if ( renderer != null )
             	renderer.renderOption( this , writer, cycle , model , 
option, i , isSelected );
             else {
	
             	writer.begin("option");
	            writer.attribute("value", model.getValue(i));
	
	            if ( isSelected )
	            {
	                writer.attribute("selected", "selected");
	
	                foundSelected = true;
	            }
	
	            writer.print(model.getLabel(i));
	
	            writer.end();
	
             }

             writer.println();
         }

         writer.end(); // <select>

         renderDelegateSuffix(writer, cycle);
     }

     /**
      * @see 
org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter, 
org.apache.tapestry.IRequestCycle)
      */
     protected void rewindFormComponent(IMarkupWriter writer, 
IRequestCycle cycle)
     {
         String value = cycle.getParameter(getName());

         Object object = (value == null) ? null : 
getModel().translateValue(value);

         try
         {
             getValidatableFieldSupport().validate(this, writer, cycle, 
object);

             setValue(object);
         }
         catch (ValidatorException e)
         {
             getForm().getDelegate().record(e);
         }
     }

     private boolean isEqual(Object left, Object right)
     {
         // Both null, or same object, then are equal

         if (left == right)
             return true;

         // If one is null, the other isn't, then not equal.

         if (left == null || right == null)
             return false;

         // Both non-null; use standard comparison.

         return left.equals(right);
     }

     public abstract IPropertySelectionModel getModel();

     /** @since 2.2 * */
     public abstract boolean getSubmitOnChange();

     /** @since 2.2 * */
     public abstract Object getValue();

     /** @since 2.2 * */
     public abstract void setValue(Object value);


     public abstract IPropertySelectionRenderer getRenderer();
     /**
      * Injected.
      */
     public abstract ValidatableFieldSupport getValidatableFieldSupport();

     /**
      * @see org.apache.tapestry.form.AbstractFormComponent#isRequired()
      */
     public boolean isRequired()
     {
         return getValidatableFieldSupport().isRequired(this);
     }

     public abstract boolean isDefaultRenderer();
}

=====================


<?xml version="1.0" encoding="UTF-8"?>
<!--
    Copyright 2004, 2005 The Apache Software Foundation

    Licensed 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.
-->

<!DOCTYPE component-specification PUBLIC
   "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
   "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">

<component-specification 
class="com.pvs.pmm.web.core.comp.common.property_selection.RendererPropertySelection"
	allow-body="no"
	allow-informal-parameters="yes">

   <description>
   Creates an HTML select to choose a single property from a list of 
options.
   </description>

   <parameter name="value" required="yes"/>

   <parameter name="model" required="yes"/>

   <parameter name="disabled"/>

   <parameter name="renderer">
   	<description>
	An alternate rendered for the property selection.
   	</description>
   </parameter>

   <parameter name="submitOnChange" deprecated="true">
   	<description>
   	Enables logic to submit containing form when value changes.
   	</description>
   </parameter>

   <parameter name="displayName"/>
   <parameter name="validators"/>

   <parameter name="id" property="idParameter" default-value="id"/>

   <parameter name="defaultRenderer" default-value="false"/>

   <reserved-parameter name="name"/>

   <inject property="validatableFieldSupport" 
object="service:tapestry.form.ValidatableFieldSupport"/>

</component-specification>


==================================

import java.util.Collection;

public interface GroupOptionResolver<PARENT,CHILD,VALUE> {

	Collection<CHILD> getOptions( PARENT parent);

	String getChildLabel(CHILD child);

	String getChildValue(CHILD child);

	String getParentLabel(PARENT option);

	PARENT getParent(int index);

	int getParentCount();

	VALUE translateChildValue(String value);

}


======================================0

import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.form.*;

public class GroupPropertySelectionRenderer implements 
IPropertySelectionRenderer, IPropertySelectionModel {

	private GroupOptionResolver optionResolver;

	public GroupPropertySelectionRenderer(GroupOptionResolver res) {
		this.optionResolver = res;
	}

	// ----------------------------------------
	// implementation of renderer
	// ----------------------------------------


	public void beginRender(PropertySelection component, IMarkupWriter 
writer, IRequestCycle cycle) {
		// do nothing;
	}

	public void endRender(PropertySelection component, IMarkupWriter 
writer, IRequestCycle cycle) {
		// do nothing;
	}

	@SuppressWarnings("unchecked")
	public void renderOption(PropertySelection component, IMarkupWriter 
writer, IRequestCycle cycle, IPropertySelectionModel model, Object 
option, int index, boolean selected) {
		Object selectedValue = component.getValue();

		if ( option != null ) {
			writer.begin("optgroup");
			writer.attribute( "label" , model.getLabel(index));
		}


		for ( Object o : optionResolver.getOptions( option ) ) {
			writer.begin( "option" );
			writer.attribute("label", this.optionResolver.getChildLabel( o ));
			if ( isSelected( selectedValue , o ))
				writer.attribute("selected" , "true" );
			writer.print( this.optionResolver.getChildValue( o ));
			writer.end();
		}

		if ( option != null )
			writer.end();

	}

	@SuppressWarnings("unchecked")
	private boolean isSelected(Object selectedValue, Object child) {
		Object childValue = this.optionResolver.getChildValue( child );
		return selectedValue == null ?
				childValue == null :
					selectedValue.equals( childValue );
	}


	// ----------------------------------------
	// implementation of model
	// ----------------------------------------

	@SuppressWarnings("unchecked")
	public String getLabel(int index) {
		return this.optionResolver.getParentLabel( getOption( index ));
	}

	public Object getOption(int index) {
		return this.optionResolver.getParent( index );
	}

	public int getOptionCount() {
		return this.optionResolver.getParentCount();
	}

	public String getValue(int index) {
		return null;
	}

	public Object translateValue(String value) {
		return this.optionResolver.translateChildValue( value );
	}


}








Matthew Walsh wrote:
> I have an implementation of IPropertySelectionModel that works fine,
> but I was looking for an easy way to divide them into groups using the
> <optgroup> tag like so:
> 
> <select>
>   <optgroup label="food">
>      <option>burger</option>
>      <option>hot dog</option>
>   </optgroup>
>   <optgroup label="drink">
>      <option>beer</option>
>      <option>soda</option>
>   </optgroup>
> </select>
> 
> What is the easiest way to accomplish this without rewriting too much?
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org