001// Copyright 2008, 2010, 2011, 2012 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.corelib.mixins; 016 017import org.apache.tapestry5.BindingConstants; 018import org.apache.tapestry5.ClientElement; 019import org.apache.tapestry5.Field; 020import org.apache.tapestry5.annotations.Environmental; 021import org.apache.tapestry5.annotations.HeartbeatDeferred; 022import org.apache.tapestry5.annotations.InjectContainer; 023import org.apache.tapestry5.annotations.Parameter; 024import org.apache.tapestry5.corelib.components.FormFragment; 025import org.apache.tapestry5.json.JSONObject; 026import org.apache.tapestry5.services.javascript.JavaScriptSupport; 027 028/** 029 * A mixin that can be applied to a {@link org.apache.tapestry5.corelib.components.Checkbox} or 030 * {@link org.apache.tapestry5.corelib.components.Radio} component that will link the input field and a 031 * {@link org.apache.tapestry5.corelib.components.FormFragment}, making the field control the client-side visibility of 032 * the FormFragment. See a full example with {@link FormFragment}'s documentation. 033 * 034 * @tapestrydoc 035 */ 036public class TriggerFragment 037{ 038 @InjectContainer 039 private Field container; 040 041 /** 042 * The {@link org.apache.tapestry5.corelib.components.FormFragment} instance to make dynamically visible or hidden. 043 */ 044 @Parameter(required = true, defaultPrefix = BindingConstants.COMPONENT, allowNull = false) 045 private ClientElement fragment; 046 047 /** 048 * If true then the client-side logic is inverted; the fragment is made visible when the checkbox is NOT checked. 049 * The default is false (the fragment is visible when the checkbox IS checked). 050 * 051 * @since 5.2.0 052 */ 053 @Parameter 054 private boolean invert; 055 056 @Environmental 057 private JavaScriptSupport javascriptSupport; 058 059 @HeartbeatDeferred 060 void beginRender() 061 { 062 String fragmentId = fragment.getClientId(); 063 if (fragmentId == null) 064 { 065 throw new IllegalStateException("The fragment has returned a null client-side ID"); 066 } 067 JSONObject spec = new JSONObject( 068 "triggerId", container.getClientId(), 069 "fragmentId", fragmentId); 070 071 if (invert) 072 { 073 spec.put("invert", true); 074 } 075 076 javascriptSupport.require("t5/core/form-fragment").invoke("linkTrigger").with(spec); 077 } 078}