001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.sys.document.web;
017    
018    import java.util.List;
019    
020    import javax.servlet.jsp.JspException;
021    import javax.servlet.jsp.PageContext;
022    import javax.servlet.jsp.tagext.Tag;
023    
024    import org.apache.commons.lang.StringUtils;
025    import org.kuali.kfs.sys.KFSConstants;
026    import org.kuali.kfs.sys.document.datadictionary.AccountingLineViewHideShowLinesDefinition;
027    import org.kuali.kfs.sys.document.web.renderers.HideShowBlockRenderer;
028    import org.kuali.rice.kns.util.WebUtils;
029    import org.kuali.rice.kns.web.ui.Field;
030    
031    /**
032     * A renderable element that renders child elements within a div that can be hidden or displayed
033     */
034    public class HideShowBlock implements RenderableElement {
035        private List<AccountingLineTableRow> contentRows; 
036        private AccountingLineViewHideShowLinesDefinition definition;
037        private AccountingLineRenderingContext renderingContext;
038        private String tabKey;
039    
040        /**
041         * Has child table rows add any fields they know about to the List
042         * @see org.kuali.kfs.sys.document.web.RenderableElement#appendFields(java.util.List)
043         */
044        public void appendFields(List<Field> fields) {
045           for (AccountingLineTableRow row : contentRows) {
046               row.appendFields(fields);
047           }
048        }
049    
050        /**
051         * This is not an action block
052         * @see org.kuali.kfs.sys.document.web.RenderableElement#isActionBlock()
053         */
054        public boolean isActionBlock() {
055            return false;
056        }
057    
058        /**
059         * Checks if all of the child rows are empty or not; if one isn't empty, then this isn't empty
060         * @see org.kuali.kfs.sys.document.web.RenderableElement#isEmpty()
061         */
062        public boolean isEmpty() {
063            for (AccountingLineTableRow row : contentRows) {
064                if (!row.isEmpty()) return false;
065            }
066            return true;
067        }
068    
069        /**
070         * Checks if all the child rows are hidden; if so, then no point in showing this...
071         * @see org.kuali.kfs.sys.document.web.RenderableElement#isHidden()
072         */
073        public boolean isHidden() {
074            for (AccountingLineTableRow row : contentRows) {
075                if (!row.isHidden()) return false;
076            }
077            return true;
078        }
079    
080        /**
081         * Has child rows populate with the tab index
082         * @see org.kuali.kfs.sys.document.web.RenderableElement#populateWithTabIndexIfRequested(int)
083         */
084        public void populateWithTabIndexIfRequested(int reallyHighIndex) {
085            for (AccountingLineTableRow row : contentRows) {
086                row.populateWithTabIndexIfRequested(reallyHighIndex);
087            }
088        }
089    
090        /**
091         * Uses a HideShowBlockRenderer to render this element
092         * @see org.kuali.kfs.sys.document.web.RenderableElement#renderElement(javax.servlet.jsp.PageContext, javax.servlet.jsp.tagext.Tag, org.kuali.kfs.sys.document.web.AccountingLineRenderingContext)
093         */
094        public void renderElement(PageContext pageContext, Tag parentTag, AccountingLineRenderingContext renderingContext) throws JspException {
095            this.renderingContext = renderingContext;
096            
097            HideShowBlockRenderer renderer = new HideShowBlockRenderer();
098            renderer.setHideShowBlock(this);
099            renderer.render(pageContext, parentTag);
100            
101            this.renderingContext = null;
102        }
103        
104        /**
105         * Forces all children rows to render themselves
106         * @param pageContext the pageContext to render to
107         * @param parentTag the tag requesting all this rendering
108         * @throws JspException thrown if something goes wrong
109         */
110        public void renderChildRows(PageContext pageContext, Tag parentTag) throws JspException {
111            for (AccountingLineTableRow row : contentRows) {
112                row.renderElement(pageContext, parentTag, renderingContext);
113            }
114        }
115    
116        /**
117         * Gets the contentRows attribute. 
118         * @return Returns the contentRows.
119         */
120        public List<AccountingLineTableRow> getContentRows() {
121            return contentRows;
122        }
123    
124        /**
125         * Sets the contentRows attribute value.
126         * @param contentRows The contentRows to set.
127         */
128        public void setContentRows(List<AccountingLineTableRow> contentRows) {
129            this.contentRows = contentRows;
130        }
131    
132        /**
133         * Sets the definition attribute value.
134         * @param definition The definition to set.
135         */
136        public void setDefinition(AccountingLineViewHideShowLinesDefinition definition) {
137            this.definition = definition;
138        }
139    
140        /** 
141         * @return the tab key for this hide/show block
142         */
143        public String getTabKey() {
144            if (tabKey == null) {
145                tabKey = WebUtils.generateTabKey(renderingContext.getGroupLabel()+definition.getLabel()) + "-" + renderingContext.getAccountingLinePropertyPath().replaceAll("\\.","-").replaceAll("\\[", "(").replaceAll("\\]", ")");
146            }
147            return tabKey;
148        }
149        
150        /**
151         * @return the current tab state
152         */
153        public String getTabState() {
154            String tabState = renderingContext.getTabState(getTabKey());
155            return StringUtils.isNotBlank(tabState) ? tabState : "CLOSE";
156        }
157        
158        /**
159         * Determines if this tab should currently be showing or not
160         * @return true if the tab shows its contents; false otherwise
161         */
162        public boolean isShowing() {
163            return getTabState().equals("OPEN");
164        }
165        
166        /**
167         * @return the label for this hide/show block
168         */
169        public String getLabel() {
170            return definition.getLabel();
171        }
172        
173        /**
174         * @return the concatenation of the group label and this block's label
175         */
176        public String getFullLabel() {
177            return renderingContext.getGroupLabel()+(!StringUtils.isBlank(definition.getLabel()) ? " "+definition.getLabel() : " Hide/Show Block");
178        }
179    }