001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 2008-2010 by chenillekit.org
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.tapestry.core.components;
016    
017    import org.apache.tapestry5.BindingConstants;
018    import org.apache.tapestry5.ClientElement;
019    import org.apache.tapestry5.ComponentResources;
020    import org.apache.tapestry5.MarkupWriter;
021    import org.apache.tapestry5.annotations.Component;
022    import org.apache.tapestry5.annotations.Environmental;
023    import org.apache.tapestry5.annotations.Parameter;
024    import org.apache.tapestry5.annotations.Persist;
025    import org.apache.tapestry5.annotations.SupportsInformalParameters;
026    import org.apache.tapestry5.corelib.components.Select;
027    import org.apache.tapestry5.ioc.annotations.Inject;
028    import org.apache.tapestry5.ioc.services.PropertyAccess;
029    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
030    import org.chenillekit.tapestry.core.internal.GenericSelectionModel;
031    import org.chenillekit.tapestry.core.internal.GenericValueEncoder;
032    
033    import java.util.List;
034    
035    /**
036     * let you make a list of beans selectable.
037     *
038     * @version $Id: BeanSelect.java 674 2010-07-29 12:47:25Z homburgs $
039     */
040    // TODO make beans multi-selectable
041    @SupportsInformalParameters
042    public class BeanSelect implements ClientElement
043    {
044            /**
045             * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
046             * times, a suffix will be appended to the to id to ensure uniqueness.
047             */
048            @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
049            private String clientId;
050    
051            /**
052             * The value(bean) to read or update.
053             */
054            @Parameter(required = true, principal = true)
055            private Object value;
056    
057            /**
058             * The list of bean should diplayed.
059             */
060            @Parameter(required = true)
061            private List<Object> list;
062    
063            /**
064             * Name of the Field that should reflect the label in the select option tag.
065             */
066            @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
067            private String labelField;
068    
069            /**
070             * Name of the Field that should reflect the value in the select option tag.
071             */
072            @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
073            private String valueField;
074    
075            @Component(inheritInformalParameters = true, parameters = {"blankLabel=inherit:blankLabel",
076                            "blankOption=inherit:blankOption", "clientId=prop:clientId",
077                            "validate=inherit:validate", "value=value", "model=beanModel", "encoder=beanEncoder"})
078            private Select select;
079    
080            @Inject
081            private ComponentResources resources;
082    
083            @Inject
084            private PropertyAccess propertyAccess;
085    
086            @Persist
087            private GenericSelectionModel<Object> model;
088    
089            @Persist
090            private GenericValueEncoder<Object> encoder;
091    
092            @Environmental
093            private JavaScriptSupport javascriptSupport;
094    
095            private String assignedClientId;
096    
097            void setupRender()
098            {
099                    assignedClientId = javascriptSupport.allocateClientId(clientId);
100            }
101    
102            void beginRender(MarkupWriter writer)
103            {
104                    encoder = new GenericValueEncoder<Object>(list, valueField, propertyAccess);
105                    model = new GenericSelectionModel<Object>(list, labelField, propertyAccess);
106            }
107    
108            public GenericSelectionModel<Object> getBeanModel()
109            {
110                    return model;
111            }
112    
113            public GenericValueEncoder<Object> getBeanEncoder()
114            {
115                    return encoder;
116            }
117    
118            public Object getValue()
119            {
120                    return value;
121            }
122    
123            public void setValue(Object value)
124            {
125                    this.value = value;
126            }
127    
128            /**
129             * only for testing
130             */
131            void setup(Object value, List<Object> list, String labelField, String valueField)
132            {
133                    this.value = value;
134                    this.list = list;
135                    this.labelField = labelField;
136                    this.valueField = valueField;
137            }
138    
139            /**
140             * only for testing
141             */
142            void inject(ComponentResources resources, PropertyAccess propertyAccess)
143            {
144                    this.resources = resources;
145                    this.propertyAccess = propertyAccess;
146            }
147    
148            /**
149             * Returns a unique id for the element. This value will be unique for any given rendering of a
150             * page. This value is intended for use as the id attribute of the client-side element, and will
151             * be used with any DHTML/Ajax related JavaScript.
152             */
153            public String getClientId()
154            {
155                    return assignedClientId;
156            }
157    }