Package org.odlabs.wiquery.ui.tabs

Source Code of org.odlabs.wiquery.ui.tabs.Tabs$ITabsAjaxEvent

/*
* Copyright (c) 2009 WiQuery team
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.odlabs.wiquery.ui.tabs;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.request.cycle.RequestCycle;
import org.odlabs.wiquery.core.events.MouseEvent;
import org.odlabs.wiquery.core.javascript.JsQuery;
import org.odlabs.wiquery.core.javascript.JsScopeContext;
import org.odlabs.wiquery.core.javascript.JsStatement;
import org.odlabs.wiquery.core.options.ArrayItemOptions;
import org.odlabs.wiquery.core.options.EventLabelOptions;
import org.odlabs.wiquery.core.options.ICollectionItemOptions;
import org.odlabs.wiquery.core.options.IComplexOption;
import org.odlabs.wiquery.core.options.IntegerItemOptions;
import org.odlabs.wiquery.core.options.Options;
import org.odlabs.wiquery.ui.core.JsScopeUiEvent;
import org.odlabs.wiquery.ui.options.HeightStyleEnum;
import org.odlabs.wiquery.ui.widget.WidgetJavaScriptResourceReference;

/**
* $Id$
* <p>
* Create a tab panel.
* </p>
*
* @author Lionel Armanet
* @since 0.9
*/
public class Tabs extends WebMarkupContainer
{
  // Constantes
  /** Constant of serialization */
  private static final long serialVersionUID = 2L;

  /**
   * Properties on the ui parameter (use it into callback functions) : anchor element of
   * the selected tab
   */
  public static final String UI_TAB = "ui.newTab";

  /**
   * Properties on the ui parameter (use it into callback functions) : element, that
   * contains the selected tab contents
   */
  public static final String UI_PANEL = "ui.newPanel";

  /**
   * Properties on the ui parameter (use it into callback functions) : zero-based index
   * of the selected tab
   */
  public static final String UI_INDEX = "ui.newTab.index()";
 
  /**
   * Options are used to customize this component.
   */
  private Options options;

  /**
   *    The tab event.
   */
  public static enum TabEvent
  {
    activate,
    beforeActivate,
    beforeLoad,
    load
  }

  /**
   * This class is only needed to make public the method generateCallbackScript.
   *
   * @author Ernesto Reinaldo Barreiro
   */
  private abstract static class TabsAjaxBehavior extends AbstractDefaultAjaxBehavior
  {

    private static final long serialVersionUID = 1L;
   
    private List<String> extraDynParams;
   

    public TabsAjaxBehavior()
    {
    }
   

    @Override
    protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
    {
      if (extraDynParams != null)
      {
        attributes.getDynamicExtraParameters().addAll(extraDynParams);
      }
    }
   
    protected void setDynParams(List<String> list)
    {
      this.extraDynParams = list;
    }   
  }

  /*
   * AJAX behavior needed for AJAX call-backs.
   */
  private TabsAjaxBehavior tabsAjaxBehavior;

  /*
   * The tab event.
   */
  public static final String TAB_EVENT = "tabEvent";

  public static final String TAB_INDEX = "tabIndex";

  /**
   * Utility class for handling tabs AJAX events.
   *
   * @author Ernesto Reinaldo Barreiro (reiern70@gmail.com)
   */
  private static class TabsAjaxJsScopeUiEvent extends JsScopeUiEvent
  {

    private static final long serialVersionUID = 1L;

    private TabEvent event;

    private Tabs tabs;

    public TabsAjaxJsScopeUiEvent(Tabs tabs, TabEvent event)
    {
      super();
      this.tabs = tabs;
      this.event = event;
    }

    @Override
    protected void execute(JsScopeContext scopeContext)
    {
      tabs.tabsAjaxBehavior.setDynParams(Arrays.asList(String.format(
          "return {'%s': '%s', '%s': %s}", TAB_EVENT, event.name(),
          TAB_INDEX, UI_INDEX)));

        scopeContext.append(
        // delegating call-back generation to AJAX behavior
        // so that we don't miss 'decorator' related functionality.
        tabs.tabsAjaxBehavior.getCallbackScript());

    }
  }

  /**
   * Specific function for beforeActivate event.
   *
   * @author reiern70
   */
  public static class TabsAjaxBeforeActivateJsScopeUiEvent extends TabsAjaxJsScopeUiEvent
  {
    private static final long serialVersionUID = 1L;

    private boolean cancelSelect = false;

    public TabsAjaxBeforeActivateJsScopeUiEvent(Tabs tabs, TabEvent event, boolean cancelSelect)
    {
      super(tabs, event);
      this.cancelSelect = cancelSelect;
    }

    @Override
    protected void execute(JsScopeContext scopeContext)
    {
      super.execute(scopeContext);
      scopeContext.append("return " + !cancelSelect);
    }
  }

  /**
   * Call back interface for AJAX Events.
   *
   * @author Ernesto Reinaldo Barreiro (reiern70@gmail.com)
   *
   */
  public interface ITabsAjaxEvent extends Serializable
  {

    /**
     * Call-back method for slider AJAX events.
     *
     * @param target
     *            The AjaxRequestTarget.
     * @param tabs
     *            The tabs to which the event is attached.
     * @param index
     *            Of the tab event
     */
    void onEvent(AjaxRequestTarget target, Tabs tabs, int index);
  }

  /*
   * Map of AJAX events.
   */
  private Map<TabEvent, ITabsAjaxEvent> ajaxEvents = new HashMap<TabEvent, ITabsAjaxEvent>();

  /**
   * Builds a new tabs container with the given wicket id.
   */
  public Tabs(String id)
  {
    super(id);
    options = new Options(this);
    tabsAjaxBehavior = new TabsAjaxBehavior()
    {

      private static final long serialVersionUID = 1L;

      @Override
      protected void respond(AjaxRequestTarget target)
      {
        String tabEvent =
          RequestCycle.get().getRequest().getQueryParameters()
            .getParameterValue(TAB_EVENT).toString();
        // if we have an event execute it.
        if (!isEmpty(tabEvent))
        {
          // calculate the index
          int index =
            parseInteger(RequestCycle.get().getRequest().getQueryParameters()
              .getParameterValue(TAB_INDEX).toString(), 0);

          ITabsAjaxEvent ajaxEvent = ajaxEvents.get(TabEvent.valueOf(tabEvent));
          if (ajaxEvent != null)
          {
            ajaxEvent.onEvent(target, Tabs.this, index);
          }
        }
      }
    };
    add(tabsAjaxBehavior);
  }

  /**
   * Parses an integer.
   *
   * @param value
   *            The value to parse.
   * @return The parsed integer.
   */
  private int parseInteger(String value, int defaultValue)
  {
    try
    {
      return Integer.parseInt(value);
    }
    catch (NumberFormatException e)
    {
      return defaultValue;
    }
  }

  public static boolean isEmpty(String str)
  {
    return (str == null || str.trim().length() == 0);
  }

  @Override
  protected void detachModel()
  {
    super.detachModel();
    options.detach();
  }

  @Override
  public void renderHead(IHeaderResponse response)
  {
    response.render(JavaScriptHeaderItem.forReference(WidgetJavaScriptResourceReference.get()));
    response.render(JavaScriptHeaderItem.forReference(TabsJavaScriptResourceReference.get()));
    response.render(OnDomReadyHeaderItem.forScript(statement().render()));
  }

  public JsStatement statement()
  {
    return new JsQuery(this).$().chain("tabs", options.getJavaScriptOptions());
  }

  /**
   * Method retrieving the options of the component
   *
   * @return the options
   */
  protected Options getOptions()
  {
    return options;
  }

  /*---- Options section ---*/

  /**
   * Set to true to allow an already selected tab to become unselected again upon
   * reselection. (Old version of this option : deselectable)
   *
   * @param collapsible
   * @return instance of the current component
   */
  public Tabs setCollapsible(boolean collapsible)
  {
    options.put("collapsible", collapsible);
    return this;
  }

  /**
   * @return the collapsible option value
   */
  public boolean isCollapsible()
  {
    if (this.options.containsKey("collapsible"))
    {
      return options.getBoolean("collapsible");
    }

    return false;
  }

  /**
   * Disables (true) or enables (false) the tabs. Can be set when initialising (first
   * creating) the tabs.
   *
   * @param disabled
   * @return instance of the current behavior
   */
  public Tabs setDisabled(boolean disabled)
  {
    this.options.put("disabled", disabled);
    return this;
  }

  /**
   * @return the disabled option
   */
  public boolean isDisabled()
  {
    if (this.options.containsKey("disabled"))
    {
      return this.options.getBoolean("disabled");
    }

    return false;
  }

  /**
   * Set an array containing the position of the tabs (zero-based index) that should be
   * disabled on initialization
   *
   * @param disabled
   * @return instance of the current component
   */
  public Tabs setDisabled(ArrayItemOptions<IntegerItemOptions> disabled)
  {
    this.options.put("disabled", disabled);
    return this;
  }

  /**
   * @return the disabled option value
   */
  public ICollectionItemOptions getDisabled()
  {
    return this.options.getCollectionItemOptions("disabled");
  }

  /**
   * Set the type of event to be used for selecting a tab
   *
   * @param event
   * @return instance of the current component
   */
  public Tabs setEvent(EventLabelOptions event)
  {
    this.options.put("event", event);
    return this;
  }

  /**
   * @return the event option value
   */
  public EventLabelOptions getEvent()
  {
    IComplexOption event = this.options.getComplexOption("event");

    if (event instanceof EventLabelOptions)
    {
      return (EventLabelOptions) event;
    }

    return new EventLabelOptions(MouseEvent.CLICK);
  }

  /**
   * If and how to animate the hiding of the panel.
   *
   * @param hideOptions
   * @return instance of the current component
   */
  public Tabs setHide(TabsAnimateOption hideOptions)
  {
    this.options.put("hide", hideOptions);
    return this;
  }
 
  /**
   * @return the hide option value
   */
  public TabsAnimateOption getHide()
  {
    IComplexOption hideOptions = this.options.getComplexOption("hide");
    if (hideOptions instanceof TabsAnimateOption)
    {
      return (TabsAnimateOption) hideOptions;
    }
   
    return null;
  }
 
  /**
   * If and how to animate the showing of the panel.
   *
   * @param showOptions
   * @return instance of the current component
   */
  public Tabs setShow(TabsAnimateOption showOptions)
  {
    this.options.put("show", showOptions);
    return this;
  }
 
  /**
   * @return the show option value
   */
  public TabsAnimateOption getShow()
  {
    IComplexOption showOptions = this.options.getComplexOption("show");
    if (showOptions instanceof TabsAnimateOption)
    {
      return (TabsAnimateOption) showOptions;
    }
   
    return null;
  }

  /**
   * @return the active option value
   */
  public int getActive()
  {
    Integer index = this.options.getInt("active");
    if (index != null)
    {
      return index;
    }
   
    return 0;
  }
 
  /**
   * The zero-based index of the panel that is active (open).
   * A negative value selects panels going backward from the last panel.
   *
   * @param index
   * @return instance of the current component
   */
  public Tabs setActive(int index)
  {
    this.options.put("active", index);
    return this;
  }
 
  /**
   * Setting active to false will collapse all panels.
   * This requires the collapsible option to be true.
   *
   * @param isActive
   * @return instance of the current component
   */
  public Tabs setActive(boolean isActive)
  {
    this.options.put("active", isActive);
    return this;
  }
 
  /**
   * @return the heightStyle option value
   */
  public HeightStyleEnum getHeightStyle()
  {
    String literal = this.options.getLiteral("heightStyle");
    return literal == null ? HeightStyleEnum.CONTENT : HeightStyleEnum.valueOf(literal.toUpperCase());
  }
 
  /**
   * Controls the height of the tabs widget and each panel. Possible values:
   * <ul>
   *   <li>AUTO: All panels will be set to the height of the tallest panel.</li>
   *   <li>FILL: Expand to the available height based on the tabs' parent height.</li>
   *   <li>CONTENT: Each panel will be only as tall as its content.</li>
   * </ul>
   * @param heightStyle
   * @return
   */
  public Tabs setHeightStyle(HeightStyleEnum heightStyle)
  {
    this.options.putLiteral("heightStyle", heightStyle.name().toLowerCase());
    return this;
  }
 
  /*---- Events section ---*/

  /**
   * Set the callback when the content of a remote tab is about to load.
   *
   * @param beforeLoad
   * @return instance of the current component
   */
  public Tabs setBeforeLoadEvent(JsScopeUiEvent beforeLoad)
  {
    this.options.put("beforeLoad", beforeLoad);
    return this;
  }

  /**
   * Sets the call-back for the AJAX beforeLoad event.
   *
   * @param beforeLoadEvent
   *            The ITabsAjaxEvent.
   */
  public Tabs setAjaxBeforeLoadEvent(ITabsAjaxEvent beforeLoadEvent)
  {
    this.ajaxEvents.put(TabEvent.beforeLoad, beforeLoadEvent);
    setBeforeLoadEvent(new TabsAjaxJsScopeUiEvent(this, TabEvent.beforeLoad));
    return this;
  }
 
  /**
   * Set the callback when the content of a remote tab has been loaded.
   *
   * @param load
   * @return instance of the current component
   */
  public Tabs setLoadEvent(JsScopeUiEvent load)
  {
    this.options.put("load", load);
    return this;
  }

  /**
   * Sets the call-back for the AJAX Load event.
   *
   * @param loadEvent
   *            The ITabsAjaxEvent.
   */
  public Tabs setAjaxLoadEvent(ITabsAjaxEvent loadEvent)
  {
    this.ajaxEvents.put(TabEvent.load, loadEvent);
    setLoadEvent(new TabsAjaxJsScopeUiEvent(this, TabEvent.load));
    return this;
  }

  /**
   * Set the callback when the user is clicking the tab
   *
   * @param beforeActivate
   * @return instance of the current component
   */
  public Tabs setBeforeActivateEvent(JsScopeUiEvent beforeActivate)
  {
    this.options.put("beforeActivate", beforeActivate);
    return this;
  }

  /**
   * Sets the call-back for the AJAX beforeActivate event.
   *
   * @param beforeActivateEvent
   *            The ITabsAjaxEvent.
   */
  public Tabs setAjaxBeforeActivateEvent(ITabsAjaxEvent beforeActivateEvent)
  {
    this.ajaxEvents.put(TabEvent.beforeActivate, beforeActivateEvent);
    setBeforeActivateEvent(new TabsAjaxBeforeActivateJsScopeUiEvent(this, TabEvent.beforeActivate, false));
    return this;
  }

  /**
   * Sets the call-back for the AJAX beforeActivate event.
   *
   * @param beforeActivateEvent
   *            The ITabsAjaxEvent.
   * @param cancelSelect
   *            If select should be cancelled.
   */
  public Tabs setAjaxBeforeActivateEvent(ITabsAjaxEvent beforeActivateEvent, boolean cancelSelect)
  {
    this.ajaxEvents.put(TabEvent.beforeActivate, beforeActivateEvent);
    setBeforeActivateEvent(new TabsAjaxBeforeActivateJsScopeUiEvent(this, TabEvent.beforeActivate, cancelSelect));
    return this;
  }

  /**
   * Set the callback when a tab is activated.
   *
   * @param activate
   * @return instance of the current component
   */
  public Tabs setActivateEvent(JsScopeUiEvent activate)
  {
    this.options.put("activate", activate);
    return this;
  }

  /**
   * Sets the call-back for the AJAX activate event.
   *
   * @param activateEvent
   *            The ITabsAjaxEvent.
   */
  public Tabs setAjaxActivateEvent(ITabsAjaxEvent activateEvent)
  {
    this.ajaxEvents.put(TabEvent.activate, activateEvent);
    setActivateEvent(new TabsAjaxJsScopeUiEvent(this, TabEvent.activate));
    return this;
  }

  /*---- Methods section ---*/

  /**
   * Method to destroy the tabs This will return the element back to its pre-init state.
   *
   * @return the associated JsStatement
   */
  public JsStatement destroy()
  {
    return new JsQuery(this).$().chain("tabs", "'destroy'");
  }

  /**
   * Method to destroy the tabs within the ajax request
   *
   * @param ajaxRequestTarget
   */
  public void destroy(AjaxRequestTarget ajaxRequestTarget)
  {
    ajaxRequestTarget.appendJavaScript(this.destroy().render().toString());
  }

  /**
   * Method to disable the tabs
   *
   * @return the associated JsStatement
   */
  public JsStatement disable()
  {
    return new JsQuery(this).$().chain("tabs", "'disable'");
  }

  /**
   * Method to disable the tabs within the ajax request
   *
   * @param ajaxRequestTarget
   */
  public void disable(AjaxRequestTarget ajaxRequestTarget)
  {
    ajaxRequestTarget.appendJavaScript(this.disable().render().toString());
  }

  /**
   * Method to disable a tab
   *
   * @param index
   *            Index tab to disable
   * @return the associated JsStatement
   */
  public JsStatement disable(int index)
  {
    return new JsQuery(this).$().chain("tabs", "'disable'", Integer.toString(index));
  }

  /**
   * Method to disable a tab within the ajax request
   *
   * @param index
   *            Index tab to disable
   * @param ajaxRequestTarget
   */
  public void disable(AjaxRequestTarget ajaxRequestTarget, int index)
  {
    ajaxRequestTarget.appendJavaScript(this.disable(index).render().toString());
  }

  /**
   * Method to enable the tabs
   *
   * @return the associated JsStatement
   */
  public JsStatement enable()
  {
    return new JsQuery(this).$().chain("tabs", "'enable'");
  }

  /**
   * Method to enable the tabs within the ajax request
   *
   * @param ajaxRequestTarget
   */
  public void enable(AjaxRequestTarget ajaxRequestTarget)
  {
    ajaxRequestTarget.appendJavaScript(this.enable().render().toString());
  }

  /**
   * Method to enable a tab
   *
   * @param index
   *            Index tab to enable
   * @return the associated JsStatement
   */
  public JsStatement enable(int index)
  {
    return new JsQuery(this).$().chain("tabs", "'enable'", Integer.toString(index));
  }

  /**
   * Method to enable a tab within the ajax request
   *
   * @param index
   *            Index tab to enable
   * @param ajaxRequestTarget
   */
  public void enable(AjaxRequestTarget ajaxRequestTarget, int index)
  {
    ajaxRequestTarget.appendJavaScript(this.enable(index).render().toString());
  }

  /**
   * Method to reload the content of an Ajax tab programmatically
   *
   * @param index
   *            Index tab to select
   * @return the associated JsStatement
   */
  public JsStatement load(int index)
  {
    return new JsQuery(this).$().chain("tabs", "'load'", Integer.toString(index));
  }

  /**
   * Method to reload the content of an Ajax tab programmatically within the ajax
   * request
   *
   * @param index
   *            Index tab to select
   * @param ajaxRequestTarget
   */
  public void load(AjaxRequestTarget ajaxRequestTarget, int index)
  {
    ajaxRequestTarget.appendJavaScript(this.load(index).render().toString());
  }

  /**
   * Returns the {@link JsStatement} to refresh tabs.
   *
   * @return a non null {@link JsStatement}.
   */
  public JsStatement refresh()
  {
    return new JsQuery(this).$().chain("tabs", "'refresh'");
  }

  /**
   * Method to refresh tabs within the ajax request
   *
   * @param ajaxRequestTarget
   */
  public void refresh(AjaxRequestTarget ajaxRequestTarget)
  {
    ajaxRequestTarget.appendJavaScript(this.refresh().render().toString());
  }

  /**
   * Method to returns the .ui-slider element
   *
   * @return the associated JsStatement
   */
  public JsStatement widget()
  {
    return new JsQuery(this).$().chain("tabs", "'widget'");
  }

  /**
   * Method to returns the .ui-slider element within the ajax request
   *
   * @param ajaxRequestTarget
   */
  public void widget(AjaxRequestTarget ajaxRequestTarget)
  {
    ajaxRequestTarget.appendJavaScript(this.widget().render().toString());
  }
}
TOP

Related Classes of org.odlabs.wiquery.ui.tabs.Tabs$ITabsAjaxEvent

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.