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.Link;
021 import org.apache.tapestry5.MarkupWriter;
022 import org.apache.tapestry5.annotations.Environmental;
023 import org.apache.tapestry5.annotations.Import;
024 import org.apache.tapestry5.annotations.Parameter;
025 import org.apache.tapestry5.annotations.SupportsInformalParameters;
026 import org.apache.tapestry5.corelib.components.PageLink;
027 import org.apache.tapestry5.ioc.Messages;
028 import org.apache.tapestry5.ioc.annotations.Inject;
029 import org.apache.tapestry5.services.PageRenderLinkSource;
030 import org.apache.tapestry5.services.javascript.JavaScriptSupport;
031
032 import java.util.List;
033
034 /**
035 * Render a button tag element and bind to it's "click" event an event on the server side.
036 * The event name is customizable and it defaults to "CLICKED".
037 * <p/>
038 * If parameter <code>pageName</code> is given the component act like a {@link PageLink}
039 * to the page corresponding to the logical name <code>pageName</code>.
040 *
041 * @version $Id: Button.java 674 2010-07-29 12:47:25Z homburgs $
042 */
043 @SupportsInformalParameters
044 @Import(library = {"../Chenillekit.js", "CkOnEvents.js"})
045 public class Button implements ClientElement
046 {
047 static final String CLICKED_EVENT = "clicked";
048
049 static final String TYPE_BUTTON = "button";
050 static final String TYPE_SUBMIT = "submit";
051 static final String TYPE_RESET = "reset";
052
053 /**
054 * Type of the button, possible value are "button", "submit" and "reset".
055 */
056 @Parameter(defaultPrefix = BindingConstants.LITERAL, value = TYPE_BUTTON)
057 private String type;
058
059 /**
060 * The name of the event fired. Defaults to <code>clicked</code>.
061 */
062 @Parameter(defaultPrefix = BindingConstants.LITERAL, value = CLICKED_EVENT)
063 private String event;
064
065 /**
066 * If specified the components act as a {@link PageLink} doing a link
067 * for rendering the logical <code>pageName</code>.
068 */
069 @Parameter(defaultPrefix = BindingConstants.LITERAL, required = false)
070 private String pageName;
071
072 /**
073 * <code>Disabled</code> attribute of the element.
074 */
075 @Parameter(value = "false")
076 private boolean disabled;
077
078 /**
079 * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
080 * times, a suffix will be appended to the to id to ensure uniqueness.
081 */
082 @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
083 private String clientId;
084
085 /**
086 * To ask for a confirmation or not
087 */
088 @Parameter(value = "literal:false")
089 private boolean confirm;
090
091 /**
092 * The context for the link (optional parameter). This list of values will
093 * be converted into strings and included in the URI. The strings will be
094 * coerced back to whatever their values are and made available to event
095 * handler methods or the passivate mthod of the page to link to in case
096 * a <code>pageName</code> has been specified.
097 */
098 @Parameter
099 private List<?> context;
100
101 @Environmental
102 private JavaScriptSupport javascriptSupport;
103
104 @Inject
105 private ComponentResources resources;
106
107 @Inject
108 private PageRenderLinkSource pageRenderResources;
109
110 @Inject
111 private Messages messages;
112
113 private String assignedClientId;
114
115 private Object[] contextArray;
116
117 void setupRender()
118 {
119 assignedClientId = javascriptSupport.allocateClientId(clientId);
120 contextArray = context == null ? new Object[0] : context.toArray();
121 }
122
123 void beginRender(MarkupWriter writer)
124 {
125 writer.element("button", "type", type, "id", getClientId());
126 resources.renderInformalParameters(writer);
127 }
128
129 void afterRender(MarkupWriter writer)
130 {
131 if (!disabled && type.equalsIgnoreCase(TYPE_BUTTON))
132 {
133 Link link;
134
135 if (pageName != null)
136 {
137 link = pageRenderResources.createPageRenderLinkWithContext(pageName, contextArray);
138 }
139 else
140 {
141 link = resources.createEventLink(event, contextArray);
142 }
143
144 String message = "";
145
146 if (this.confirm)
147 message = messages.format("ck-button-confirm-message", clientId);
148
149 javascriptSupport.addScript("new Ck.ButtonEvent('%s', '%s', '%s');",
150 getClientId(), link.toAbsoluteURI(), message);
151 }
152
153 // Close the button tag
154 writer.end();
155 }
156
157 /**
158 * Returns a unique id for the element. This value will be unique for any given rendering of a
159 * page. This value is intended for use as the id attribute of the client-side element, and will
160 * be used with any DHTML/Ajax related JavaScript.
161 */
162 public String getClientId()
163 {
164 return assignedClientId;
165 }
166 }