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 }