1 /**
2 * This file is part of the equanda project.
3 *
4 * The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
7 *
8 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
9 * ANY KIND, either express or implied. See the License for the specific language governing rights and
10 * limitations under the License.
11 *
12 * Alternatively, the contents of this file may be used under the terms of
13 * either the GNU General Public License Version 2 or later (the "GPL"), or
14 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
15 * in which case the provisions of the GPL or the LGPL are applicable instead
16 * of those above. If you wish to allow use of your version of this file only
17 * under the terms of either the GPL or the LGPL, and not to allow others to
18 * use your version of this file under the terms of the MPL, indicate your
19 * decision by deleting the provisions above and replace them with the notice
20 * and other provisions required by the GPL or the LGPL. If you do not delete
21 * the provisions above, a recipient may use your version of this file under
22 * the terms of any one of the MPL, the GPL or the LGPL.
23 */
24
25 package org.equanda.tapestry5.components;
26
27 import org.apache.tapestry5.*;
28 import org.apache.tapestry5.annotations.Environmental;
29 import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary;
30 import org.apache.tapestry5.annotations.Parameter;
31 import org.apache.tapestry5.corelib.base.AbstractTextField;
32 import org.apache.tapestry5.ioc.annotations.Inject;
33
34 /**
35 * A variation on the tapestry builtin TextField component. The main difference being that this one can also contain
36 * zone and context parameters. The zone is updated when a value is defined in the text field.
37 * Note that due to limitations in tapestry, the zone contents should not contain form elements.
38 *
39 * @author <a href="mailto:joachim@progs.be">Joachim Van der Auwera</a>
40 */
41 @IncludeJavaScriptLibrary( { "${tapestry.scriptaculous}/prototype.js",
42 "classpath:/org/equanda/tapestry5/resources/t5equanda.js" } )
43 public class TextField
44 extends AbstractTextField
45 {
46 @Inject
47 private ComponentResources resources;
48
49 @Environmental
50 private RenderSupport renderSupport;
51
52 /**
53 * The context for the link (optional parameter). This list of values will be converted into strings and included in
54 * the URI. The strings will be coerced back to whatever their values are and made available to event handler
55 * methods.
56 */
57 @Parameter
58 private Object[] context;
59
60 /** Binding the zone parameter turns the link into a an Ajax control that causes the related zone to be updated. */
61 @Parameter( defaultPrefix = BindingConstants.LITERAL )
62 private String zone;
63
64 protected Link createLink( Object[] contextArray )
65 {
66 return resources.createEventLink( "change", contextArray );
67 }
68
69 @Override
70 protected void writeFieldTag( MarkupWriter writer, String value )
71 {
72 writer.element( "input",
73 "type", "text",
74 "name", getControlName(),
75 "id", getClientId(),
76 "value", value,
77 "size", getWidth() );
78 }
79
80 final void afterRender( MarkupWriter writer )
81 {
82 writer.end(); // input
83 if ( null != zone )
84 {
85 String urlStart = createLink( context ).toAbsoluteURI();
86 String urlEnd = "";
87 int pos = getUrlSplit( urlStart );
88 if ( pos > 0 )
89 {
90 urlEnd = urlStart.substring( pos );
91 urlStart = urlStart.substring( 0, pos ) + "/";
92 }
93 renderSupport.addScript( "element = $('%s');\n" +
94 // Update the element with the id of zone div. This may be changed dynamically on the client side.
95 "$T(element).zoneId = '%s';\n" +
96 "element.observe(\"change\", function(event) { eqTfzu( event, '%s/', '%s' ); });\n",
97 getClientId(), zone, urlStart, urlEnd );
98 }
99 }
100
101 private int getUrlSplit( String url )
102 {
103 int p1 = url.indexOf( '?' );
104 int p2 = url.indexOf( ';' );
105 if ( -1 == p1 ) return p2;
106 if ( -1 == p2 ) return p1;
107 return p1 < p2 ? p1 : p2;
108 }
109 }