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.MarkupWriter;
021    import org.apache.tapestry5.annotations.Environmental;
022    import org.apache.tapestry5.annotations.Import;
023    import org.apache.tapestry5.annotations.Parameter;
024    import org.apache.tapestry5.annotations.SupportsInformalParameters;
025    import org.apache.tapestry5.ioc.annotations.Inject;
026    import org.apache.tapestry5.services.Environment;
027    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
028    
029    import java.util.List;
030    
031    /**
032     * accordion component.
033     *
034     * @version $Id: Accordion.java 674 2010-07-29 12:47:25Z homburgs $
035     */
036    @SupportsInformalParameters
037    @Import(library = {"../Chenillekit.js", "Accordion.js"}, stylesheet = {"Accordion.css"})
038    public class Accordion implements ClientElement
039    {
040            /**
041             * The id used to generate a page-unique client-side identifier for the component. If a component renders multiple
042             * times, a suffix will be appended to the to id to ensure uniqueness.
043             */
044            @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
045            private String clientId;
046    
047            /**
048             * array of strings to show as panels subject.
049             */
050            @Parameter(required = true)
051            private List<?> subjects;
052    
053            /**
054             * array of strings to show as details text.
055             */
056            @Parameter(required = true)
057            private List<?> details;
058    
059            /**
060             * output raw markup to the client if true.
061             */
062            @Parameter(value = "false", required = false)
063            private boolean renderDetailsRaw;
064    
065            /**
066             * duration of slide animation.
067             */
068            @Parameter(value = "0.2", required = false)
069            private String duration;
070    
071            @Inject
072            private ComponentResources resources;
073    
074            @Environmental
075            private JavaScriptSupport javascriptSupport;
076    
077            @Inject
078            private Environment environment;
079    
080            private String assignedClientId;
081    
082            void setupRender()
083            {
084                    assignedClientId = javascriptSupport.allocateClientId(clientId);
085            }
086    
087            void beginRender(MarkupWriter writer)
088            {
089                    writer.element("div", "id", getClientId());
090                    resources.renderInformalParameters(writer);
091    
092    
093                    Object[] subjectsArray = subjects.toArray();
094                    Object[] detailsArray = details.toArray();
095    
096                    for (int i = 0; i < subjectsArray.length; i++)
097                    {
098                            String subject = subjectsArray[i].toString();
099                            String detail = "";
100                            if (detailsArray.length >= i + 1)
101                                    detail = detailsArray[i].toString();
102    
103                            writer.element("div", "id", getClientId() + "_toggle_" + i, "class", "ck_accordionToggle");
104                            writer.write(subject);
105                            writer.end();
106    
107                            writer.element("div", "id", getClientId() + "_content_" + i, "class", "ck_accordionContent", "style", "display: none;");
108    
109                            writer.element("div");
110                            if (renderDetailsRaw)
111                                    writer.writeRaw(detail);
112                            else
113                                    writer.write(detail);
114                            writer.end(); // overViewContent
115    
116                            writer.end(); // overViewContent
117                    }
118            }
119    
120            void afterRender(MarkupWriter writer)
121            {
122                    writer.end(); // main div
123                    javascriptSupport.addScript("new Ck.Accordion('%s', {duration: %s});", getClientId(), duration);
124            }
125    
126            /**
127             * Returns a unique id for the element. This value will be unique for any given rendering of a
128             * page. This value is intended for use as the id attribute of the client-side element, and will
129             * be used with any DHTML/Ajax related JavaScript.
130             */
131            public String getClientId()
132            {
133                    return assignedClientId;
134            }
135    }