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