All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.webui.jsf.renderkit.html.EditableListRenderer Maven / Gradle / Ivy

There is a newer version: 4.4.0.1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2007-2018 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://oss.oracle.com/licenses/CDDL+GPL-1.1
 * or LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

/*
 * $Id: EditableListRenderer.java,v 1.1.12.1 2009-12-29 04:52:46 jyeary Exp $
 */
/*
 * EditableListRenderer.java
 *
 * Created on December 23, 2004, 11:11 AM
 */
package com.sun.webui.jsf.renderkit.html;

import com.sun.faces.annotation.Renderer;
import java.io.IOException;
import java.util.Map;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import com.sun.webui.jsf.component.ComplexComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import com.sun.webui.jsf.component.EditableList;
import com.sun.webui.jsf.component.ListSelector;
import com.sun.webui.theme.Theme;
import com.sun.webui.jsf.theme.ThemeStyles;
import com.sun.webui.jsf.util.JavaScriptUtilities;
import com.sun.webui.jsf.util.RenderingUtilities;
import com.sun.webui.jsf.util.ThemeUtilities;
import org.json.JSONException;
import org.json.JSONObject;

/**
 *
 * @author avk
 */
@Renderer(@Renderer.Renders(componentFamily = "com.sun.webui.jsf.EditableList"))
public class EditableListRenderer extends ListRendererBase {

    private final static boolean DEBUG = false;

    /**
     * 

Render the editable list component * * @param context FacesContext for the current request * @param component UIComponent to be rendered * end should be rendered * * @exception IOException if an input/output error occurs */ @Override public void encodeEnd(FacesContext context, UIComponent component) throws IOException { if (DEBUG) { log("encodeEnd()"); //NOI18N } if (component instanceof EditableList) { renderListComponent((EditableList) component, context, getStyles(component, context)); } else { String message = "Component " + component.toString() + //NOI18N " has been associated with an EditableListRenderer. " + //NOI18N " This renderer can only be used by components " + //NOI18N " that extend com.sun.webui.jsf.component.Selector."; //NOI18N throw new FacesException(message); } } /** * Retrieve user input from the UI. * @param context The FacesContext of this request * @param component The component associated with the renderer */ @Override public void decode(FacesContext context, UIComponent component) { if (DEBUG) { log("decode()"); } EditableList list = (EditableList) component; if (list.isReadOnly()) { if (DEBUG) { log("component is readonly..."); } return; } String id = list.getClientId(context); Map params = context.getExternalContext().getRequestParameterValuesMap(); // The id for the editable list content or "select" element. // If there is a parameter matching listID then // there have been selections made. These are only // respected when the action is remove. // Do it every time, since we cannot know which action // has taken place, an add or a remove. // String listID = null; if (list instanceof ComplexComponent) { listID = list.getLabeledElementId(context); } else { listID = list.getClientId(context); } String[] selections = null; Object parameters = params.get(listID); if (parameters == null) { selections = new String[0]; } else if (parameters instanceof String[]) { selections = (String[]) parameters; } else { selections = new String[1]; selections[0] = parameters.toString(); } // These are the values to remove. // The submitted value for the component will be the // current contents of the select element. // It is important to not reference the values to // remove during an add action. // list.setValuesToRemove(selections); // Always decode the list contents. // This is the only place where the current values of the // list are kept. This is a result of having both the // add and remove buttons set with immediate == true. // With immediate true, update model values does not // occur. In the listbox case, validation does not occur // either therefore the local value of the EditableList // which is the contents of the list, is not updated // either. The current value is stored only in the // submittedValue during the lifecycle of a request // initiated by the add or remove button. // The update model values will only occur when a submit // of the page has occurred. // The decoded field is the hidden field rendered // by the ListRenderer containing the current list contents. String valueID = id.concat(ListSelector.VALUE_ID); super.decode(context, component, valueID); } /** *

This method determines whether the component should be * rendered as a standalone list, or laid out together with a * label that was defined as part of the component.

* *

A label will be rendered if either of the following is * true:

*
    *
  • The page author defined a label facet; or
  • *
  • The page author specified text in the label attribute.
  • *
*

If there is a label, the component will be laid out using a * HTML table. If not, the component will be rendered as a * standalone HTML select element.

* @param component The component associated with the * renderer. Must be a subclass of ListSelector. * @param context The FacesContext of the request * @param styles A String array of styles used to render the * component. The first item of the array is the name of the * JavaScript method that handles change event. The second item is * the style used when the list is enabled. The third style is the * one to use when the list is disabled. The fourth item is the * style to use for an item that is enabled, the fifth to use for * an item that is disabled, and the sixth to use when the item is * selected. * @throws java.io.IOException if the renderer fails to write to * the response */ void renderListComponent(EditableList component, FacesContext context, String[] styles) throws IOException { if (DEBUG) { log("renderListComponent()"); } if (component.isReadOnly()) { UIComponent label = component.getListLabelComponent(); super.renderReadOnlyList(component, label, context, styles[8]); return; } UIComponent headerComponent = component.getFacet(EditableList.HEADER_FACET); UIComponent footerComponent = component.getFacet(EditableList.FOOTER_FACET); boolean gotHeaderOrFooter = (headerComponent != null) || (footerComponent != null); ResponseWriter writer = context.getResponseWriter(); super.renderOpenEncloser(component, context, "div", styles[8]); if (DEBUG) { log("layout the component"); } if (gotHeaderOrFooter) { writer.startElement("table", component); //NOI18N writer.writeText("\n", null); //NOI18N if (headerComponent != null) { addComponentSingleRow(component, headerComponent, context); } // New table row for the list writer.startElement("tr", component); //NOI18N writer.writeText("\n", null); //NOI18N writer.startElement("td", component); //NOI18N writer.writeText("\n", null); //NOI18N } writer.startElement("table", component); //NOI18N writer.writeAttribute("class", styles[9], null); //NOI18N writer.writeText("\n", null); //NOI18N boolean listOnTop = component.isListOnTop(); if (listOnTop) { addListRow(component, context, styles); addFieldRow(component, context, styles); } else { addFieldRow(component, context, styles); addListRow(component, context, styles); } writer.endElement("table"); //NOI18N writer.writeText("\n", null); //NOI18N if (gotHeaderOrFooter) { writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N writer.endElement("tr"); //NOI18N writer.writeText("\n", null); //NOI18N if (footerComponent != null) { addComponentSingleRow(component, footerComponent, context); } writer.endElement("table"); //NOI18N writer.writeText("\n", null); //NOI18N } writer.endElement("div"); //NOI18N renderJavaScript(component, context, writer); } /** * Overrides encodeChildren of Renderer to do nothing. This * renderer renders its own children, but not through this * method. * @param context The FacesContext of the request * @param component The component associated with the * renderer. Must be a subclass of ListSelector. */ @Override public void encodeChildren(javax.faces.context.FacesContext context, javax.faces.component.UIComponent component) throws java.io.IOException { return; } /** *

Renders a component in a table row.

* @param component The component * @param context The FacesContext of the request * @throws java.io.IOException if the renderer fails to write to * the response */ private void addComponentSingleRow(EditableList list, UIComponent component, FacesContext context) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.startElement("tr", list); //NOI18N writer.writeText("\n", null); //NOI18N writer.startElement("td", list); //NOI18N RenderingUtilities.renderComponent(component, context); writer.writeText("\n", null); //NOI18N // Perhaps this should depend on the dir? // writer.writeAttribute("align", "left", null); writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N writer.endElement("tr"); //NOI18N writer.writeText("\n", null); //NOI18N } /** *

Renders the list row

* @param component The component * @param context The FacesContext of the request * @throws java.io.IOException if the renderer fails to write to * the response */ private void addListRow(EditableList component, FacesContext context, String[] styles) throws IOException { // Perhaps this should depend on the dir? // writer.writeAttribute("align", "left", null); UIComponent listLabelComponent = component.getListLabelComponent(); UIComponent removeButtonComponent = component.getRemoveButtonComponent(); ResponseWriter writer = context.getResponseWriter(); // Begin new row for the list label, list & remove button writer.startElement("tr", component); //NOI18N writer.writeText("\n", null); //NOI18N // Render the label in a new table cell writer.startElement("td", component); //NOI18N writer.writeAttribute("class", styles[13], null); //NOI18N writer.writeAttribute("valign", "top", null); //NOI18N writer.writeText("\n", null); //NOI18N RenderingUtilities.renderComponent(listLabelComponent, context); writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N // Render the textfield in a new table cell writer.startElement("td", component); //NOI18N writer.writeAttribute("class", styles[14], null); //NOI18N writer.writeAttribute("valign", "top", null); //NOI18N writer.writeText("\n", null); //NOI18N super.renderHiddenValue(component, context, writer, styles[8]); writer.writeText("\n", null); String id = component.getClientId(context).concat(ListSelector.LIST_ID); super.renderList(component, id, context, styles); writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N // Render the button in a new table cell // Create another table cell for the list and the remove buttons... writer.startElement("td", component); //NOI18N writer.writeAttribute("class", styles[15], null); //NOI18N writer.writeAttribute("valign", "top", null); //NOI18N writer.writeText("\n", null); //NOI18N RenderingUtilities.renderComponent(removeButtonComponent, context); writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N // End the row writer.endElement("tr"); //NOI18N writer.writeText("\n", null); //NOI18N } /** *

Renders the list row

* @param component The component * @param context The FacesContext of the request * @throws java.io.IOException if the renderer fails to write to * the response */ private void addFieldRow(EditableList component, FacesContext context, String[] styles) throws IOException { // Perhaps this should depend on the dir? // writer.writeAttribute("align", "left", null); UIComponent textfieldLabelComponent = component.getFieldLabelComponent(); UIComponent textfieldComponent = component.getFieldComponent(); UIComponent addButtonComponent = component.getAddButtonComponent(); UIComponent searchButtonComponent = component.getFacet(EditableList.SEARCH_FACET); ResponseWriter writer = context.getResponseWriter(); // Begin new row writer.startElement("tr", component); //NOI18N writer.writeText("\n", null); //NOI18N // Render the label writer.startElement("td", component); //NOI18N writer.writeAttribute("class", styles[10], null); //NOI18N writer.writeText("\n", null); //NOI18N RenderingUtilities.renderComponent(textfieldLabelComponent, context); writer.writeText("\n", null); //NOI18N writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N // Create another table cell for the text field, the add // button and the search button... writer.startElement("td", component); //NOI18N writer.writeAttribute("class", styles[11], null); //NOI18N writer.writeAttribute("valign", "top", null); //NOI18N writer.writeText("\n", null); //NOI18N RenderingUtilities.renderComponent(textfieldComponent, context); writer.writeText("\n", null); //NOI18N writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N // Create another table cell for the text field, the add // button and the search button... writer.startElement("td", component); //NOI18N writer.writeAttribute("class", styles[12], null); //NOI18N writer.writeAttribute("valign", "top", null); //NOI18N writer.writeText("\n", null); //NOI18N RenderingUtilities.renderComponent(addButtonComponent, context); writer.writeText("\n", null); //NOI18N writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N if (searchButtonComponent != null) { writer.startElement("td", component); //NOI18N writer.writeAttribute("class", styles[12], null); //NOI18N writer.writeAttribute("valign", "top", null); //NOI18N writer.writeText("\n", null); //NOI18N RenderingUtilities.renderComponent(searchButtonComponent, context); writer.writeText("\n", null); //NOI18N writer.endElement("td"); //NOI18N writer.writeText("\n", null); //NOI18N } // End the row writer.endElement("tr"); //NOI18N writer.writeText("\n", null); //NOI18N } private void renderJavaScript(UIComponent component, FacesContext context, ResponseWriter writer) throws IOException { try { // Append properties. StringBuffer buff = new StringBuffer(256); JSONObject json = new JSONObject(); json.put("id", component.getClientId(context)); // Append JavaScript. buff.append(JavaScriptUtilities.getModule("editableList")).append("\n") // NOI18N .append(JavaScriptUtilities.getModuleName("editableList.init")) // NOI18N .append("(") //NOI18N .append(json.toString(JavaScriptUtilities.INDENT_FACTOR)).append(");\n") //NOI18N .append(JavaScriptUtilities.getDomNode(context, component)).append(EditableList.UPDATE_BUTTONS_FUNCTION); // Render JavaScript. JavaScriptUtilities.renderJavaScript(component, writer, buff.toString()); } catch (JSONException e) { e.printStackTrace(); } } /** *

Render the appropriate element end, depending on the value of the * type property.

* * @param context FacesContext for the current request * @param monospace UIComponent if true, use the monospace * styles to render the list. * * @exception IOException if an input/output error occurs */ private String[] getStyles(UIComponent component, FacesContext context) { if (DEBUG) { log("getStyles()"); //NOI18N } Theme theme = ThemeUtilities.getTheme(context); StringBuffer onchangeBuffer = new StringBuffer(128); onchangeBuffer.append(((EditableList) component).getOnChange()); onchangeBuffer.append(JavaScriptUtilities.getModuleName("listbox.changed")); //NOI18N onchangeBuffer.append("('"); //NOI18N onchangeBuffer.append(component.getClientId(context)); onchangeBuffer.append("'); return false;"); //NOI18N String[] styles = new String[17]; styles[0] = onchangeBuffer.toString(); //NOI18N styles[1] = theme.getStyleClass(ThemeStyles.LIST); styles[2] = theme.getStyleClass(ThemeStyles.LIST_DISABLED); styles[3] = theme.getStyleClass(ThemeStyles.LIST_OPTION); styles[4] = theme.getStyleClass(ThemeStyles.LIST_OPTION_DISABLED); styles[5] = theme.getStyleClass(ThemeStyles.LIST_OPTION_SELECTED); styles[6] = theme.getStyleClass(ThemeStyles.LIST_OPTION_GROUP); styles[7] = theme.getStyleClass(ThemeStyles.LIST_OPTION_SEPARATOR); styles[8] = theme.getStyleClass(ThemeStyles.HIDDEN); styles[9] = theme.getStyleClass(ThemeStyles.EDITABLELIST_TABLE); styles[10] = theme.getStyleClass(ThemeStyles.EDITABLELIST_FIELD_LABEL); styles[11] = theme.getStyleClass(ThemeStyles.EDITABLELIST_FIELD); styles[12] = theme.getStyleClass(ThemeStyles.EDITABLELIST_ADD_BUTTON); styles[13] = theme.getStyleClass(ThemeStyles.EDITABLELIST_LIST_LABEL); styles[14] = theme.getStyleClass(ThemeStyles.EDITABLELIST_LIST); styles[15] = theme.getStyleClass(ThemeStyles.EDITABLELIST_REMOVE_BUTTON); styles[16] = null; return styles; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy