    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}