All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tapestry5.corelib.components.FormFragment Maven / Gradle / Ivy

Go to download

Central module for Tapestry, containing interfaces to the Java Servlet API and all core services and components.

There is a newer version: 5.8.6
Show newest version
// Copyright 2008, 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.apache.tapestry5.corelib.components;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.CSSClassConstants;
import org.apache.tapestry5.ClientElement;
import org.apache.tapestry5.ComponentAction;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.SupportsInformalParameters;
import org.apache.tapestry5.corelib.internal.ComponentActionSink;
import org.apache.tapestry5.corelib.internal.FormSupportAdapter;
import org.apache.tapestry5.corelib.internal.HiddenFieldPositioner;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ClientBehaviorSupport;
import org.apache.tapestry5.services.ClientDataEncoder;
import org.apache.tapestry5.services.Environment;
import org.apache.tapestry5.services.FormSupport;
import org.apache.tapestry5.services.HiddenFieldLocationRules;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.slf4j.Logger;

/**
 * A FormFragment is a portion of a Form that may be selectively displayed. Form elements inside a FormFragment will
 * automatically bypass validation when the fragment is invisible. The trick is to also bypass server-side form
 * processing for such fields when the form is submitted; client-side logic "removes" the
 * {@link org.apache.tapestry5.corelib.components.Form#FORM_DATA form data} for the fragment if it is invisible when the
 * form
 * is submitted; alternately, client-side logic can simply remove the form fragment element (including its visible and
 * hidden fields) to prevent server-side processing.
 * 

* The client-side element will now listen to two new event defined by client-side constants: *

*
Tapestry.CHANGE_VISIBILITY_EVENT
*
Change the visiblity as per the event memo's visibility property. When the visiblity changes, the correct * animation is executed.
*
Tapestry.HIDE_AND_REMOVE_EVENT
*
Hides the element, then removes it from the DOM entirely. *
* * @see org.apache.tapestry5.corelib.mixins.TriggerFragment */ @SupportsInformalParameters public class FormFragment implements ClientElement { /** * Determines if the fragment is initially visible or initially invisible (the default). This is only used when * rendering; when the form is submitted, the hidden field value is used to determine whether the elements within * the fragment should be processed (or ignored if still invisible). */ @Parameter private boolean visible; /** * If true, then the fragment submits the values from fields it contains even if the fragment is not * visible. * The default is to omit values from fields when the enclosing fragment is non visible. * * @since 5.2.0 */ @Parameter private boolean alwaysSubmit; /** * Name of a function on the client-side Tapestry.ElementEffect object that is invoked to make the fragment visible. * If not specified, then the default "slidedown" function is used. */ @Parameter(defaultPrefix = BindingConstants.LITERAL) private String show; /** * Name of a function on the client-side Tapestry.ElementEffect object that is invoked when the fragment is to be * hidden. If not specified, the default "slideup" function is used. */ @Parameter(defaultPrefix = BindingConstants.LITERAL) private String hide; /** * The element to render for each iteration of the loop. The default comes from the template, or "div" if the * template did not specific an element. */ @Parameter(defaultPrefix = BindingConstants.LITERAL) private String element; /** * If bound, then the id attribute of the rendered element will be this exact value. If not bound, then a unique id * is generated for the element. */ @Parameter(name = "id", defaultPrefix = BindingConstants.LITERAL) private String idParameter; @Inject private Environment environment; @Environmental private JavaScriptSupport javascriptSupport; @Inject private ComponentResources resources; @Environmental private ClientBehaviorSupport clientBehaviorSupport; private String clientId; private ComponentActionSink componentActions; @Inject private Logger logger; @Inject private HiddenFieldLocationRules rules; private HiddenFieldPositioner hiddenFieldPositioner; @Inject private ClientDataEncoder clientDataEncoder; String defaultElement() { return resources.getElementName("div"); } /** * Renders a <div> tag and provides an override of the {@link org.apache.tapestry5.services.FormSupport} * environmental. */ void beginRender(MarkupWriter writer) { FormSupport formSupport = environment.peekRequired(FormSupport.class); clientId = resources.isBound("id") ? idParameter : javascriptSupport.allocateClientId(resources); hiddenFieldPositioner = new HiddenFieldPositioner(writer, rules); Element element = writer.element(this.element, "id", clientId); resources.renderInformalParameters(writer); if (!visible) element.addClassName(CSSClassConstants.INVISIBLE); clientBehaviorSupport.addFormFragment(clientId, alwaysSubmit, show, hide); componentActions = new ComponentActionSink(logger, clientDataEncoder); // Here's the magic of environmentals ... we can create a wrapper around // the normal FormSupport environmental that intercepts some of the behavior. // Here we're setting aside all the actions inside the FormFragment so that we // can control whether those actions occur when the form is submitted. FormSupport override = new FormSupportAdapter(formSupport) { @Override public void store(T component, ComponentAction action) { componentActions.store(component, action); } @Override public void storeAndExecute(T component, ComponentAction action) { componentActions.store(component, action); action.execute(component); } }; // Tada! Now all the enclosed components will use our override of FormSupport, // until we pop it off. environment.push(FormSupport.class, override); } /** * Closes the <div> tag and pops off the {@link org.apache.tapestry5.services.FormSupport} environmental * override. * * @param writer */ void afterRender(MarkupWriter writer) { hiddenFieldPositioner.getElement().attributes("type", "hidden", "name", Form.FORM_DATA, "id", clientId + "-hidden", "value", componentActions.getClientData()); writer.end(); // div environment.pop(FormSupport.class); } public String getClientId() { return clientId; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy