Package com.liferay.faces.alloy.component.tabview

Source Code of com.liferay.faces.alloy.component.tabview.TabViewRenderer

/**
* Copyright (c) 2000-2014 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.faces.alloy.component.tabview;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;

import com.liferay.faces.alloy.component.tab.Tab;
import com.liferay.faces.alloy.component.tab.TabSelectEvent;
import com.liferay.faces.alloy.component.tab.TabUtil;
import com.liferay.faces.alloy.renderkit.AlloyRendererUtil;
import com.liferay.faces.util.component.ComponentUtil;
import com.liferay.faces.util.component.Styleable;
import com.liferay.faces.util.helper.IntegerHelper;
import com.liferay.faces.util.lang.StringPool;
import com.liferay.faces.util.logging.Logger;
import com.liferay.faces.util.logging.LoggerFactory;
import com.liferay.faces.util.render.RendererUtil;


/**
* This class is a JSF {@link Renderer} for the aui:tabView component.
*
* @author  Neil Griffin
* @author  Vernon Singleton
*/
//J-
@FacesRenderer(componentFamily = TabView.COMPONENT_FAMILY, rendererType = TabView.RENDERER_TYPE)
@ResourceDependencies(
  {
    @ResourceDependency(library = "liferay-faces-alloy", name = "alloy.css"),
    @ResourceDependency(library = "liferay-faces-alloy", name = "alloy.js"),
    @ResourceDependency(library = "liferay-faces-reslib", name = "build/aui-css/css/bootstrap.min.css"),
    @ResourceDependency(library = "liferay-faces-reslib", name = "build/aui/aui-min.js"),
    @ResourceDependency(library = "liferay-faces-reslib", name = "liferay.js")
  }
)
//J+
public class TabViewRenderer extends TabViewRendererBase {

  // Private Constants
  private static final String NAV_NAV_TABS = "nav nav-tabs";
  private static final String SELECTED_TAB_HEADER_CLASSES = "tab yui3-widget active tab-selected";
  private static final String SELECTION_CHANGE = "selectionChange";
  private static final String SRC_NODE = "srcNode";
  private static final String TAB_CONTENT = "tab-content";
  private static final String UNSELECTED_TAB_HEADER_CLASSES = "tab yui3-widget";

  // Logger
  private static final Logger logger = LoggerFactory.getLogger(TabViewRenderer.class);

  @Override
  public void decodeClientState(FacesContext facesContext, UIComponent uiComponent) {

    // Apply the client-side state of the selected index.
    TabView tabView = (TabView) uiComponent;
    String hiddenFieldName = tabView.getClientId(facesContext) + SELECTED_INDEX;
    Map<String, String> requestParameterMap = facesContext.getExternalContext().getRequestParameterMap();
    String selectedIndex = requestParameterMap.get(hiddenFieldName);

    if (selectedIndex != null) {
      tabView.setSelectedIndex(IntegerHelper.toInteger(selectedIndex, -1));
    }
  }

  @Override
  public void encodeChildren(FacesContext facesContext, UIComponent uiComponent) throws IOException {

    // Get the "value" and "var" attributes of the TabView component and determine if iteration should take place
    // using a prototype child tab.
    TabView tabView = (TabView) uiComponent;
    Integer selectedIndex = tabView.getSelectedIndex();
    Object value = tabView.getValue();
    String var = tabView.getVar();
    boolean iterateOverDataModel = ((value != null) && (var != null));
    Tab prototypeChildTab = null;

    if (uiComponent instanceof TabView) {
      prototypeChildTab = TabUtil.getFirstChildTab(tabView);
    }

    // Encode the starting <ul> unordered list element that represents the list of clickable tabs.
    ResponseWriter responseWriter = facesContext.getResponseWriter();
    responseWriter.startElement(StringPool.UL, tabView);
    RendererUtil.encodeStyleable(responseWriter, tabView, NAV_NAV_TABS);

    if (iterateOverDataModel) {

      if (prototypeChildTab != null) {

        int rowCount = tabView.getRowCount();

        for (int i = 0; i < rowCount; i++) {
          tabView.setRowIndex(i);

          boolean selected = ((selectedIndex != null) && (i == selectedIndex));
          encodeTabListItem(facesContext, responseWriter, prototypeChildTab, selected);
        }

        tabView.setRowIndex(-1);

      }
      else {
        logger.warn("Unable to iterate because aui:tabView does not have an aui:tab child element.");
      }
    }
    else {
      List<UIComponent> children = uiComponent.getChildren();
      int childCount = children.size();

      for (int i = 0; i < childCount; i++) {
        UIComponent child = children.get(i);

        if ((child instanceof Tab) && child.isRendered()) {
          Tab childTab = (Tab) child;
          boolean selected = ((selectedIndex != null) && (i == selectedIndex));
          encodeTabListItem(facesContext, responseWriter, childTab, selected);
        }
        else {
          logger.warn("Unable to render child element of alloy:tabView since it is not alloy:tab");
        }
      }
    }

    responseWriter.endElement(StringPool.UL);

    // Encode the starting <div> element that represents the content for the selected tab.
    responseWriter.startElement(StringPool.DIV, uiComponent);
    RendererUtil.encodeStyleable(responseWriter, (Styleable) uiComponent, TAB_CONTENT);

    // Encode the content for each tab.
    if ((iterateOverDataModel) && (prototypeChildTab != null)) {
      int rowCount = tabView.getRowCount();

      for (int i = 0; i < rowCount; i++) {
        tabView.setRowIndex(i);
        prototypeChildTab.encodeAll(facesContext);
      }
    }
    else {
      List<UIComponent> children = tabView.getChildren();

      for (int i = 0; i < children.size(); i++) {
        UIComponent child = children.get(i);

        if (child.isRendered()) {
          child.encodeAll(facesContext);
        }
      }
    }

    tabView.setRowIndex(-1);

    // Encode the closing </div> element for the content.
    responseWriter.endElement(StringPool.DIV);
  }

  @Override
  public void encodeClientState(FacesContext facesContext, ResponseWriter responseWriter, UIComponent uiComponent)
    throws IOException {

    // Encode the hidden field that contains the client-side state of the selected index.
    TabView tabView = (TabView) uiComponent;
    responseWriter.startElement(StringPool.INPUT, tabView);

    String hiddenFieldName = tabView.getClientId(facesContext) + SELECTED_INDEX;
    responseWriter.writeAttribute(StringPool.ID, hiddenFieldName, null);
    responseWriter.writeAttribute(StringPool.NAME, hiddenFieldName, null);
    responseWriter.writeAttribute(StringPool.TYPE, StringPool.HIDDEN, null);
    responseWriter.writeAttribute(StringPool.VALUE, tabView.getSelectedIndex(), null);
    responseWriter.endElement(StringPool.INPUT);

  }

  @Override
  public void encodeJavaScriptCustom(FacesContext facesContext, UIComponent uiComponent) throws IOException {

    // The outermost div was initially styled with "display:none;" in order to prevent blinking when Alloy's
    // JavaScript attempts to hide the div. At this point in JavaScript execution, Alloy is done manipulating the
    // DOM and it is necessary to set the style back to "display:block;" so that the component will be visible.

    // A.one('#tabViewExample\x5c\x3atabViewForm\x5c\x3aj\x5fidt73')._node['style'].display = 'block';
    ResponseWriter responseWriter = facesContext.getResponseWriter();
    responseWriter.write(AlloyRendererUtil.A_DOT_ONE);
    responseWriter.write(StringPool.OPEN_PARENTHESIS);
    responseWriter.write(StringPool.APOSTROPHE);

    String clientId = uiComponent.getClientId(facesContext);
    String escapedClientId = StringPool.POUND + RendererUtil.escapeClientId(clientId);
    responseWriter.write(escapedClientId);
    responseWriter.write("')._node['style'].display='block';");

    // Encode a script that will handle the client-side state of the selected tab index, as well as submitting
    // Ajax requests to support server-side events.
    TabView tabView = (TabView) uiComponent;

    // var clientVarName = Liferay.component('clientKey');
    String clientVarName = ComponentUtil.getClientVarName(facesContext, tabView);
    String clientKey = tabView.getClientKey();

    if (clientKey == null) {
      clientKey = clientVarName;
    }

    // var clientVar = Liferay.component('clientVarName');
    // var tabViewExample_tabViewForm_j_idt73 = Liferay.component('tabViewExample\x5ftabViewForm\x5fj\x5fidt73');
    encodeLiferayComponentVar(responseWriter, clientVarName, clientKey);

    // clientIdselectedIndex
    String hiddenFieldId = clientId + SELECTED_INDEX;

    // tabViewExample_tabViewForm_j_idt73.after('selectionChange', function(event){
    responseWriter.write(clientVarName);
    responseWriter.write(StringPool.PERIOD);
    responseWriter.write(StringPool.AFTER);
    responseWriter.write(StringPool.OPEN_PARENTHESIS); // begin call to "after" method
    responseWriter.write(StringPool.APOSTROPHE);
    responseWriter.write(SELECTION_CHANGE);
    responseWriter.write(StringPool.APOSTROPHE);
    responseWriter.write(StringPool.COMMA_AND_SPACE);
    responseWriter.write("function(event){ "); // begin function to call after selectionChange

    // var hidden = document.getElementById('tabViewExample:tabViewForm:j_idt73selectedIndex');
    responseWriter.write("var hidden=document.getElementById('");
    responseWriter.write(hiddenFieldId);
    responseWriter.write(StringPool.APOSTROPHE);
    responseWriter.append(StringPool.CLOSE_PARENTHESIS);
    responseWriter.append(StringPool.SEMICOLON);

    responseWriter.write("var prevTabIndex=hidden.value;");

    responseWriter.write(
      "if(event.newVal){hidden.value=event.newVal.get('index');}else if (prevTabIndex==event.newVal.get('index')){hidden.value='';};");

    Map<String, List<ClientBehavior>> clientBehaviorMap = tabView.getClientBehaviors();
    Collection<String> eventNames = tabView.getEventNames();

    for (String eventName : eventNames) {
      List<ClientBehavior> clientBehaviorsForEvent = clientBehaviorMap.get(eventName);

      if (clientBehaviorsForEvent != null) {

        for (ClientBehavior clientBehavior : clientBehaviorsForEvent) {

          ClientBehaviorContext clientBehaviorContext = ClientBehaviorContext.createClientBehaviorContext(
              facesContext, tabView, eventName, clientId, null);
          String clientBehaviorScript = clientBehavior.getScript(clientBehaviorContext);

          // If <f:ajax event="tabSelected" /> is specified in the view, then render a script that submits
          // an Ajax request.
          if (TabSelectEvent.TAB_SELECT.equals(eventName)) {

            //J-
            // if (event.newVal) {
            //     jsf.ajax.request(this, event, {'javax.faces.behavior.event': 'tabExpanded'});
            // }
            //J+
            responseWriter.write("if(event.newVal)");
            responseWriter.write(StringPool.OPEN_CURLY_BRACE);
            responseWriter.write(clientBehaviorScript);
            responseWriter.write(StringPool.CLOSE_CURLY_BRACE);
          }
        }
      }
    }

    responseWriter.write(StringPool.CLOSE_CURLY_BRACE); // end function to call after selectionChange
    responseWriter.write(StringPool.CLOSE_PARENTHESIS); // end call to "after" method
    responseWriter.write(StringPool.SEMICOLON);

    int tabIndex = 0;
    List<UIComponent> children = tabView.getChildren();

    for (UIComponent child : children) {

      if ((child instanceof Tab) && child.isRendered()) {
        Tab childTab = (Tab) child;

        if (childTab.isDisabled()) {
          responseWriter.write(clientVarName);
          responseWriter.write(".disableTab(");
          responseWriter.write(Integer.toString(tabIndex));
          responseWriter.write(");");
        }
        else {
          responseWriter.write(clientVarName);
          responseWriter.write(".enableTab(");
          responseWriter.write(Integer.toString(tabIndex));
          responseWriter.write(");");
        }

        tabIndex++;
      }
    }
  }

  @Override
  public void encodeMarkupBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {

    // Encode the starting <div> element that represents the component.
    ResponseWriter responseWriter = facesContext.getResponseWriter();
    responseWriter.startElement(StringPool.DIV, uiComponent);
    responseWriter.writeAttribute(StringPool.ID, uiComponent.getClientId(facesContext), StringPool.ID);
    RendererUtil.encodeStyleable(responseWriter, (Styleable) uiComponent);
  }

  @Override
  public void encodeMarkupEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException {

    // Encode the closing </div> element.
    ResponseWriter responseWriter = facesContext.getResponseWriter();
    responseWriter.endElement(StringPool.DIV);
  }

  @Override
  protected void encodeHiddenAttributes(FacesContext facesContext, ResponseWriter responseWriter, TabView tabView,
    boolean first) throws IOException {

    encodeWidgetRender(responseWriter, first);

    first = false;

    encodeClientId(responseWriter, SRC_NODE, tabView.getClientId(facesContext), first);
  }

  protected void encodeTabListItem(FacesContext facesContext, ResponseWriter responseWriter, Tab tab,
    boolean selected) throws IOException {

    responseWriter.startElement(StringPool.LI, tab);

    // Encode the div's class attribute according to the specified tab's selected/un-selected state.
    String tabClasses = UNSELECTED_TAB_HEADER_CLASSES;

    if (selected) {
      tabClasses = SELECTED_TAB_HEADER_CLASSES;
    }

    // If the specified tab has a headerClass, then append it to the class attribute before encoding.
    String tabHeaderClass = tab.getHeaderClass();

    if (tabHeaderClass != null) {
      tabClasses += StringPool.SPACE + tabHeaderClass;
    }

    responseWriter.writeAttribute(StringPool.CLASS, tabClasses, Styleable.STYLE_CLASS);
    responseWriter.startElement("a", tab);

    if (tab.isDisabled()) {
      responseWriter.writeAttribute(StringPool.DISABLED, StringPool.DISABLED, null);
    }

    responseWriter.writeAttribute(StringPool.HREF, StringPool.POUND + tab.getClientId(facesContext), null);

    // If the header facet exists for the specified tab, then encode the header facet.
    UIComponent headerFacet = tab.getFacet(StringPool.HEADER);

    if (headerFacet != null) {
      headerFacet.encodeAll(facesContext);
    }

    // Otherwise, render the label of the specified tab.
    else {
      String headerText = (String) tab.getHeaderText();

      if (headerText != null) {
        responseWriter.write(headerText);
      }
    }

    responseWriter.endElement("a");
    responseWriter.endElement(StringPool.LI);
  }

  @Override
  public boolean getRendersChildren() {
    return true;
  }
}
TOP

Related Classes of com.liferay.faces.alloy.component.tabview.TabViewRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.