www/include/scripts/tabcontrol-2.js

Code
Comments
Other
Rev Date Author Line
6159 09 Oct 12 nicklas 1 /* $Id$
6159 09 Oct 12 nicklas 2   ------------------------------------------------------------------
6159 09 Oct 12 nicklas 3   Copyright (C) 2012 Nicklas Nordborg
6159 09 Oct 12 nicklas 4
6159 09 Oct 12 nicklas 5   This file is part of BASE - BioArray Software Environment.
6159 09 Oct 12 nicklas 6   Available at http://base.thep.lu.se/
6159 09 Oct 12 nicklas 7
6159 09 Oct 12 nicklas 8   BASE is free software; you can redistribute it and/or
6159 09 Oct 12 nicklas 9   modify it under the terms of the GNU General Public License
6159 09 Oct 12 nicklas 10   as published by the Free Software Foundation; either version 3
6159 09 Oct 12 nicklas 11   of the License, or (at your option) any later version.
6159 09 Oct 12 nicklas 12
6159 09 Oct 12 nicklas 13   BASE is distributed in the hope that it will be useful,
6159 09 Oct 12 nicklas 14   but WITHOUT ANY WARRANTY; without even the implied warranty of
6159 09 Oct 12 nicklas 15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6159 09 Oct 12 nicklas 16   GNU General Public License for more details.
6159 09 Oct 12 nicklas 17
6159 09 Oct 12 nicklas 18   You should have received a copy of the GNU General Public License
6159 09 Oct 12 nicklas 19   along with BASE. If not, see <http://www.gnu.org/licenses/>.
6159 09 Oct 12 nicklas 20   ------------------------------------------------------------------
6159 09 Oct 12 nicklas 21
6159 09 Oct 12 nicklas 22   JavaScript functions for the TabControl2 taglib.
6159 09 Oct 12 nicklas 23
6159 09 Oct 12 nicklas 24   @author Nicklas
6159 09 Oct 12 nicklas 25   @since 3.3
6159 09 Oct 12 nicklas 26 */
7419 03 Nov 17 nicklas 27 'use strict';
6159 09 Oct 12 nicklas 28
6159 09 Oct 12 nicklas 29 var TabControl = function()
6159 09 Oct 12 nicklas 30 {
6159 09 Oct 12 nicklas 31   var tc = {};
6159 09 Oct 12 nicklas 32   var internal = {};
6159 09 Oct 12 nicklas 33   
6159 09 Oct 12 nicklas 34   /**
6160 10 Oct 12 nicklas 35     Register a function that is responsible for switching 
6160 10 Oct 12 nicklas 36     between tabs. Typically used when a 'virtual' tab is used as
6160 10 Oct 12 nicklas 37     a placeholder for loading a different page in the browser.
6160 10 Oct 12 nicklas 38     Note that validators that have been registered for the current tab
6160 10 Oct 12 nicklas 39     are not automatically called when a custom switch function is used.
6160 10 Oct 12 nicklas 40     The switch function must either call TabControl.setActiveTab() (which also
6160 10 Oct 12 nicklas 41     switches to the new tab) or TabControl.validateActiveTab() if validation
6160 10 Oct 12 nicklas 42     is wanted.
6160 10 Oct 12 nicklas 43   */
6160 10 Oct 12 nicklas 44   tc.setSwitchFunction = function(tabControl, switchFunction)
6160 10 Oct 12 nicklas 45   {
6160 10 Oct 12 nicklas 46     if (!switchFunction || !switchFunction.call) return; // 'switchFunction' is not a function
6160 10 Oct 12 nicklas 47     tabControl = Doc.element(tabControl);
6315 06 Sep 13 nicklas 48     if (!tabControl) return;
6160 10 Oct 12 nicklas 49     tabControl.switchFunction = switchFunction;
6160 10 Oct 12 nicklas 50   }
6160 10 Oct 12 nicklas 51   
6160 10 Oct 12 nicklas 52   /**
6159 09 Oct 12 nicklas 53     Adds a validator callback to the given tab. All registered validators
6159 09 Oct 12 nicklas 54     are called whenever the current tab is about to lose focus due to switching
6160 10 Oct 12 nicklas 55     to another tab or due to form submission. A validator function should
6160 10 Oct 12 nicklas 56     take a single 'event' parameter. The event object is a custom event object
6160 10 Oct 12 nicklas 57     with the 'target' property set to the tab that should be validated.
6160 10 Oct 12 nicklas 58     The validator should return 'true' to indicate successful validation, or
6160 10 Oct 12 nicklas 59     'false' to indicate failure. If at least one validator signals a failure
6160 10 Oct 12 nicklas 60     the entire validation is considered a failure and the default action (tab 
6160 10 Oct 12 nicklas 61     switch, form submission, etc) is cancelled.
6159 09 Oct 12 nicklas 62   */
6315 06 Sep 13 nicklas 63   tc.addTabValidator = function(tab, validator, attributes)
6159 09 Oct 12 nicklas 64   {
6160 10 Oct 12 nicklas 65     if (!validator || !validator.call) return; // 'validator' is not a function
6159 09 Oct 12 nicklas 66     tab = Doc.element(tab);
6315 06 Sep 13 nicklas 67     if (!tab) return;
6315 06 Sep 13 nicklas 68     if (attributes) Data.define(tab, attributes);
6161 10 Oct 12 nicklas 69     tab.addEventListener('base-validate', 
6159 09 Oct 12 nicklas 70         function(event)
6159 09 Oct 12 nicklas 71         {
6160 10 Oct 12 nicklas 72           if (!validator.call(tab, event)) event.preventDefault();
6159 09 Oct 12 nicklas 73         }
6159 09 Oct 12 nicklas 74       );
6159 09 Oct 12 nicklas 75   }
6159 09 Oct 12 nicklas 76   
6159 09 Oct 12 nicklas 77   /**
6161 10 Oct 12 nicklas 78     Adds a listener to a tab that is called whenever that tab is made the active
6161 10 Oct 12 nicklas 79     tab. The listener function should take a single 'event' parameter. The event 
6161 10 Oct 12 nicklas 80     object is a custom event object with the 'target' property set to the tab that 
6161 10 Oct 12 nicklas 81     has been activated.
6161 10 Oct 12 nicklas 82   */
6315 06 Sep 13 nicklas 83   tc.addTabActivateListener = function(tab, listener, attributes)
6161 10 Oct 12 nicklas 84   {
6161 10 Oct 12 nicklas 85     if (!listener || !listener.call) return; // 'listener' is not a function
6161 10 Oct 12 nicklas 86     tab = Doc.element(tab);
6315 06 Sep 13 nicklas 87     if (!tab) return;
6315 06 Sep 13 nicklas 88     if (attributes) Data.define(tab, attributes);
6161 10 Oct 12 nicklas 89     tab.addEventListener('base-activate', listener, false);
6161 10 Oct 12 nicklas 90   }
6161 10 Oct 12 nicklas 91   
6161 10 Oct 12 nicklas 92   
6161 10 Oct 12 nicklas 93   /**
6159 09 Oct 12 nicklas 94     Switch to the given tab. Validators attached to the currently active tab
6159 09 Oct 12 nicklas 95     are called first which may abort the switch. This function returns true of
6160 10 Oct 12 nicklas 96     the switch was successful, false if not or if the current tab is the same
6161 10 Oct 12 nicklas 97     as the given tab. If the switch is sucessful, the 'activate' event is sent
6161 10 Oct 12 nicklas 98     to all listeners registered with TabControl.addTabActivateListener().
6160 10 Oct 12 nicklas 99     @param tab The tab element or id of a tab element to switch to
6159 09 Oct 12 nicklas 100   */
6159 09 Oct 12 nicklas 101   tc.setActiveTab = function(tab)
6159 09 Oct 12 nicklas 102   {
6159 09 Oct 12 nicklas 103     tab = Doc.element(tab);
6315 06 Sep 13 nicklas 104     if (!tab) return;
6159 09 Oct 12 nicklas 105     var tabControl = internal.tabControl(tab);
6159 09 Oct 12 nicklas 106     
6159 09 Oct 12 nicklas 107     if (tabControl.activeTab == tab) return false;
6159 09 Oct 12 nicklas 108     if (!tc.validateActiveTab(tabControl)) return false;
6159 09 Oct 12 nicklas 109   
6159 09 Oct 12 nicklas 110     if (tabControl.activeTab != null)
6159 09 Oct 12 nicklas 111     {
6342 01 Nov 13 nicklas 112       Doc.removeClass(tabControl.activeTab, 'active');
6608 20 Nov 14 nicklas 113       Doc.addClass(tabControl.activeTab, 'interactable');
6159 09 Oct 12 nicklas 114     }
6342 01 Nov 13 nicklas 115     Doc.addClass(tab, 'active');
6608 20 Nov 14 nicklas 116     Doc.removeClass(tab, 'interactable');
6159 09 Oct 12 nicklas 117
6159 09 Oct 12 nicklas 118     tabControl.activeTab = tab;
6159 09 Oct 12 nicklas 119     if (tabControl.activeContent != null)
6159 09 Oct 12 nicklas 120     {
6159 09 Oct 12 nicklas 121       tabControl.activeContent.style.display = 'none';
6159 09 Oct 12 nicklas 122     }
6400 27 Jan 14 nicklas 123     var content = Doc.element(tab.id+'.content');
6159 09 Oct 12 nicklas 124     if (content != null)
6159 09 Oct 12 nicklas 125     {
6159 09 Oct 12 nicklas 126       content.style.display = 'block';
6159 09 Oct 12 nicklas 127       tabControl.activeContent = content;
6159 09 Oct 12 nicklas 128     }
6261 27 Mar 13 nicklas 129
6261 27 Mar 13 nicklas 130     Data.setPageValue('last-tab.'+tabControl.id, tab.id);
6261 27 Mar 13 nicklas 131
6161 10 Oct 12 nicklas 132     var evt = document.createEvent('Event');
6161 10 Oct 12 nicklas 133     evt.initEvent('base-activate', false, true);
6161 10 Oct 12 nicklas 134     tab.dispatchEvent(evt);
6161 10 Oct 12 nicklas 135     
6159 09 Oct 12 nicklas 136     return true;
6159 09 Oct 12 nicklas 137   }
6159 09 Oct 12 nicklas 138   
6160 10 Oct 12 nicklas 139   /**
6160 10 Oct 12 nicklas 140     Validate the currently active tab. If the validation is sucessful or if there
6160 10 Oct 12 nicklas 141     is no active tab 'true' is returned, 'false' if not.
6160 10 Oct 12 nicklas 142     @param tabControl A tab control element or the id of a tab control
6160 10 Oct 12 nicklas 143   */
6159 09 Oct 12 nicklas 144   tc.validateActiveTab = function(tabControl)
6159 09 Oct 12 nicklas 145   {
6159 09 Oct 12 nicklas 146     tabControl = Doc.element(tabControl);
6159 09 Oct 12 nicklas 147     if (!tabControl.activeTab) return true;
6159 09 Oct 12 nicklas 148     return tc.validateTab(tabControl.activeTab);
6159 09 Oct 12 nicklas 149   }
6159 09 Oct 12 nicklas 150   
6160 10 Oct 12 nicklas 151   /**
6160 10 Oct 12 nicklas 152     Validate the given tab. If the validation is sucessful 'true'
6160 10 Oct 12 nicklas 153     is returned, 'false' if not.
6160 10 Oct 12 nicklas 154     @param tab A tab element or the id of a tab
6160 10 Oct 12 nicklas 155   */
6159 09 Oct 12 nicklas 156   tc.validateTab = function(tab)
6159 09 Oct 12 nicklas 157   {
6159 09 Oct 12 nicklas 158     var evt = document.createEvent('Event');
6161 10 Oct 12 nicklas 159     evt.initEvent('base-validate', false, true);
6159 09 Oct 12 nicklas 160     return tab.dispatchEvent(evt);
6159 09 Oct 12 nicklas 161   }
6159 09 Oct 12 nicklas 162   
6159 09 Oct 12 nicklas 163   /**
6160 10 Oct 12 nicklas 164     Get the id for the help section that applies to the currently active tab.
6160 10 Oct 12 nicklas 165     @param tabControl A tab control element or the id of a tab control
6160 10 Oct 12 nicklas 166   */
6160 10 Oct 12 nicklas 167   tc.getActiveHelpId = function(tabControl)
6160 10 Oct 12 nicklas 168   {
6160 10 Oct 12 nicklas 169     tabControl = Doc.element(tabControl);
7419 03 Nov 17 nicklas 170     var tab = tabControl.activeTab;
6160 10 Oct 12 nicklas 171     return tc.getHelpId(tab);
6160 10 Oct 12 nicklas 172   }
6160 10 Oct 12 nicklas 173   
6160 10 Oct 12 nicklas 174   /**
6160 10 Oct 12 nicklas 175     Get the id for the help section that applies to the given tab.
6160 10 Oct 12 nicklas 176     @param tabControl A tab element or the id of a tab
6160 10 Oct 12 nicklas 177   */
6160 10 Oct 12 nicklas 178   tc.getHelpId = function(tab)
6160 10 Oct 12 nicklas 179   {
6160 10 Oct 12 nicklas 180     return tab ? Data.get(tab,  'help-id') : null;
6160 10 Oct 12 nicklas 181   }
6160 10 Oct 12 nicklas 182
6160 10 Oct 12 nicklas 183   /**
6159 09 Oct 12 nicklas 184     Get a reference to the tab-control object that contains the given tab.
6160 10 Oct 12 nicklas 185   */
6159 09 Oct 12 nicklas 186   internal.tabControl = function(tab)
6159 09 Oct 12 nicklas 187   {
6400 27 Jan 14 nicklas 188     return Doc.element(tab.id.substr(0, tab.id.indexOf('.')));
6159 09 Oct 12 nicklas 189   }
6159 09 Oct 12 nicklas 190   
6159 09 Oct 12 nicklas 191   /**
6160 10 Oct 12 nicklas 192     'click' event handler for tabs. If a switch function has been
6160 10 Oct 12 nicklas 193     assigned to the tab control, the switch function is called with the
6160 10 Oct 12 nicklas 194     event as parameter. Otherwise the TabControl.setActiveTab() function
6160 10 Oct 12 nicklas 195     is used to switch to the clicked tab.
6159 09 Oct 12 nicklas 196   */
6159 09 Oct 12 nicklas 197   internal.tabOnClick = function(event)
6159 09 Oct 12 nicklas 198   {
6159 09 Oct 12 nicklas 199     var tab = event.currentTarget;
6160 10 Oct 12 nicklas 200     var tabControl = internal.tabControl(tab);
6160 10 Oct 12 nicklas 201     if (tabControl.switchFunction)
6160 10 Oct 12 nicklas 202     {
6160 10 Oct 12 nicklas 203       tabControl.switchFunction.call(tabControl, event);
6160 10 Oct 12 nicklas 204     }
6160 10 Oct 12 nicklas 205     else
6160 10 Oct 12 nicklas 206     {
6160 10 Oct 12 nicklas 207       tc.setActiveTab(tab);
6160 10 Oct 12 nicklas 208     }
6159 09 Oct 12 nicklas 209   }
6159 09 Oct 12 nicklas 210   
6159 09 Oct 12 nicklas 211   /**
6160 10 Oct 12 nicklas 212     Initializer that add 'onclick' event handlers to all 'tab' elements.
6159 09 Oct 12 nicklas 213   */
6160 10 Oct 12 nicklas 214   internal.addOnClickHandler = function(tab, autoInit)
6159 09 Oct 12 nicklas 215   {
6160 10 Oct 12 nicklas 216     if (autoInit != 'tab') return;
6159 09 Oct 12 nicklas 217     Events.addEventHandler(tab, 'click', internal.tabOnClick);
6159 09 Oct 12 nicklas 218     if (tab.tabIndex >= 0)
6159 09 Oct 12 nicklas 219     {
6159 09 Oct 12 nicklas 220       Events.enableClickOnEnter(tab);
6159 09 Oct 12 nicklas 221     }
6159 09 Oct 12 nicklas 222   }
6160 10 Oct 12 nicklas 223   Doc.addElementInitializer(internal.addOnClickHandler);
6159 09 Oct 12 nicklas 224
6159 09 Oct 12 nicklas 225   /**
6160 10 Oct 12 nicklas 226     Initializer that set the initially active tab on the tab control.
6159 09 Oct 12 nicklas 227   */
6160 10 Oct 12 nicklas 228   internal.setInitialTab = function(tabControl, autoInit)
6159 09 Oct 12 nicklas 229   {
6160 10 Oct 12 nicklas 230     if (autoInit != 'tabcontrol') return;
6260 27 Mar 13 nicklas 231     var initialTab = Data.get(tabControl, 'initial-tab');
6161 10 Oct 12 nicklas 232     var checkRemembered = Data.int(tabControl, 'remember-last');
6260 27 Mar 13 nicklas 233     if (initialTab)
6161 10 Oct 12 nicklas 234     {
6260 27 Mar 13 nicklas 235       // Prepend the tabcontrol id
6260 27 Mar 13 nicklas 236       initialTab = tabControl.id + '.' + initialTab;
6260 27 Mar 13 nicklas 237     }
6260 27 Mar 13 nicklas 238     else if (checkRemembered)
6260 27 Mar 13 nicklas 239     {
6161 10 Oct 12 nicklas 240       var remembered = Data.getPageValue('last-tab.'+tabControl.id);
6161 10 Oct 12 nicklas 241       if (remembered) initialTab = remembered;
6161 10 Oct 12 nicklas 242     }
6260 27 Mar 13 nicklas 243     if (!initialTab)
6260 27 Mar 13 nicklas 244     {
6260 27 Mar 13 nicklas 245       // Locate the ID of the first defined tab and make that the initial tab
6260 27 Mar 13 nicklas 246       var tabs = tabControl.getElementsByClassName('tab');
6260 27 Mar 13 nicklas 247       if (tabs.length > 0) initialTab = tabs[0].id;
6260 27 Mar 13 nicklas 248     }
6160 10 Oct 12 nicklas 249     Doc.addFinalizer(function()
6160 10 Oct 12 nicklas 250       {
6161 10 Oct 12 nicklas 251         TabControl.setActiveTab(initialTab);
6160 10 Oct 12 nicklas 252       });
6160 10 Oct 12 nicklas 253     
6159 09 Oct 12 nicklas 254   }
6160 10 Oct 12 nicklas 255   Doc.addElementInitializer(internal.setInitialTab);
6159 09 Oct 12 nicklas 256   
6159 09 Oct 12 nicklas 257   return tc;
6159 09 Oct 12 nicklas 258 }();
6159 09 Oct 12 nicklas 259
6159 09 Oct 12 nicklas 260