6159 |
09 Oct 12 |
nicklas |
/* $Id$ |
6159 |
09 Oct 12 |
nicklas |
2 |
------------------------------------------------------------------ |
6159 |
09 Oct 12 |
nicklas |
Copyright (C) 2012 Nicklas Nordborg |
6159 |
09 Oct 12 |
nicklas |
4 |
|
6159 |
09 Oct 12 |
nicklas |
This file is part of BASE - BioArray Software Environment. |
6159 |
09 Oct 12 |
nicklas |
Available at http://base.thep.lu.se/ |
6159 |
09 Oct 12 |
nicklas |
7 |
|
6159 |
09 Oct 12 |
nicklas |
BASE is free software; you can redistribute it and/or |
6159 |
09 Oct 12 |
nicklas |
modify it under the terms of the GNU General Public License |
6159 |
09 Oct 12 |
nicklas |
as published by the Free Software Foundation; either version 3 |
6159 |
09 Oct 12 |
nicklas |
of the License, or (at your option) any later version. |
6159 |
09 Oct 12 |
nicklas |
12 |
|
6159 |
09 Oct 12 |
nicklas |
BASE is distributed in the hope that it will be useful, |
6159 |
09 Oct 12 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
6159 |
09 Oct 12 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
6159 |
09 Oct 12 |
nicklas |
GNU General Public License for more details. |
6159 |
09 Oct 12 |
nicklas |
17 |
|
6159 |
09 Oct 12 |
nicklas |
You should have received a copy of the GNU General Public License |
6159 |
09 Oct 12 |
nicklas |
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 |
JavaScript functions for the TabControl2 taglib. |
6159 |
09 Oct 12 |
nicklas |
23 |
|
6159 |
09 Oct 12 |
nicklas |
@author Nicklas |
6159 |
09 Oct 12 |
nicklas |
@since 3.3 |
6159 |
09 Oct 12 |
nicklas |
26 |
*/ |
7419 |
03 Nov 17 |
nicklas |
'use strict'; |
6159 |
09 Oct 12 |
nicklas |
28 |
|
6159 |
09 Oct 12 |
nicklas |
var TabControl = function() |
6159 |
09 Oct 12 |
nicklas |
30 |
{ |
6159 |
09 Oct 12 |
nicklas |
var tc = {}; |
6159 |
09 Oct 12 |
nicklas |
var internal = {}; |
6159 |
09 Oct 12 |
nicklas |
33 |
|
6159 |
09 Oct 12 |
nicklas |
34 |
/** |
6160 |
10 Oct 12 |
nicklas |
Register a function that is responsible for switching |
6160 |
10 Oct 12 |
nicklas |
between tabs. Typically used when a 'virtual' tab is used as |
6160 |
10 Oct 12 |
nicklas |
a placeholder for loading a different page in the browser. |
6160 |
10 Oct 12 |
nicklas |
Note that validators that have been registered for the current tab |
6160 |
10 Oct 12 |
nicklas |
are not automatically called when a custom switch function is used. |
6160 |
10 Oct 12 |
nicklas |
The switch function must either call TabControl.setActiveTab() (which also |
6160 |
10 Oct 12 |
nicklas |
switches to the new tab) or TabControl.validateActiveTab() if validation |
6160 |
10 Oct 12 |
nicklas |
is wanted. |
6160 |
10 Oct 12 |
nicklas |
43 |
*/ |
6160 |
10 Oct 12 |
nicklas |
tc.setSwitchFunction = function(tabControl, switchFunction) |
6160 |
10 Oct 12 |
nicklas |
45 |
{ |
6160 |
10 Oct 12 |
nicklas |
if (!switchFunction || !switchFunction.call) return; // 'switchFunction' is not a function |
6160 |
10 Oct 12 |
nicklas |
tabControl = Doc.element(tabControl); |
6315 |
06 Sep 13 |
nicklas |
if (!tabControl) return; |
6160 |
10 Oct 12 |
nicklas |
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 |
Adds a validator callback to the given tab. All registered validators |
6159 |
09 Oct 12 |
nicklas |
are called whenever the current tab is about to lose focus due to switching |
6160 |
10 Oct 12 |
nicklas |
to another tab or due to form submission. A validator function should |
6160 |
10 Oct 12 |
nicklas |
take a single 'event' parameter. The event object is a custom event object |
6160 |
10 Oct 12 |
nicklas |
with the 'target' property set to the tab that should be validated. |
6160 |
10 Oct 12 |
nicklas |
The validator should return 'true' to indicate successful validation, or |
6160 |
10 Oct 12 |
nicklas |
'false' to indicate failure. If at least one validator signals a failure |
6160 |
10 Oct 12 |
nicklas |
the entire validation is considered a failure and the default action (tab |
6160 |
10 Oct 12 |
nicklas |
switch, form submission, etc) is cancelled. |
6159 |
09 Oct 12 |
nicklas |
62 |
*/ |
6315 |
06 Sep 13 |
nicklas |
tc.addTabValidator = function(tab, validator, attributes) |
6159 |
09 Oct 12 |
nicklas |
64 |
{ |
6160 |
10 Oct 12 |
nicklas |
if (!validator || !validator.call) return; // 'validator' is not a function |
6159 |
09 Oct 12 |
nicklas |
tab = Doc.element(tab); |
6315 |
06 Sep 13 |
nicklas |
if (!tab) return; |
6315 |
06 Sep 13 |
nicklas |
if (attributes) Data.define(tab, attributes); |
6161 |
10 Oct 12 |
nicklas |
tab.addEventListener('base-validate', |
6159 |
09 Oct 12 |
nicklas |
function(event) |
6159 |
09 Oct 12 |
nicklas |
71 |
{ |
6160 |
10 Oct 12 |
nicklas |
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 |
Adds a listener to a tab that is called whenever that tab is made the active |
6161 |
10 Oct 12 |
nicklas |
tab. The listener function should take a single 'event' parameter. The event |
6161 |
10 Oct 12 |
nicklas |
object is a custom event object with the 'target' property set to the tab that |
6161 |
10 Oct 12 |
nicklas |
has been activated. |
6161 |
10 Oct 12 |
nicklas |
82 |
*/ |
6315 |
06 Sep 13 |
nicklas |
tc.addTabActivateListener = function(tab, listener, attributes) |
6161 |
10 Oct 12 |
nicklas |
84 |
{ |
6161 |
10 Oct 12 |
nicklas |
if (!listener || !listener.call) return; // 'listener' is not a function |
6161 |
10 Oct 12 |
nicklas |
tab = Doc.element(tab); |
6315 |
06 Sep 13 |
nicklas |
if (!tab) return; |
6315 |
06 Sep 13 |
nicklas |
if (attributes) Data.define(tab, attributes); |
6161 |
10 Oct 12 |
nicklas |
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 |
Switch to the given tab. Validators attached to the currently active tab |
6159 |
09 Oct 12 |
nicklas |
are called first which may abort the switch. This function returns true of |
6160 |
10 Oct 12 |
nicklas |
the switch was successful, false if not or if the current tab is the same |
6161 |
10 Oct 12 |
nicklas |
as the given tab. If the switch is sucessful, the 'activate' event is sent |
6161 |
10 Oct 12 |
nicklas |
to all listeners registered with TabControl.addTabActivateListener(). |
6160 |
10 Oct 12 |
nicklas |
@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 |
tc.setActiveTab = function(tab) |
6159 |
09 Oct 12 |
nicklas |
102 |
{ |
6159 |
09 Oct 12 |
nicklas |
tab = Doc.element(tab); |
6315 |
06 Sep 13 |
nicklas |
if (!tab) return; |
6159 |
09 Oct 12 |
nicklas |
var tabControl = internal.tabControl(tab); |
6159 |
09 Oct 12 |
nicklas |
106 |
|
6159 |
09 Oct 12 |
nicklas |
if (tabControl.activeTab == tab) return false; |
6159 |
09 Oct 12 |
nicklas |
if (!tc.validateActiveTab(tabControl)) return false; |
6159 |
09 Oct 12 |
nicklas |
109 |
|
6159 |
09 Oct 12 |
nicklas |
if (tabControl.activeTab != null) |
6159 |
09 Oct 12 |
nicklas |
111 |
{ |
6342 |
01 Nov 13 |
nicklas |
Doc.removeClass(tabControl.activeTab, 'active'); |
6608 |
20 Nov 14 |
nicklas |
Doc.addClass(tabControl.activeTab, 'interactable'); |
6159 |
09 Oct 12 |
nicklas |
114 |
} |
6342 |
01 Nov 13 |
nicklas |
Doc.addClass(tab, 'active'); |
6608 |
20 Nov 14 |
nicklas |
Doc.removeClass(tab, 'interactable'); |
6159 |
09 Oct 12 |
nicklas |
117 |
|
6159 |
09 Oct 12 |
nicklas |
tabControl.activeTab = tab; |
6159 |
09 Oct 12 |
nicklas |
if (tabControl.activeContent != null) |
6159 |
09 Oct 12 |
nicklas |
120 |
{ |
6159 |
09 Oct 12 |
nicklas |
tabControl.activeContent.style.display = 'none'; |
6159 |
09 Oct 12 |
nicklas |
122 |
} |
6400 |
27 Jan 14 |
nicklas |
var content = Doc.element(tab.id+'.content'); |
6159 |
09 Oct 12 |
nicklas |
if (content != null) |
6159 |
09 Oct 12 |
nicklas |
125 |
{ |
6159 |
09 Oct 12 |
nicklas |
content.style.display = 'block'; |
6159 |
09 Oct 12 |
nicklas |
tabControl.activeContent = content; |
6159 |
09 Oct 12 |
nicklas |
128 |
} |
6261 |
27 Mar 13 |
nicklas |
129 |
|
6261 |
27 Mar 13 |
nicklas |
Data.setPageValue('last-tab.'+tabControl.id, tab.id); |
6261 |
27 Mar 13 |
nicklas |
131 |
|
6161 |
10 Oct 12 |
nicklas |
var evt = document.createEvent('Event'); |
6161 |
10 Oct 12 |
nicklas |
evt.initEvent('base-activate', false, true); |
6161 |
10 Oct 12 |
nicklas |
tab.dispatchEvent(evt); |
6161 |
10 Oct 12 |
nicklas |
135 |
|
6159 |
09 Oct 12 |
nicklas |
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 |
Validate the currently active tab. If the validation is sucessful or if there |
6160 |
10 Oct 12 |
nicklas |
is no active tab 'true' is returned, 'false' if not. |
6160 |
10 Oct 12 |
nicklas |
@param tabControl A tab control element or the id of a tab control |
6160 |
10 Oct 12 |
nicklas |
143 |
*/ |
6159 |
09 Oct 12 |
nicklas |
tc.validateActiveTab = function(tabControl) |
6159 |
09 Oct 12 |
nicklas |
145 |
{ |
6159 |
09 Oct 12 |
nicklas |
tabControl = Doc.element(tabControl); |
6159 |
09 Oct 12 |
nicklas |
if (!tabControl.activeTab) return true; |
6159 |
09 Oct 12 |
nicklas |
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 |
Validate the given tab. If the validation is sucessful 'true' |
6160 |
10 Oct 12 |
nicklas |
is returned, 'false' if not. |
6160 |
10 Oct 12 |
nicklas |
@param tab A tab element or the id of a tab |
6160 |
10 Oct 12 |
nicklas |
155 |
*/ |
6159 |
09 Oct 12 |
nicklas |
tc.validateTab = function(tab) |
6159 |
09 Oct 12 |
nicklas |
157 |
{ |
6159 |
09 Oct 12 |
nicklas |
var evt = document.createEvent('Event'); |
6161 |
10 Oct 12 |
nicklas |
evt.initEvent('base-validate', false, true); |
6159 |
09 Oct 12 |
nicklas |
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 |
Get the id for the help section that applies to the currently active tab. |
6160 |
10 Oct 12 |
nicklas |
@param tabControl A tab control element or the id of a tab control |
6160 |
10 Oct 12 |
nicklas |
166 |
*/ |
6160 |
10 Oct 12 |
nicklas |
tc.getActiveHelpId = function(tabControl) |
6160 |
10 Oct 12 |
nicklas |
168 |
{ |
6160 |
10 Oct 12 |
nicklas |
tabControl = Doc.element(tabControl); |
7419 |
03 Nov 17 |
nicklas |
var tab = tabControl.activeTab; |
6160 |
10 Oct 12 |
nicklas |
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 |
Get the id for the help section that applies to the given tab. |
6160 |
10 Oct 12 |
nicklas |
@param tabControl A tab element or the id of a tab |
6160 |
10 Oct 12 |
nicklas |
177 |
*/ |
6160 |
10 Oct 12 |
nicklas |
tc.getHelpId = function(tab) |
6160 |
10 Oct 12 |
nicklas |
179 |
{ |
6160 |
10 Oct 12 |
nicklas |
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 |
Get a reference to the tab-control object that contains the given tab. |
6160 |
10 Oct 12 |
nicklas |
185 |
*/ |
6159 |
09 Oct 12 |
nicklas |
internal.tabControl = function(tab) |
6159 |
09 Oct 12 |
nicklas |
187 |
{ |
6400 |
27 Jan 14 |
nicklas |
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 |
'click' event handler for tabs. If a switch function has been |
6160 |
10 Oct 12 |
nicklas |
assigned to the tab control, the switch function is called with the |
6160 |
10 Oct 12 |
nicklas |
event as parameter. Otherwise the TabControl.setActiveTab() function |
6160 |
10 Oct 12 |
nicklas |
is used to switch to the clicked tab. |
6159 |
09 Oct 12 |
nicklas |
196 |
*/ |
6159 |
09 Oct 12 |
nicklas |
internal.tabOnClick = function(event) |
6159 |
09 Oct 12 |
nicklas |
198 |
{ |
6159 |
09 Oct 12 |
nicklas |
var tab = event.currentTarget; |
6160 |
10 Oct 12 |
nicklas |
var tabControl = internal.tabControl(tab); |
6160 |
10 Oct 12 |
nicklas |
if (tabControl.switchFunction) |
6160 |
10 Oct 12 |
nicklas |
202 |
{ |
6160 |
10 Oct 12 |
nicklas |
tabControl.switchFunction.call(tabControl, event); |
6160 |
10 Oct 12 |
nicklas |
204 |
} |
6160 |
10 Oct 12 |
nicklas |
else |
6160 |
10 Oct 12 |
nicklas |
206 |
{ |
6160 |
10 Oct 12 |
nicklas |
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 |
Initializer that add 'onclick' event handlers to all 'tab' elements. |
6159 |
09 Oct 12 |
nicklas |
213 |
*/ |
6160 |
10 Oct 12 |
nicklas |
internal.addOnClickHandler = function(tab, autoInit) |
6159 |
09 Oct 12 |
nicklas |
215 |
{ |
6160 |
10 Oct 12 |
nicklas |
if (autoInit != 'tab') return; |
6159 |
09 Oct 12 |
nicklas |
Events.addEventHandler(tab, 'click', internal.tabOnClick); |
6159 |
09 Oct 12 |
nicklas |
if (tab.tabIndex >= 0) |
6159 |
09 Oct 12 |
nicklas |
219 |
{ |
6159 |
09 Oct 12 |
nicklas |
Events.enableClickOnEnter(tab); |
6159 |
09 Oct 12 |
nicklas |
221 |
} |
6159 |
09 Oct 12 |
nicklas |
222 |
} |
6160 |
10 Oct 12 |
nicklas |
Doc.addElementInitializer(internal.addOnClickHandler); |
6159 |
09 Oct 12 |
nicklas |
224 |
|
6159 |
09 Oct 12 |
nicklas |
225 |
/** |
6160 |
10 Oct 12 |
nicklas |
Initializer that set the initially active tab on the tab control. |
6159 |
09 Oct 12 |
nicklas |
227 |
*/ |
6160 |
10 Oct 12 |
nicklas |
internal.setInitialTab = function(tabControl, autoInit) |
6159 |
09 Oct 12 |
nicklas |
229 |
{ |
6160 |
10 Oct 12 |
nicklas |
if (autoInit != 'tabcontrol') return; |
6260 |
27 Mar 13 |
nicklas |
var initialTab = Data.get(tabControl, 'initial-tab'); |
6161 |
10 Oct 12 |
nicklas |
var checkRemembered = Data.int(tabControl, 'remember-last'); |
6260 |
27 Mar 13 |
nicklas |
if (initialTab) |
6161 |
10 Oct 12 |
nicklas |
234 |
{ |
6260 |
27 Mar 13 |
nicklas |
// Prepend the tabcontrol id |
6260 |
27 Mar 13 |
nicklas |
initialTab = tabControl.id + '.' + initialTab; |
6260 |
27 Mar 13 |
nicklas |
237 |
} |
6260 |
27 Mar 13 |
nicklas |
else if (checkRemembered) |
6260 |
27 Mar 13 |
nicklas |
239 |
{ |
6161 |
10 Oct 12 |
nicklas |
var remembered = Data.getPageValue('last-tab.'+tabControl.id); |
6161 |
10 Oct 12 |
nicklas |
if (remembered) initialTab = remembered; |
6161 |
10 Oct 12 |
nicklas |
242 |
} |
6260 |
27 Mar 13 |
nicklas |
if (!initialTab) |
6260 |
27 Mar 13 |
nicklas |
244 |
{ |
6260 |
27 Mar 13 |
nicklas |
// Locate the ID of the first defined tab and make that the initial tab |
6260 |
27 Mar 13 |
nicklas |
var tabs = tabControl.getElementsByClassName('tab'); |
6260 |
27 Mar 13 |
nicklas |
if (tabs.length > 0) initialTab = tabs[0].id; |
6260 |
27 Mar 13 |
nicklas |
248 |
} |
6160 |
10 Oct 12 |
nicklas |
Doc.addFinalizer(function() |
6160 |
10 Oct 12 |
nicklas |
250 |
{ |
6161 |
10 Oct 12 |
nicklas |
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 |
Doc.addElementInitializer(internal.setInitialTab); |
6159 |
09 Oct 12 |
nicklas |
256 |
|
6159 |
09 Oct 12 |
nicklas |
return tc; |
6159 |
09 Oct 12 |
nicklas |
258 |
}(); |
6159 |
09 Oct 12 |
nicklas |
259 |
|
6159 |
09 Oct 12 |
nicklas |
260 |
|