Hi there, I googled a little around, but I was not able to find a tapestry component that generates a button.
Here you can find a first attempt to create such component. It was shameless copied from the Submit component already present in tapestry. I would be happy if someone more expert than me could revise it and add to the core components. Regards, larzeni package org.apache.tapestry5.corelib.components; import org.apache.tapestry5.BindingConstants; import org.apache.tapestry5.ClientElement; import org.apache.tapestry5.ComponentAction; import org.apache.tapestry5.ComponentResources; import org.apache.tapestry5.EventConstants; import org.apache.tapestry5.MarkupWriter; import org.apache.tapestry5.TrackableComponentEventCallback; import org.apache.tapestry5.annotations.Environmental; import org.apache.tapestry5.annotations.Events; import org.apache.tapestry5.annotations.Import; import org.apache.tapestry5.annotations.Parameter; import org.apache.tapestry5.annotations.SupportsInformalParameters; import org.apache.tapestry5.corelib.SubmitMode; import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.corelib.components.Loop; import org.apache.tapestry5.internal.util.Holder; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.json.JSONArray; import org.apache.tapestry5.services.FormSupport; import org.apache.tapestry5.services.Heartbeat; import org.apache.tapestry5.services.Request; import org.apache.tapestry5.services.javascript.JavaScriptSupport; /** * Corresponds to <input type="submit"> or <input type="image">, a client-side element that can force the * enclosing form to submit. The submit responsible for the form submission will post a notification that allows the * application to know that it was the responsible entity. The notification is named * {@linkplain EventConstants#SELECTED selected}, by default, and has no context. * * @tapestrydoc */ @SupportsInformalParameters @Events(EventConstants.SELECTED + " by default, may be overridden") @Import(module="t5/core/forms") public class Html5Button implements ClientElement { /** * If true (the default), then any notification sent by the component will be deferred until the end of the form * submission (this is usually desirable). In general, this can be left as the default except when the Submit * component is rendering inside a {@link Loop}, in which case defer should be bound to false (otherwise, the * event context will always be the final value of the Loop). */ @Parameter private boolean defer = true; /** * The name of the event that will be triggered if this component is the cause of the form submission. The default * is {@link EventConstants#SELECTED}. */ @Parameter(allowNull = false, defaultPrefix = BindingConstants.LITERAL) private String event = EventConstants.SELECTED; /** * If true, then the field will render out with a disabled attribute * (to turn off client-side behavior). When the form is submitted, the * bound value is evaluated again and, if true, the field's value is * ignored (not even validated) and the component's events are not fired. */ @Parameter("false") private boolean disabled; @Parameter(defaultPrefix = BindingConstants.LITERAL) private String type; /** * The list of values that will be made available to event handler method of this component when the form is * submitted. * * @since 5.1.0.0 */ @Parameter private Object[] context; /** * Defines the mode, or client-side behavior, for the submit. The default is {@link SubmitMode#NORMAL}; clicking the * button submits the form with validation. {@link SubmitMode#CANCEL} indicates the form should be submitted as a cancel, * with no client-side validation. {@link SubmitMode#UNCONDITIONAL} bypasses client-side validation, but does not indicate * that the form was cancelled. * * @see EventConstants#CANCELED * @since 5.2.0 */ @Parameter(allowNull = false, defaultPrefix = BindingConstants.LITERAL) private SubmitMode mode = SubmitMode.NORMAL; /** * CSS class for the element. * * @since 5.4 */ @Parameter(name = "class", defaultPrefix = BindingConstants.LITERAL, value = "message:private-core-components.submit.class") private String cssClass; @Environmental private FormSupport formSupport; @Environmental private Heartbeat heartbeat; @Inject private ComponentResources resources; @Inject private Request request; @Inject private JavaScriptSupport javascriptSupport; @SuppressWarnings("rawtypes") @Environmental private TrackableComponentEventCallback eventCallback; private String clientId; @SuppressWarnings("serial") private static class ProcessSubmission implements ComponentAction<Html5Button> { private final String clientId, elementName; public ProcessSubmission(String clientId, String elementName) { this.clientId = clientId; this.elementName = elementName; } public void execute(Html5Button component) { component.processSubmission(clientId, elementName); } } public Html5Button() { } Html5Button(Request request) { this.request = request; } void beginRender(MarkupWriter writer) { clientId = javascriptSupport.allocateClientId(resources); String l_name = formSupport.allocateControlName(resources.getId()); // Save the element, to see if an id is later requested. writer.element("button", "type", type, "name", l_name, "data-submit-mode", mode.name().toLowerCase(), "class", cssClass, "id", clientId); if (disabled) { writer.attributes("disabled", "disabled"); } formSupport.store(this, new ProcessSubmission(clientId, l_name)); resources.renderInformalParameters(writer); } void afterRender(MarkupWriter writer) { writer.end(); } void processSubmission(String clientId, String elementName) { if (disabled || !selected(clientId, elementName)) return; // TAP5-1658: copy the context of the current Submit instance so we trigger the event with // the correct context later final Holder<Object[]> currentContextHolder = Holder.create(); if (context != null) { Object[] currentContext = new Object[context.length]; System.arraycopy(context, 0, currentContext, 0, context.length); currentContextHolder.put(currentContext); } Runnable sendNotification = new Runnable() { public void run() { // TAP5-1024: allow for navigation result from the event callback resources.triggerEvent(event, currentContextHolder.get(), eventCallback); } }; // When not deferred, don't wait, fire the event now (actually, at the end of the current // heartbeat). This is most likely because the Submit is inside a Loop and some contextual // information will change if we defer. if (defer) formSupport.defer(sendNotification); else heartbeat.defer(sendNotification); } private boolean selected(String clientId, String elementName) { // Case #1: via JavaScript, the client id is passed up. String raw = request.getParameter(Form.SUBMITTING_ELEMENT_ID); if (InternalUtils.isNonBlank(raw) && new JSONArray(raw).getString(0).equals(clientId)) { return true; } String name = elementName; String value = request.getParameter(name); return value != null; } /** * Returns the component's client id. This must be called after the component has rendered. * * @return client id for the component */ public String getClientId() { return clientId; } } --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org