// Sticky Plugin v1.0.4 for jQuery
// =============
// Author: Anthony Garand
// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk)
// Improvements by Leonardo C. Daronco (daronco)
// Created: 02/14/2011
// Date: 07/20/2015
// Website: http://stickyjs.com/
// Description: Makes an element on the page stick on the screen as you scroll
// It will only set the 'top' and 'position' of your element, you
// might need to adjust the width in some cases.
// Date: 10/2/2017
// Remove the document.write function for the datatables assets
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var slice = Array.prototype.slice; // save ref to original slice()
var splice = Array.prototype.splice; // save ref to original slice()
var defaults = {
topSpacing: 0,
bottomSpacing: 0,
className: 'is-sticky',
wrapperClassName: 'sticky-wrapper',
center: false,
getWidthFrom: '',
widthFromWrapper: true, // works only when .getWidthFrom is empty
responsiveWidth: false,
zIndex: 'auto'
},
$window = $(window),
$document = $(document),
sticked = [],
windowHeight = $window.height(),
scroller = function() {
var scrollTop = $window.scrollTop(),
documentHeight = $document.height(),
dwh = documentHeight - windowHeight,
extra = (scrollTop > dwh) ? dwh - scrollTop : 0;
for (var i = 0, l = sticked.length; i < l; i++) {
var s = sticked[i],
elementTop = s.stickyWrapper.offset().top,
etse = elementTop - s.topSpacing - extra;
//update height in case of dynamic content
s.stickyWrapper.css('height', s.stickyElement.outerHeight());
if (scrollTop <= etse) {
if (s.currentTop !== null) {
s.stickyElement
.css({
'width': '',
'position': '',
'top': '',
'z-index': ''
});
s.stickyElement.parent().removeClass(s.className);
s.stickyElement.trigger('sticky-end', [s]);
s.currentTop = null;
}
}
else {
var newTop = documentHeight - s.stickyElement.outerHeight()
- s.topSpacing - s.bottomSpacing - scrollTop - extra;
if (newTop < 0) {
newTop = newTop + s.topSpacing;
} else {
newTop = s.topSpacing;
}
if (s.currentTop !== newTop) {
var newWidth;
if (s.getWidthFrom) {
newWidth = $(s.getWidthFrom).width() || null;
} else if (s.widthFromWrapper) {
newWidth = s.stickyWrapper.width();
}
if (newWidth == null) {
newWidth = s.stickyElement.width();
}
s.stickyElement
.css('width', newWidth)
.css('position', 'fixed')
.css('top', newTop)
.css('z-index', s.zIndex);
s.stickyElement.parent().addClass(s.className);
if (s.currentTop === null) {
s.stickyElement.trigger('sticky-start', [s]);
} else {
// sticky is started but it have to be repositioned
s.stickyElement.trigger('sticky-update', [s]);
}
if (s.currentTop === s.topSpacing && s.currentTop > newTop || s.currentTop === null && newTop < s.topSpacing) {
// just reached bottom || just started to stick but bottom is already reached
s.stickyElement.trigger('sticky-bottom-reached', [s]);
} else if(s.currentTop !== null && newTop === s.topSpacing && s.currentTop < newTop) {
// sticky is started && sticked at topSpacing && overflowing from top just finished
s.stickyElement.trigger('sticky-bottom-unreached', [s]);
}
s.currentTop = newTop;
}
// Check if sticky has reached end of container and stop sticking
var stickyWrapperContainer = s.stickyWrapper.parent();
var unstick = (s.stickyElement.offset().top + s.stickyElement.outerHeight() >= stickyWrapperContainer.offset().top + stickyWrapperContainer.outerHeight()) && (s.stickyElement.offset().top <= s.topSpacing);
if( unstick ) {
s.stickyElement
.css('position', 'absolute')
.css('top', '')
.css('bottom', 0)
.css('z-index', '');
} else {
s.stickyElement
.css('position', 'fixed')
.css('top', newTop)
.css('bottom', '')
.css('z-index', s.zIndex);
}
}
}
},
resizer = function() {
windowHeight = $window.height();
for (var i = 0, l = sticked.length; i < l; i++) {
var s = sticked[i];
var newWidth = null;
if (s.getWidthFrom) {
if (s.responsiveWidth) {
newWidth = $(s.getWidthFrom).width();
}
} else if(s.widthFromWrapper) {
newWidth = s.stickyWrapper.width();
}
if (newWidth != null) {
s.stickyElement.css('width', newWidth);
}
}
},
methods = {
init: function(options) {
return this.each(function() {
var o = $.extend({}, defaults, options);
var stickyElement = $(this);
var stickyId = stickyElement.attr('id');
var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName;
var wrapper = $('
')
.attr('id', wrapperId)
.addClass(o.wrapperClassName);
stickyElement.wrapAll(function() {
if ($(this).parent("#" + wrapperId).length == 0) {
return wrapper;
}
});
var stickyWrapper = stickyElement.parent();
if (o.center) {
stickyWrapper.css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"});
}
if (stickyElement.css("float") === "right") {
stickyElement.css({"float":"none"}).parent().css({"float":"right"});
}
o.stickyElement = stickyElement;
o.stickyWrapper = stickyWrapper;
o.currentTop = null;
sticked.push(o);
methods.setWrapperHeight(this);
methods.setupChangeListeners(this);
});
},
setWrapperHeight: function(stickyElement) {
var element = $(stickyElement);
var stickyWrapper = element.parent();
if (stickyWrapper) {
stickyWrapper.css('height', element.outerHeight());
}
},
setupChangeListeners: function(stickyElement) {
if (window.MutationObserver) {
var mutationObserver = new window.MutationObserver(function(mutations) {
if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) {
methods.setWrapperHeight(stickyElement);
}
});
mutationObserver.observe(stickyElement, {subtree: true, childList: true});
} else {
if (window.addEventListener) {
stickyElement.addEventListener('DOMNodeInserted', function() {
methods.setWrapperHeight(stickyElement);
}, false);
stickyElement.addEventListener('DOMNodeRemoved', function() {
methods.setWrapperHeight(stickyElement);
}, false);
} else if (window.attachEvent) {
stickyElement.attachEvent('onDOMNodeInserted', function() {
methods.setWrapperHeight(stickyElement);
});
stickyElement.attachEvent('onDOMNodeRemoved', function() {
methods.setWrapperHeight(stickyElement);
});
}
}
},
update: scroller,
unstick: function(options) {
return this.each(function() {
var that = this;
var unstickyElement = $(that);
var removeIdx = -1;
var i = sticked.length;
while (i-- > 0) {
if (sticked[i].stickyElement.get(0) === that) {
splice.call(sticked,i,1);
removeIdx = i;
}
}
if(removeIdx !== -1) {
unstickyElement.unwrap();
unstickyElement
.css({
'width': '',
'position': '',
'top': '',
'float': '',
'z-index': ''
})
;
}
});
}
};
// should be more efficient than using $window.scroll(scroller) and $window.resize(resizer):
if (window.addEventListener) {
window.addEventListener('scroll', scroller, false);
window.addEventListener('resize', resizer, false);
} else if (window.attachEvent) {
window.attachEvent('onscroll', scroller);
window.attachEvent('onresize', resizer);
}
$.fn.sticky = function(method) {
if (methods[method]) {
return methods[method].apply(this, slice.call(arguments, 1));
} else if (typeof method === 'object' || !method ) {
return methods.init.apply( this, arguments );
} else {
$.error('Method ' + method + ' does not exist on jQuery.sticky');
}
};
$.fn.unstick = function(method) {
if (methods[method]) {
return methods[method].apply(this, slice.call(arguments, 1));
} else if (typeof method === 'object' || !method ) {
return methods.unstick.apply( this, arguments );
} else {
$.error('Method ' + method + ' does not exist on jQuery.sticky');
}
};
$(function() {
setTimeout(scroller, 0);
});
}));
// End Sticky Plugin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
Copyright © 2013 Adobe Systems Incorporated.
Licensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* See http://jquery.com .
* @name jquery
* @class
* See the jQuery Library (http://jquery.com ) for full details. This just
* documents the function and classes that are added to jQuery by this plug-in.
*/
/**
* See http://jquery.com
* @name fn
* @class
* See the jQuery Library (http://jquery.com ) for full details. This just
* documents the function and classes that are added to jQuery by this plug-in.
* @memberOf jquery
*/
/**
* @fileOverview accessibleMegaMenu plugin
*
*Licensed under the Apache License, Version 2.0 (the “License”)
* Copyright © 2013 Adobe Systems Incorporated.
* Project page https://github.com/adobe-accessibility/Accessible-Mega-Menu
* @version 0.1
* @author Michael Jordan
* @requires jquery
*/
/*jslint browser: true, devel: true, plusplus: true, nomen: true */
/*global jQuery */
(function ($, window, document) {
"use strict";
var pluginName = "accessibleMegaMenu",
defaults = {
uuidPrefix: "accessible-megamenu", // unique ID's are required to indicate aria-owns, aria-controls and aria-labelledby
menuClass: "accessible-megamenu", // default css class used to define the megamenu styling
topNavItemClass: "accessible-megamenu-top-nav-item", // default css class for a top-level navigation item in the megamenu
panelClass: "accessible-megamenu-panel", // default css class for a megamenu panel
panelGroupClass: "accessible-megamenu-panel-group", // default css class for a group of items within a megamenu panel
hoverClass: "hover", // default css class for the hover state
focusClass: "focus", // default css class for the focus state
openClass: "open" // default css class for the open state
},
Keyboard = {
BACKSPACE: 8,
COMMA: 188,
DELETE: 46,
DOWN: 40,
END: 35,
ENTER: 13,
ESCAPE: 27,
HOME: 36,
LEFT: 37,
PAGE_DOWN: 34,
PAGE_UP: 33,
PERIOD: 190,
RIGHT: 39,
SPACE: 32,
TAB: 9,
UP: 38,
keyMap: {
48: "0",
49: "1",
50: "2",
51: "3",
52: "4",
53: "5",
54: "6",
55: "7",
56: "8",
57: "9",
59: ";",
65: "a",
66: "b",
67: "c",
68: "d",
69: "e",
70: "f",
71: "g",
72: "h",
73: "i",
74: "j",
75: "k",
76: "l",
77: "m",
78: "n",
79: "o",
80: "p",
81: "q",
82: "r",
83: "s",
84: "t",
85: "u",
86: "v",
87: "w",
88: "x",
89: "y",
90: "z",
96: "0",
97: "1",
98: "2",
99: "3",
100: "4",
101: "5",
102: "6",
103: "7",
104: "8",
105: "9",
190: "."
}
};
/**
* @desc Creates a new accessible mega menu instance.
* @param {jquery} element
* @param {object} [options] Mega Menu options
* @param {string} [options.uuidPrefix=accessible-megamenu] - Prefix for generated unique id attributes, which are required to indicate aria-owns, aria-controls and aria-labelledby
* @param {string} [options.menuClass=accessible-megamenu] - CSS class used to define the megamenu styling
* @param {string} [options.topNavItemClass=accessible-megamenu-top-nav-item] - CSS class for a top-level navigation item in the megamenu
* @param {string} [options.panelClass=accessible-megamenu-panel] - CSS class for a megamenu panel
* @param {string} [options.panelGroupClass=accessible-megamenu-panel-group] - CSS class for a group of items within a megamenu panel
* @param {string} [options.hoverClass=hover] - CSS class for the hover state
* @param {string} [options.focusClass=focus] - CSS class for the focus state
* @param {string} [options.openClass=open] - CSS class for the open state
* @constructor
*/
function AccessibleMegaMenu(element, options) {
this.element = element;
// merge optional settings and defaults into settings
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.mouseTimeoutID = null;
this.focusTimeoutID = null;
this.mouseFocused = false;
this.justFocused = false;
this.init();
}
AccessibleMegaMenu.prototype = (function () {
/* private attributes and methods ------------------------ */
var uuid = 0,
keydownTimeoutDuration = 1000,
keydownSearchString = "",
isTouch = typeof window.hasOwnProperty === "function" && !!window.hasOwnProperty("ontouchstart"),
_getPlugin,
_addUniqueId,
_togglePanel,
_clickHandler,
_clickOutsideHandler,
_DOMAttrModifiedHandler,
_focusInHandler,
_focusOutHandler,
_keyDownHandler,
_mouseDownHandler,
_mouseOverHandler,
_mouseOutHandler,
_toggleExpandedEventHandlers;
/**
* @name jQuery.fn.accessibleMegaMenu~_getPlugin
* @desc Returns the parent accessibleMegaMenu instance for a given element
* @param {jQuery} element
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_getPlugin = function (element) {
return $(element).closest(':data(plugin_' + pluginName + ')').data("plugin_" + pluginName);
};
/**
* @name jQuery.fn.accessibleMegaMenu~_addUniqueId
* @desc Adds a unique id and element.
* The id string starts with the
* string defined in settings.uuidPrefix.
* @param {jQuery} element
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_addUniqueId = function (element) {
element = $(element);
var settings = this.settings;
if (!element.attr("id")) {
element.attr("id", settings.uuidPrefix + "-" + new Date().getTime() + "-" + (++uuid));
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_togglePanel
* @desc Toggle the display of mega menu panels in response to an event.
* The optional boolean value 'hide' forces all panels to hide.
* @param {event} event
* @param {Boolean} [hide] Hide all mega menu panels when true
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_togglePanel = function (event, hide) {
var target = $(event.target),
that = this,
settings = this.settings,
menu = this.menu,
topli = target.closest('.' + settings.topNavItemClass),
panel = target.hasClass(settings.panelClass) ? target : target.closest('.' + settings.panelClass),
newfocus;
_toggleExpandedEventHandlers.call(this, true);
if (hide) {
topli = menu.find('.' + settings.topNavItemClass + ' .' + settings.openClass + ':first').closest('.' + settings.topNavItemClass);
if (!(topli.is(event.relatedTarget) || topli.has(event.relatedTarget).length > 0)) {
if ((event.type === 'mouseout' || event.type === 'focusout') && topli.has(document.activeElement).length > 0) {
return;
}
topli.find('[aria-expanded]')
.attr('aria-expanded', 'false')
.removeClass(settings.openClass)
.filter('.' + settings.panelClass)
.attr('aria-hidden', 'true');
if ((event.type === 'keydown' && event.keyCode === Keyboard.ESCAPE) || event.type === 'DOMAttrModified') {
newfocus = topli.find(':tabbable:first');
setTimeout(function () {
menu.find('[aria-expanded].' + that.settings.panelClass).off('DOMAttrModified.accessible-megamenu');
newfocus.focus();
that.justFocused = false;
}, 99);
}
} else if (topli.length === 0) {
menu.find('[aria-expanded=true]')
.attr('aria-expanded', 'false')
.removeClass(settings.openClass)
.filter('.' + settings.panelClass)
.attr('aria-hidden', 'true');
}
} else {
clearTimeout(that.focusTimeoutID);
topli.siblings()
.find('[aria-expanded]')
.attr('aria-expanded', 'false')
.removeClass(settings.openClass)
.filter('.' + settings.panelClass)
.attr('aria-hidden', 'true');
topli.find('[aria-expanded]')
.attr('aria-expanded', 'true')
.addClass(settings.openClass)
.filter('.' + settings.panelClass)
.attr('aria-hidden', 'false');
if (event.type === 'mouseover' && target.is(':tabbable') && topli.length === 1 && panel.length === 0 && menu.has(document.activeElement).length > 0) {
target.focus();
that.justFocused = false;
}
_toggleExpandedEventHandlers.call(that);
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_clickHandler
* @desc Handle click event on mega menu item
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_clickHandler = function (event) {
var target = $(event.currentTarget),
topli = target.closest('.' + this.settings.topNavItemClass),
panel = target.closest('.' + this.settings.panelClass);
if (topli.length === 1
&& panel.length === 0
&& topli.find('.' + this.settings.panelClass).length === 1) {
if (!target.hasClass(this.settings.openClass)) {
event.preventDefault();
event.stopPropagation();
_togglePanel.call(this, event);
this.justFocused = false;
} else {
if (this.justFocused) {
event.preventDefault();
event.stopPropagation();
this.justFocused = false;
} else if (isTouch) {
event.preventDefault();
event.stopPropagation();
_togglePanel.call(this, event, target.hasClass(this.settings.openClass));
}
}
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_clickOutsideHandler
* @desc Handle click event outside of a the megamenu
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_clickOutsideHandler = function (event) {
if ($(event.target).closest(this.menu).length === 0) {
event.preventDefault();
event.stopPropagation();
_togglePanel.call(this, event, true);
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_DOMAttrModifiedHandler
* @desc Handle DOMAttrModified event on panel to respond to Windows 8 Narrator ExpandCollapse pattern
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_DOMAttrModifiedHandler = function (event) {
if (event.originalEvent.attrName === 'aria-expanded'
&& event.originalEvent.newValue === 'false'
&& $(event.target).hasClass(this.settings.openClass)) {
event.preventDefault();
event.stopPropagation();
_togglePanel.call(this, event, true);
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_focusInHandler
* @desc Handle focusin event on mega menu item.
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_focusInHandler = function (event) {
clearTimeout(this.focusTimeoutID);
var target = $(event.target),
panel = target.closest('.' + this.settings.panelClass);
target
.addClass(this.settings.focusClass)
.on('click.accessible-megamenu', $.proxy(_clickHandler, this));
this.justFocused = !this.mouseFocused;
this.mouseFocused = false;
if (this.panels.not(panel).filter('.' + this.settings.openClass).length) {
_togglePanel.call(this, event);
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_focusOutHandler
* @desc Handle focusout event on mega menu item.
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_focusOutHandler = function (event) {
this.justFocused = false;
var that = this,
target = $(event.target),
topli = target.closest('.' + this.settings.topNavItemClass),
keepOpen = false;
target
.removeClass(this.settings.focusClass)
.off('click.accessible-megamenu');
if (window.cvox) {
// If ChromeVox is running...
that.focusTimeoutID = setTimeout(function () {
window.cvox.Api.getCurrentNode(function (node) {
if (topli.has(node).length) {
// and the current node being voiced is in
// the mega menu, clearTimeout,
// so the panel stays open.
clearTimeout(that.focusTimeoutID);
} else {
that.focusTimeoutID = setTimeout(function (scope, event, hide) {
_togglePanel.call(scope, event, hide);
}, 275, that, event, true);
}
});
}, 25);
} else {
that.focusTimeoutID = setTimeout(function () {
_togglePanel.call(that, event, true);
}, 300);
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_keyDownHandler
* @desc Handle keydown event on mega menu.
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_keyDownHandler = function (event) {
var that = (this.constructor === AccessibleMegaMenu) ? this : _getPlugin(this), // determine the AccessibleMegaMenu plugin instance
settings = that.settings,
target = $($(this).is('.' + settings.hoverClass + ':tabbable') ? this : event.target), // if the element is hovered the target is this, otherwise, its the focused element
menu = that.menu,
topnavitems = that.topnavitems,
topli = target.closest('.' + settings.topNavItemClass),
tabbables = menu.find(':tabbable'),
panel = target.hasClass(settings.panelClass) ? target : target.closest('.' + settings.panelClass),
panelGroups = panel.find('.' + settings.panelGroupClass),
currentPanelGroup = target.closest('.' + settings.panelGroupClass),
next,
keycode = event.keyCode || event.which,
start,
i,
o,
label,
found = false,
newString = Keyboard.keyMap[event.keyCode] || '',
regex,
isTopNavItem = (topli.length === 1 && panel.length === 0);
if (target.is("input:focus, select:focus, textarea:focus, button:focus")) {
// if the event target is a form element we should handle keydown normally
return;
}
if (target.is('.' + settings.hoverClass + ':tabbable')) {
$('html').off('keydown.accessible-megamenu');
}
switch (keycode) {
case Keyboard.ESCAPE:
_togglePanel.call(that, event, true);
break;
case Keyboard.DOWN:
event.preventDefault();
if (isTopNavItem) {
_togglePanel.call(that, event);
found = (topli.find('.' + settings.panelClass + ' :tabbable:first').focus().length === 1);
} else {
found = (tabbables.filter(':gt(' + tabbables.index(target) + '):first').focus().length === 1);
}
if (!found && window.opera && opera.toString() === "[object Opera]" && (event.ctrlKey || event.metaKey)) {
tabbables = $(':tabbable');
i = tabbables.index(target);
found = ($(':tabbable:gt(' + $(':tabbable').index(target) + '):first').focus().length === 1);
}
break;
case Keyboard.UP:
event.preventDefault();
if (isTopNavItem && target.hasClass(settings.openClass)) {
_togglePanel.call(that, event, true);
next = topnavitems.filter(':lt(' + topnavitems.index(topli) + '):last');
if (next.children('.' + settings.panelClass).length) {
found = (next.children()
.attr('aria-expanded', 'true')
.addClass(settings.openClass)
.filter('.' + settings.panelClass)
.attr('aria-hidden', 'false')
.find(':tabbable:last')
.focus() === 1);
}
} else if (!isTopNavItem) {
found = (tabbables.filter(':lt(' + tabbables.index(target) + '):last').focus().length === 1);
}
if (!found && window.opera && opera.toString() === "[object Opera]" && (event.ctrlKey || event.metaKey)) {
tabbables = $(':tabbable');
i = tabbables.index(target);
found = ($(':tabbable:lt(' + $(':tabbable').index(target) + '):first').focus().length === 1);
}
break;
case Keyboard.RIGHT:
event.preventDefault();
if (isTopNavItem) {
found = (topnavitems.filter(':gt(' + topnavitems.index(topli) + '):first').find(':tabbable:first').focus().length === 1);
} else {
if (panelGroups.length && currentPanelGroup.length) {
// if the current panel contains panel groups, and we are able to focus the first tabbable element of the next panel group
found = (panelGroups.filter(':gt(' + panelGroups.index(currentPanelGroup) + '):first').find(':tabbable:first').focus().length === 1);
}
if (!found) {
found = (topli.find(':tabbable:first').focus().length === 1);
}
}
break;
case Keyboard.LEFT:
event.preventDefault();
if (isTopNavItem) {
found = (topnavitems.filter(':lt(' + topnavitems.index(topli) + '):last').find(':tabbable:first').focus().length === 1);
} else {
if (panelGroups.length && currentPanelGroup.length) {
// if the current panel contains panel groups, and we are able to focus the first tabbable element of the previous panel group
found = (panelGroups.filter(':lt(' + panelGroups.index(currentPanelGroup) + '):last').find(':tabbable:first').focus().length === 1);
}
if (!found) {
found = (topli.find(':tabbable:first').focus().length === 1);
}
}
break;
case Keyboard.TAB:
i = tabbables.index(target);
if (event.shiftKey && isTopNavItem && target.hasClass(settings.openClass)) {
_togglePanel.call(that, event, true);
next = topnavitems.filter(':lt(' + topnavitems.index(topli) + '):last');
if (next.children('.' + settings.panelClass).length) {
found = next.children()
.attr('aria-expanded', 'true')
.addClass(settings.openClass)
.filter('.' + settings.panelClass)
.attr('aria-hidden', 'false')
.find(':tabbable:last')
.focus();
}
} else if (event.shiftKey && i > 0) {
found = (tabbables.filter(':lt(' + i + '):last').focus().length === 1);
} else if (!event.shiftKey && i < tabbables.length - 1) {
found = (tabbables.filter(':gt(' + i + '):first').focus().length === 1);
} else if (window.opera && opera.toString() === "[object Opera]") {
tabbables = $(':tabbable');
i = tabbables.index(target);
if (event.shiftKey) {
found = ($(':tabbable:lt(' + $(':tabbable').index(target) + '):last').focus().length === 1);
} else {
found = ($(':tabbable:gt(' + $(':tabbable').index(target) + '):first').focus().length === 1);
}
}
if (found) {
event.preventDefault();
}
break;
case Keyboard.SPACE:
if (isTopNavItem) {
event.preventDefault();
_clickHandler.call(that, event);
} else {
return true;
}
break;
case Keyboard.ENTER:
return true;
break;
default:
// alphanumeric filter
clearTimeout(this.keydownTimeoutID);
keydownSearchString += newString !== keydownSearchString ? newString : '';
if (keydownSearchString.length === 0) {
return;
}
this.keydownTimeoutID = setTimeout(function () {
keydownSearchString = '';
}, keydownTimeoutDuration);
if (isTopNavItem && !target.hasClass(settings.openClass)) {
tabbables = tabbables.filter(':not(.' + settings.panelClass + ' :tabbable)');
} else {
tabbables = topli.find(':tabbable');
}
if (event.shiftKey) {
tabbables = $(tabbables.get()
.reverse());
}
for (i = 0; i < tabbables.length; i++) {
o = tabbables.eq(i);
if (o.is(target)) {
start = (keydownSearchString.length === 1) ? i + 1 : i;
break;
}
}
regex = new RegExp('^' + keydownSearchString.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'), 'i');
for (i = start; i < tabbables.length; i++) {
o = tabbables.eq(i);
label = $.trim(o.text());
if (regex.test(label)) {
found = true;
o.focus();
break;
}
}
if (!found) {
for (i = 0; i < start; i++) {
o = tabbables.eq(i);
label = $.trim(o.text());
if (regex.test(label)) {
o.focus();
break;
}
}
}
break;
}
that.justFocused = false;
};
/**
* @name jQuery.fn.accessibleMegaMenu~_mouseDownHandler
* @desc Handle mousedown event on mega menu.
* @param {event} Event object
* @memberof accessibleMegaMenu
* @inner
* @private
*/
_mouseDownHandler = function (event) {
if ($(event.target).is(this.settings.panelClass) || $(event.target).closest(":focusable").length) {
this.mouseFocused = true;
}
this.mouseTimeoutID = setTimeout(function () {
clearTimeout(this.focusTimeoutID);
}, 1);
};
/**
* @name jQuery.fn.accessibleMegaMenu~_mouseOverHandler
* @desc Handle mouseover event on mega menu.
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_mouseOverHandler = function (event) {
clearTimeout(this.mouseTimeoutID);
$(event.target)
.addClass(this.settings.hoverClass);
_togglePanel.call(this, event);
if ($(event.target).is(':tabbable')) {
$('html').on('keydown.accessible-megamenu', $.proxy(_keyDownHandler, event.target));
}
};
/**
* @name jQuery.fn.accessibleMegaMenu~_mouseOutHandler
* @desc Handle mouseout event on mega menu.
* @param {event} Event object
* @memberof jQuery.fn.accessibleMegaMenu
* @inner
* @private
*/
_mouseOutHandler = function (event) {
var that = this;
$(event.target)
.removeClass(that.settings.hoverClass);
that.mouseTimeoutID = setTimeout(function () {
_togglePanel.call(that, event, true);
}, 250);
if ($(event.target).is(':tabbable')) {
$('html').off('keydown.accessible-megamenu');
}
};
_toggleExpandedEventHandlers = function (hide) {
var menu = this.menu;
if (hide) {
$('html').off('mouseup.outside-accessible-megamenu, touchend.outside-accessible-megamenu, mspointerup.outside-accessible-megamenu, pointerup.outside-accessible-megamenu');
menu.find('[aria-expanded].' + this.settings.panelClass).off('DOMAttrModified.accessible-megamenu');
} else {
$('html').on('mouseup.outside-accessible-megamenu, touchend.outside-accessible-megamenu, mspointerup.outside-accessible-megamenu, pointerup.outside-accessible-megamenu', $.proxy(_clickOutsideHandler, this));
/* Narrator in Windows 8 automatically toggles the aria-expanded property on double tap or click.
To respond to the change to collapse the panel, we must add a listener for a DOMAttrModified event. */
menu.find('[aria-expanded=true].' + this.settings.panelClass).on('DOMAttrModified.accessible-megamenu', $.proxy(_DOMAttrModifiedHandler, this));
}
};
/* public attributes and methods ------------------------- */
return {
constructor: AccessibleMegaMenu,
/**
* @lends jQuery.fn.accessibleMegaMenu
* @desc Initializes an instance of the accessibleMegaMenu plugins
* @memberof jQuery.fn.accessibleMegaMenu
* @instance
*/
init: function () {
var settings = this.settings,
nav = $(this.element),
menu = nav.children().first(),
topnavitems = menu.children();
this.start(settings, nav, menu, topnavitems);
},
start: function(settings, nav, menu, topnavitems) {
var that = this;
this.settings = settings;
this.menu = menu;
this.topnavitems = topnavitems;
nav.attr("role", "navigation");
menu.addClass(settings.menuClass);
topnavitems.each(function (i, topnavitem) {
var topnavitemlink, topnavitempanel;
topnavitem = $(topnavitem);
topnavitem.addClass(settings.topNavItemClass);
topnavitemlink = topnavitem.find(":tabbable:first");
topnavitempanel = topnavitem.children(":not(:tabbable):last");
_addUniqueId.call(that, topnavitemlink);
if (topnavitempanel.length) {
_addUniqueId.call(that, topnavitempanel);
topnavitemlink.attr({
"aria-haspopup": true,
"aria-controls": topnavitempanel.attr("id"),
"aria-expanded": false
});
topnavitempanel.attr({
"role": "group",
"aria-expanded": false,
"aria-hidden": true
})
.addClass(settings.panelClass)
.not("[aria-labelledby]")
.attr("aria-labelledby", topnavitemlink.attr("id"));
}
});
this.panels = menu.find("." + settings.panelClass);
menu.on("focusin.accessible-megamenu", ":focusable, ." + settings.panelClass, $.proxy(_focusInHandler, this))
.on("focusout.accessible-megamenu", ":focusable, ." + settings.panelClass, $.proxy(_focusOutHandler, this))
.on("keydown.accessible-megamenu", $.proxy(_keyDownHandler, this))
.on("mouseover.accessible-megamenu", $.proxy(_mouseOverHandler, this))
.on("mouseout.accessible-megamenu", $.proxy(_mouseOutHandler, this))
.on("mousedown.accessible-megamenu", $.proxy(_mouseDownHandler, this));//original
// .on("mousedown.accessible-megamenu", $.proxy(_mouseOverHandler, this));
if (isTouch) {
menu.on("touchstart.accessible-megamenu", $.proxy(_clickHandler, this));
}
menu.find("hr").attr("role", "separator");
if ($(document.activeElement).closest(menu).length) {
$(document.activeElement).trigger("focusin.accessible-megamenu");
}
},
/**
* @desc Get default values
* @example $(selector).accessibleMegaMenu("getDefaults");
* @return {object}
* @memberof jQuery.fn.accessibleMegaMenu
* @instance
*/
getDefaults: function () {
return this._defaults;
},
/**
* @desc Get any option set to plugin using its name (as string)
* @example $(selector).accessibleMegaMenu("getOption", some_option);
* @param {string} opt
* @return {string}
* @memberof jQuery.fn.accessibleMegaMenu
* @instance
*/
getOption: function (opt) {
return this.settings[opt];
},
/**
* @desc Get all options
* @example $(selector).accessibleMegaMenu("getAllOptions");
* @return {object}
* @memberof jQuery.fn.accessibleMegaMenu
* @instance
*/
getAllOptions: function () {
return this.settings;
},
/**
* @desc Set option
* @example $(selector).accessibleMegaMenu("setOption", "option_name", "option_value", reinitialize);
* @param {string} opt - Option name
* @param {string} val - Option value
* @param {boolean} [reinitialize] - boolean to re-initialize the menu.
* @memberof jQuery.fn.accessibleMegaMenu
* @instance
*/
setOption: function (opt, value, reinitialize) {
this.settings[opt] = value;
if (reinitialize) {
this.init();
}
}
};
}());
/* lightweight plugin wrapper around the constructor,
to prevent against multiple instantiations */
/**
* @class accessibleMegaMenu
* @memberOf jQuery.fn
* @classdesc Implements an accessible mega menu as a jQuery plugin.
*
The mega-menu It is modeled after the mega menu on {@link http://adobe.com|adobe.com} but has been simplified for use by others. A brief description of the interaction design choices can be found in a blog post at {@link http://blogs.adobe.com/accessibility/2013/05/adobe-com.html|Mega menu accessibility on adobe.com}.
* Keyboard Accessibility
* The accessible mega menu supports keyboard interaction modeled after the behavior described in the {@link http://www.w3.org/TR/wai-aria-practices/#menu|WAI-ARIA Menu or Menu bar (widget) design pattern}, however we also try to respect users' general expectations for the behavior of links in a global navigation. To this end, the accessible mega menu implementation permits tab focus on each of the six top-level menu items. When one of the menu items has focus, pressing the Enter key, Spacebar or Down arrow will open the submenu panel, and pressing the Left or Right arrow key will shift focus to the adjacent menu item. Links within the submenu panels are included in the tab order when the panel is open. They can also be navigated with the arrow keys or by typing the first character in the link name, which speeds up keyboard navigation considerably. Pressing the Escape key closes the submenu and restores focus to the parent menu item.
* Screen Reader Accessibility
* The accessible mega menu models its use of WAI-ARIA Roles, States, and Properties after those described in the {@link http://www.w3.org/TR/wai-aria-practices/#menu|WAI-ARIA Menu or Menu bar (widget) design pattern} with some notable exceptions, so that it behaves better with screen reader user expectations for global navigation. We don't use role = "menu"
for the menu container and role = "menuitem"
for each of the links therein, because if we do, assistive technology will no longer interpret the links as links, but instead, as menu items, and the links in our global navigation will no longer show up when a screen reader user executes a shortcut command to bring up a list of links in the page.
* @example HTML
<nav>
<ul class="nav-menu">
<li class="nav-item">
<a href="?movie">Movies</a>
<div class="sub-nav">
<ul class="sub-nav-group">
<li><a href="?movie&genre=0">Action & Adventure</a></li>
<li><a href="?movie&genre=2">Children & Family</a></li>
<li>…</li>
</ul>
<ul class="sub-nav-group">
<li><a href="?movie&genre=7">Dramas</a></li>
<li><a href="?movie&genre=9">Foreign</a></li>
<li>…</li>
</ul>
<ul class="sub-nav-group">
<li><a href="?movie&genre=14">Musicals</a></li>
<li><a href="?movie&genre=15">Romance</a></li>
<li>…</li>
</ul>
</div>
</li>
<li class="nav-item">
<a href="?tv">TV Shows</a>
<div class="sub-nav">
<ul class="sub-nav-group">
<li><a href="?tv&genre=20">Classic TV</a></li>
<li><a href="?tv&genre=21">Crime TV</a></li>
<li>…</li>
</ul>
<ul class="sub-nav-group">
<li><a href="?tv&genre=27">Reality TV</a></li>
<li><a href="?tv&genre=30">TV Action</a></li>
<li>…</li>
</ul>
<ul class="sub-nav-group">
<li><a href="?tv&genre=33">TV Dramas</a></li>
<li><a href="?tv&genre=34">TV Horror</a></li>
<li>…</li>
</ul>
</div>
</li>
</ul>
</nav>
* @example CSS
/* Rudimentary mega menu CSS for demonstration */
/* mega menu list */
.nav-menu {
display: block;
position: relative;
list-style: none;
margin: 0;
padding: 0;
z-index: 15;
}
/* a top level navigation item in the mega menu */
.nav-item {
list-style: none;
display: inline-block;
padding: 0;
margin: 0;
}
/* first descendant link within a top level navigation item */
.nav-item > a {
position: relative;
display: inline-block;
padding: 0.5em 1em;
margin: 0 0 -1px 0;
border: 1px solid transparent;
}
/* focus/open states of first descendant link within a top level
navigation item */
.nav-item > a:focus,
.nav-item > a.open {
border: 1px solid #dedede;
}
/* open state of first descendant link within a top level
navigation item */
.nav-item > a.open {
background-color: #fff;
border-bottom: none;
z-index: 1;
}
/* sub-navigation panel */
.sub-nav {
position: absolute;
display: none;
top: 2.2em;
margin-top: -1px;
padding: 0.5em 1em;
border: 1px solid #dedede;
background-color: #fff;
}
/* sub-navigation panel open state */
.sub-nav.open {
display: block;
}
/* list of items within sub-navigation panel */
.sub-nav ul {
display: inline-block;
vertical-align: top;
margin: 0 1em 0 0;
padding: 0;
}
/* list item within sub-navigation panel */
.sub-nav li {
display: block;
list-style-type: none;
margin: 0;
padding: 0;
}
* @example JavaScript
<!-- include jquery -->
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<!-- include the jquery-accessibleMegaMenu plugin script -->
<script src="js/jquery-accessibleMegaMenu.js"></script>
<!-- initialize a selector as an accessibleMegaMenu -->
<script>
$("nav:first").accessibleMegaMenu({
/* prefix for generated unique id attributes, which are required to indicate aria-owns, aria-controls and aria-labelledby */
uuidPrefix: "accessible-megamenu",
/* css class used to define the megamenu styling */
menuClass: "nav-menu",
/* css class for a top-level navigation item in the megamenu */
topNavItemClass: "nav-item",
/* css class for a megamenu panel */
panelClass: "sub-nav",
/* css class for a group of items within a megamenu panel */
panelGroupClass: "sub-nav-group",
/* css class for the hover state */
hoverClass: "hover",
/* css class for the focus state */
focusClass: "focus",
/* css class for the open state */
openClass: "open"
});
</script>
* @param {object} [options] Mega Menu options
* @param {string} [options.uuidPrefix=accessible-megamenu] - Prefix for generated unique id attributes, which are required to indicate aria-owns, aria-controls and aria-labelledby
* @param {string} [options.menuClass=accessible-megamenu] - CSS class used to define the megamenu styling
* @param {string} [options.topNavItemClass=accessible-megamenu-top-nav-item] - CSS class for a top-level navigation item in the megamenu
* @param {string} [options.panelClass=accessible-megamenu-panel] - CSS class for a megamenu panel
* @param {string} [options.panelGroupClass=accessible-megamenu-panel-group] - CSS class for a group of items within a megamenu panel
* @param {string} [options.hoverClass=hover] - CSS class for the hover state
* @param {string} [options.focusClass=focus] - CSS class for the focus state
* @param {string} [options.openClass=open] - CSS class for the open state
*/
$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new $.fn[pluginName].AccessibleMegaMenu(this, options));
}
});
};
$.fn[pluginName].AccessibleMegaMenu = AccessibleMegaMenu;
/* :focusable and :tabbable selectors from
https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.core.js */
/**
* @private
*/
function visible(element) {
return $.expr.filters.visible(element) && !$(element).parents().addBack().filter(function () {
return $.css(this, "visibility") === "hidden";
}).length;
}
/**
* @private
*/
function focusable(element, isTabIndexNotNaN) {
var map, mapName, img,
nodeName = element.nodeName.toLowerCase();
if ("area" === nodeName) {
map = element.parentNode;
mapName = map.name;
if (!element.href || !mapName || map.nodeName.toLowerCase() !== "map") {
return false;
}
img = $("img[usemap=#" + mapName + "]")[0];
return !!img && visible(img);
}
return (/input|select|textarea|button|object/.test(nodeName) ? !element.disabled :
"a" === nodeName ?
element.href || isTabIndexNotNaN :
isTabIndexNotNaN) &&
// the element and all of its ancestors must be visible
visible(element);
}
$.extend($.expr[":"], {
data: $.expr.createPseudo ? $.expr.createPseudo(function (dataName) {
return function (elem) {
return !!$.data(elem, dataName);
};
}) : // support: jQuery <1.8
function (elem, i, match) {
return !!$.data(elem, match[3]);
},
focusable: function (element) {
return focusable(element, !isNaN($.attr(element, "tabindex")));
},
tabbable: function (element) {
var tabIndex = $.attr(element, "tabindex"),
isTabIndexNaN = isNaN(tabIndex);
return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN);
}
});
}(jQuery, window, document));
// End Plugin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//jQuery Function
$.fn.setFullHeight = function() {
var winWidth = $(window).width(),
winHeight = $(window).height() - $('#ahaHeader').height() - $('#top-header').height() - $('#primaryNav').height();
var $el = $(this);
$el.css({
'width': 'auto',
//'width': winWidth,
'height': winHeight
});
};
//Chosen
/*!
Chosen, a Select Box Enhancer for jQuery and Prototype
by Patrick Filler for Harvest, http://getharvest.com
Version 1.6.2
Full source at https://github.com/harvesthq/chosen
Copyright (c) 2011-2016 Harvest http://getharvest.com
MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
This file is generated by `grunt build`, do not edit it by hand.
*/
(function() {
var $, AbstractChosen, Chosen, SelectParser, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
SelectParser = (function() {
function SelectParser() {
this.options_index = 0;
this.parsed = [];
}
SelectParser.prototype.add_node = function(child) {
if (child.nodeName.toUpperCase() === "OPTGROUP") {
return this.add_group(child);
} else {
return this.add_option(child);
}
};
SelectParser.prototype.add_group = function(group) {
var group_position, option, _i, _len, _ref, _results;
group_position = this.parsed.length;
this.parsed.push({
array_index: group_position,
group: true,
label: this.escapeExpression(group.label),
title: group.title ? group.title : void 0,
children: 0,
disabled: group.disabled,
classes: group.className
});
_ref = group.childNodes;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
option = _ref[_i];
_results.push(this.add_option(option, group_position, group.disabled));
}
return _results;
};
SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
if (option.nodeName.toUpperCase() === "OPTION") {
if (option.text !== "") {
if (group_position != null) {
this.parsed[group_position].children += 1;
}
this.parsed.push({
array_index: this.parsed.length,
options_index: this.options_index,
value: option.value,
text: option.text,
html: option.innerHTML,
title: option.title ? option.title : void 0,
selected: option.selected,
disabled: group_disabled === true ? group_disabled : option.disabled,
group_array_index: group_position,
group_label: group_position != null ? this.parsed[group_position].label : null,
classes: option.className,
style: option.style.cssText
});
} else {
this.parsed.push({
array_index: this.parsed.length,
options_index: this.options_index,
empty: true
});
}
return this.options_index += 1;
}
};
SelectParser.prototype.escapeExpression = function(text) {
var map, unsafe_chars;
if ((text == null) || text === false) {
return "";
}
if (!/[\&\<\>\"\'\`]/.test(text)) {
return text;
}
map = {
"<": "<",
">": ">",
'"': """,
"'": "'",
"`": "`"
};
unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
return text.replace(unsafe_chars, function(chr) {
return map[chr] || "&";
});
};
return SelectParser;
})();
SelectParser.select_to_array = function(select) {
var child, parser, _i, _len, _ref;
parser = new SelectParser();
_ref = select.childNodes;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
parser.add_node(child);
}
return parser.parsed;
};
AbstractChosen = (function() {
function AbstractChosen(form_field, options) {
this.form_field = form_field;
this.options = options != null ? options : {};
if (!AbstractChosen.browser_is_supported()) {
return;
}
this.is_multiple = this.form_field.multiple;
this.set_default_text();
this.set_default_values();
this.setup();
this.set_up_html();
this.register_observers();
this.on_ready();
}
AbstractChosen.prototype.set_default_values = function() {
var _this = this;
this.click_test_action = function(evt) {
return _this.test_active_click(evt);
};
this.activate_action = function(evt) {
return _this.activate_field(evt);
};
this.active_field = false;
this.mouse_on_container = false;
this.results_showing = false;
this.result_highlighted = null;
this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
this.disable_search_threshold = this.options.disable_search_threshold || 0;
this.disable_search = this.options.disable_search || false;
this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
this.group_search = this.options.group_search != null ? this.options.group_search : true;
this.search_contains = this.options.search_contains || false;
this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
this.max_selected_options = this.options.max_selected_options || Infinity;
this.inherit_select_classes = this.options.inherit_select_classes || false;
this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
this.include_group_label_in_selected = this.options.include_group_label_in_selected || false;
this.max_shown_results = this.options.max_shown_results || Number.POSITIVE_INFINITY;
return this.case_sensitive_search = this.options.case_sensitive_search || false;
};
AbstractChosen.prototype.set_default_text = function() {
if (this.form_field.getAttribute("data-placeholder")) {
this.default_text = this.form_field.getAttribute("data-placeholder");
} else if (this.is_multiple) {
this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
} else {
this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
}
return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
};
AbstractChosen.prototype.choice_label = function(item) {
if (this.include_group_label_in_selected && (item.group_label != null)) {
return "" + item.group_label + " " + item.html;
} else {
return item.html;
}
};
AbstractChosen.prototype.mouse_enter = function() {
return this.mouse_on_container = true;
};
AbstractChosen.prototype.mouse_leave = function() {
return this.mouse_on_container = false;
};
AbstractChosen.prototype.input_focus = function(evt) {
var _this = this;
if (this.is_multiple) {
if (!this.active_field) {
return setTimeout((function() {
return _this.container_mousedown();
}), 50);
}
} else {
if (!this.active_field) {
return this.activate_field();
}
}
};
AbstractChosen.prototype.input_blur = function(evt) {
var _this = this;
if (!this.mouse_on_container) {
this.active_field = false;
return setTimeout((function() {
return _this.blur_test();
}), 100);
}
};
AbstractChosen.prototype.results_option_build = function(options) {
var content, data, data_content, shown_results, _i, _len, _ref;
content = '';
shown_results = 0;
_ref = this.results_data;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
data = _ref[_i];
data_content = '';
if (data.group) {
data_content = this.result_add_group(data);
} else {
data_content = this.result_add_option(data);
}
if (data_content !== '') {
shown_results++;
content += data_content;
}
if (options != null ? options.first : void 0) {
if (data.selected && this.is_multiple) {
this.choice_build(data);
} else if (data.selected && !this.is_multiple) {
this.single_set_selected_text(this.choice_label(data));
}
}
if (shown_results >= this.max_shown_results) {
break;
}
}
return content;
};
AbstractChosen.prototype.result_add_option = function(option) {
var classes, option_el;
if (!option.search_match) {
return '';
}
if (!this.include_option_in_results(option)) {
return '';
}
classes = [];
if (!option.disabled && !(option.selected && this.is_multiple)) {
classes.push("active-result");
}
if (option.disabled && !(option.selected && this.is_multiple)) {
classes.push("disabled-result");
}
if (option.selected) {
classes.push("result-selected");
}
if (option.group_array_index != null) {
classes.push("group-option");
}
if (option.classes !== "") {
classes.push(option.classes);
}
option_el = document.createElement("li");
option_el.className = classes.join(" ");
option_el.style.cssText = option.style;
//Note:TU LI CUSTOM
option_el.setAttribute("data-option-array-index", option.array_index);
option_el.setAttribute("role","option");
option_el.setAttribute("tabindex","-1");
//option_el.setAttribute("aria-live","polite");
//option_el.setAttribute("id","ss_opt"+option.array_index);
option_el.innerHTML = option.search_text;
if (option.title) {
option_el.title = option.title;
}
return this.outerHTML(option_el);
};
AbstractChosen.prototype.result_add_group = function(group) {
var classes, group_el;
if (!(group.search_match || group.group_match)) {
return '';
}
if (!(group.active_options > 0)) {
return '';
}
classes = [];
classes.push("group-result");
if (group.classes) {
classes.push(group.classes);
}
group_el = document.createElement("li");
group_el.className = classes.join(" ");
group_el.innerHTML = group.search_text;
if (group.title) {
group_el.title = group.title;
}
return this.outerHTML(group_el);
};
AbstractChosen.prototype.results_update_field = function() {
this.set_default_text();
if (!this.is_multiple) {
this.results_reset_cleanup();
}
this.result_clear_highlight();
this.results_build();
if (this.results_showing) {
return this.winnow_results();
}
};
AbstractChosen.prototype.reset_single_select_options = function() {
var result, _i, _len, _ref, _results;
_ref = this.results_data;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i];
if (result.selected) {
_results.push(result.selected = false);
} else {
_results.push(void 0);
}
}
return _results;
};
AbstractChosen.prototype.results_toggle = function() {
if (this.results_showing) {
return this.results_hide();
} else {
return this.results_show();
}
};
AbstractChosen.prototype.results_search = function(evt) {
if (this.results_showing) {
return this.winnow_results();
} else {
return this.results_show();
}
};
AbstractChosen.prototype.winnow_results = function() {
var escapedSearchText, option, regex, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
this.no_results_clear();
results = 0;
searchText = this.get_search_text();
escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
zregex = new RegExp(escapedSearchText, 'i');
regex = this.get_search_regex(escapedSearchText);
_ref = this.results_data;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
option = _ref[_i];
option.search_match = false;
results_group = null;
if (this.include_option_in_results(option)) {
if (option.group) {
option.group_match = false;
option.active_options = 0;
}
if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
results_group = this.results_data[option.group_array_index];
if (results_group.active_options === 0 && results_group.search_match) {
results += 1;
}
results_group.active_options += 1;
}
option.search_text = option.group ? option.label : option.html;
if (!(option.group && !this.group_search)) {
option.search_match = this.search_string_match(option.search_text, regex);
if (option.search_match && !option.group) {
results += 1;
}
if (option.search_match) {
if (searchText.length) {
startpos = option.search_text.search(zregex);
text = option.search_text.substr(0, startpos + searchText.length) + '' + option.search_text.substr(startpos + searchText.length);
option.search_text = text.substr(0, startpos) + '' + text.substr(startpos);
}
if (results_group != null) {
results_group.group_match = true;
}
} else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
option.search_match = true;
}
}
}
}
this.result_clear_highlight();
if (results < 1 && searchText.length) {
this.update_results_content("");
return this.no_results(searchText);
} else {
this.update_results_content(this.results_option_build());
return this.winnow_results_set_highlight();
}
};
AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
var regex_anchor, regex_flag;
regex_anchor = this.search_contains ? "" : "^";
regex_flag = this.case_sensitive_search ? "" : "i";
return new RegExp(regex_anchor + escaped_search_string, regex_flag);
};
AbstractChosen.prototype.search_string_match = function(search_string, regex) {
var part, parts, _i, _len;
if (regex.test(search_string)) {
return true;
} else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
parts = search_string.replace(/\[|\]/g, "").split(" ");
if (parts.length) {
for (_i = 0, _len = parts.length; _i < _len; _i++) {
part = parts[_i];
if (regex.test(part)) {
return true;
}
}
}
}
};
AbstractChosen.prototype.choices_count = function() {
var option, _i, _len, _ref;
if (this.selected_option_count != null) {
return this.selected_option_count;
}
this.selected_option_count = 0;
_ref = this.form_field.options;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
option = _ref[_i];
if (option.selected) {
this.selected_option_count += 1;
}
}
return this.selected_option_count;
};
AbstractChosen.prototype.choices_click = function(evt) {
evt.preventDefault();
if (!(this.results_showing || this.is_disabled)) {
return this.results_show();
}
};
AbstractChosen.prototype.keyup_checker = function(evt) {
var stroke, _ref;
stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
this.search_field_scale();
switch (stroke) {
case 8:
if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
return this.keydown_backstroke();
} else if (!this.pending_backstroke) {
this.result_clear_highlight();
return this.results_search();
}
break;
case 13:
evt.preventDefault();
if (this.results_showing) {
return this.result_select(evt);
}
break;
case 27:
if (this.results_showing) {
this.results_hide();
}
return true;
case 9:
case 38:
case 40:
case 16:
case 91:
case 17:
case 18:
break;
default:
return this.results_search();
}
};
AbstractChosen.prototype.clipboard_event_checker = function(evt) {
var _this = this;
return setTimeout((function() {
return _this.results_search();
}), 50);
};
AbstractChosen.prototype.container_width = function() {
if (this.options.width != null) {
return this.options.width;
} else {
return "" + this.form_field.offsetWidth + "px";
}
};
AbstractChosen.prototype.include_option_in_results = function(option) {
if (this.is_multiple && (!this.display_selected_options && option.selected)) {
return false;
}
if (!this.display_disabled_options && option.disabled) {
return false;
}
if (option.empty) {
return false;
}
return true;
};
AbstractChosen.prototype.search_results_touchstart = function(evt) {
this.touch_started = true;
return this.search_results_mouseover(evt);
};
AbstractChosen.prototype.search_results_touchmove = function(evt) {
this.touch_started = false;
return this.search_results_mouseout(evt);
};
AbstractChosen.prototype.search_results_touchend = function(evt) {
if (this.touch_started) {
return this.search_results_mouseup(evt);
}
};
AbstractChosen.prototype.outerHTML = function(element) {
var tmp;
if (element.outerHTML) {
return element.outerHTML;
}
tmp = document.createElement("div");
tmp.appendChild(element);
return tmp.innerHTML;
};
AbstractChosen.browser_is_supported = function() {
if ("Microsoft Internet Explorer" === window.navigator.appName) {
return document.documentMode >= 8;
}
if (/iP(od|hone)/i.test(window.navigator.userAgent) || /IEMobile/i.test(window.navigator.userAgent) || /Windows Phone/i.test(window.navigator.userAgent) || /BlackBerry/i.test(window.navigator.userAgent) || /BB10/i.test(window.navigator.userAgent) || /Android.*Mobile/i.test(window.navigator.userAgent)) {
return false;
}
return true;
};
AbstractChosen.default_multiple_text = "Select Some Options";
AbstractChosen.default_single_text = "Select an Option";
AbstractChosen.default_no_result_text = "No results match";
return AbstractChosen;
})();
$ = jQuery;
$.fn.extend({
chosen: function(options) {
if (!AbstractChosen.browser_is_supported()) {
return this;
}
return this.each(function(input_field) {
var $this, chosen;
$this = $(this);
chosen = $this.data('chosen');
if (options === 'destroy') {
if (chosen instanceof Chosen) {
chosen.destroy();
}
return;
}
if (!(chosen instanceof Chosen)) {
$this.data('chosen', new Chosen(this, options));
}
});
}
});
Chosen = (function(_super) {
__extends(Chosen, _super);
function Chosen() {
_ref = Chosen.__super__.constructor.apply(this, arguments);
return _ref;
}
Chosen.prototype.setup = function() {
this.form_field_jq = $(this.form_field);
this.current_selectedIndex = this.form_field.selectedIndex;
return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
};
Chosen.prototype.set_up_html = function() {
var container_classes, container_props;
container_classes = ["chosen-container"];
container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
if (this.inherit_select_classes && this.form_field.className) {
container_classes.push(this.form_field.className);
}
if (this.is_rtl) {
container_classes.push("chosen-rtl");
}
container_props = {
'class': container_classes.join(' '),
'style': "width: " + (this.container_width()) + ";",
'title': this.form_field.title
};
if (this.form_field.id.length) {
container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
}
this.container = $("
", container_props);
//Modify to inject label for search input field for accessibility
//Generate random
var rand = Date.now();
if (this.is_multiple) {
this.container.html('');
} else {
this.container.html('' + this.default_text + '
');
}
//
// Note: TU LISTBOX
this.form_field_jq.hide().after(this.container);
this.dropdown = this.container.find('div.chosen-drop').first();
this.search_field = this.container.find('input').first();
this.search_results = this.container.find('ul.chosen-results').first();
this.search_field_scale();
this.search_no_results = this.container.find('li.no-results').first();
if (this.is_multiple) {
this.search_choices = this.container.find('ul.chosen-choices').first();
this.search_container = this.container.find('li.search-field').first();
} else {
this.search_container = this.container.find('div.chosen-search').first();
this.selected_item = this.container.find('.chosen-single').first();
}
this.results_build();
this.set_tab_index();
return this.set_label_behavior();
};
Chosen.prototype.on_ready = function() {
return this.form_field_jq.trigger("chosen:ready", {
chosen: this
});
};
Chosen.prototype.register_observers = function() {
var _this = this;
this.container.bind('touchstart.chosen', function(evt) {
_this.container_mousedown(evt);
return evt.preventDefault();
});
this.container.bind('touchend.chosen', function(evt) {
_this.container_mouseup(evt);
return evt.preventDefault();
});
this.container.bind('mousedown.chosen', function(evt) {
_this.container_mousedown(evt);
});
this.container.bind('mouseup.chosen', function(evt) {
_this.container_mouseup(evt);
});
this.container.bind('mouseenter.chosen', function(evt) {
_this.mouse_enter(evt);
});
this.container.bind('mouseleave.chosen', function(evt) {
_this.mouse_leave(evt);
});
this.search_results.bind('mouseup.chosen', function(evt) {
_this.search_results_mouseup(evt);
});
this.search_results.bind('mouseover.chosen', function(evt) {
_this.search_results_mouseover(evt);
});
this.search_results.bind('mouseout.chosen', function(evt) {
_this.search_results_mouseout(evt);
});
this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
_this.search_results_mousewheel(evt);
});
this.search_results.bind('touchstart.chosen', function(evt) {
_this.search_results_touchstart(evt);
});
this.search_results.bind('touchmove.chosen', function(evt) {
_this.search_results_touchmove(evt);
});
this.search_results.bind('touchend.chosen', function(evt) {
_this.search_results_touchend(evt);
});
this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
_this.results_update_field(evt);
});
this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
_this.activate_field(evt);
});
this.form_field_jq.bind("chosen:open.chosen", function(evt) {
_this.container_mousedown(evt);
});
this.form_field_jq.bind("chosen:close.chosen", function(evt) {
_this.input_blur(evt);
});
this.search_field.bind('blur.chosen', function(evt) {
_this.input_blur(evt);
});
this.search_field.bind('keyup.chosen', function(evt) {
_this.keyup_checker(evt);
});
this.search_field.bind('keydown.chosen', function(evt) {
_this.keydown_checker(evt);
});
this.search_field.bind('focus.chosen', function(evt) {
_this.input_focus(evt);
});
this.search_field.bind('cut.chosen', function(evt) {
_this.clipboard_event_checker(evt);
});
this.search_field.bind('paste.chosen', function(evt) {
_this.clipboard_event_checker(evt);
});
if (this.is_multiple) {
return this.search_choices.bind('click.chosen', function(evt) {
_this.choices_click(evt);
});
} else {
return this.container.bind('click.chosen', function(evt) {
evt.preventDefault();
});
}
};
Chosen.prototype.destroy = function() {
$(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
if (this.search_field[0].tabIndex) {
this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
}
this.container.remove();
this.form_field_jq.removeData('chosen');
return this.form_field_jq.show();
};
Chosen.prototype.search_field_disabled = function() {
this.is_disabled = this.form_field_jq[0].disabled;
if (this.is_disabled) {
this.container.addClass('chosen-disabled');
this.search_field[0].disabled = true;
if (!this.is_multiple) {
this.selected_item.unbind("focus.chosen", this.activate_action);
}
return this.close_field();
} else {
this.container.removeClass('chosen-disabled');
this.search_field[0].disabled = false;
if (!this.is_multiple) {
return this.selected_item.bind("focus.chosen", this.activate_action);
}
}
};
Chosen.prototype.container_mousedown = function(evt) {
if (!this.is_disabled) {
if (evt && evt.type === "mousedown" && !this.results_showing) {
evt.preventDefault();
}
if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
if (!this.active_field) {
if (this.is_multiple) {
this.search_field.val("");
}
$(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
this.results_show();
} else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
evt.preventDefault();
this.results_toggle();
}
return this.activate_field();
}
}
};
Chosen.prototype.container_mouseup = function(evt) {
if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
return this.results_reset(evt);
}
};
Chosen.prototype.search_results_mousewheel = function(evt) {
var delta;
if (evt.originalEvent) {
delta = evt.originalEvent.deltaY || -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
}
if (delta != null) {
evt.preventDefault();
if (evt.type === 'DOMMouseScroll') {
delta = delta * 40;
}
return this.search_results.scrollTop(delta + this.search_results.scrollTop());
}
};
Chosen.prototype.blur_test = function(evt) {
if (!this.active_field && this.container.hasClass("chosen-container-active")) {
return this.close_field();
}
};
Chosen.prototype.close_field = function() {
$(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
this.active_field = false;
this.results_hide();
this.container.removeClass("chosen-container-active");
this.clear_backstroke();
this.show_search_field_default();
return this.search_field_scale();
};
Chosen.prototype.activate_field = function() {
this.container.addClass("chosen-container-active");
this.active_field = true;
this.search_field.val(this.search_field.val());
return this.search_field.focus();
};
Chosen.prototype.test_active_click = function(evt) {
var active_container;
active_container = $(evt.target).closest('.chosen-container');
if (active_container.length && this.container[0] === active_container[0]) {
return this.active_field = true;
} else {
return this.close_field();
}
};
Chosen.prototype.results_build = function() {
this.parsing = true;
this.selected_option_count = null;
this.results_data = SelectParser.select_to_array(this.form_field);
if (this.is_multiple) {
this.search_choices.find("li.search-choice").remove();
} else if (!this.is_multiple) {
this.single_set_selected_text();
if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
this.search_field[0].readOnly = true;
this.container.addClass("chosen-container-single-nosearch");
} else {
this.search_field[0].readOnly = false;
this.container.removeClass("chosen-container-single-nosearch");
}
}
this.update_results_content(this.results_option_build({
first: true
}));
this.search_field_disabled();
this.show_search_field_default();
this.search_field_scale();
return this.parsing = false;
};
Chosen.prototype.result_do_highlight = function(el) {
var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
if (el.length) {
this.result_clear_highlight();
this.result_highlight = el;
this.result_highlight.addClass("highlighted");
//Note: TU HIGHLIGHTED ITEM
this.result_highlight.addClass("focused");
//this.result_highlight.attr("tabindex","0");
//this.result_highlight.attr("aria-selected","true");
maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
visible_top = this.search_results.scrollTop();
visible_bottom = maxHeight + visible_top;
high_top = this.result_highlight.position().top + this.search_results.scrollTop();
high_bottom = high_top + this.result_highlight.outerHeight();
if (high_bottom >= visible_bottom) {
return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
} else if (high_top < visible_top) {
return this.search_results.scrollTop(high_top);
}
}
};
Chosen.prototype.result_clear_highlight = function() {
if (this.result_highlight) {
this.result_highlight.removeClass("highlighted");
this.result_highlight.removeClass("focused");
//note: TU REMOVE HIGHLIGHTED
//this.result_highlight.attr("tabindex","-1");
//this.result_highlight.removeAttr("aria-selected")
}
return this.result_highlight = null;
};
Chosen.prototype.results_show = function() {
if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
this.form_field_jq.trigger("chosen:maxselected", {
chosen: this
});
return false;
}
this.container.addClass("chosen-with-drop");
this.results_showing = true;
this.search_field.focus();
this.search_field.val(this.search_field.val());
this.winnow_results();
return this.form_field_jq.trigger("chosen:showing_dropdown", {
chosen: this
});
};
Chosen.prototype.update_results_content = function(content) {
return this.search_results.html(content);
};
Chosen.prototype.results_hide = function() {
if (this.results_showing) {
this.result_clear_highlight();
this.container.removeClass("chosen-with-drop");
this.form_field_jq.trigger("chosen:hiding_dropdown", {
chosen: this
});
}
return this.results_showing = false;
};
Chosen.prototype.set_tab_index = function(el) {
var ti;
if (this.form_field.tabIndex) {
ti = this.form_field.tabIndex;
this.form_field.tabIndex = -1;
return this.search_field[0].tabIndex = ti;
}
};
Chosen.prototype.set_label_behavior = function() {
var _this = this;
this.form_field_label = this.form_field_jq.parents("label");
if (!this.form_field_label.length && this.form_field.id.length) {
this.form_field_label = $("label[for='" + this.form_field.id + "']");
}
if (this.form_field_label.length > 0) {
return this.form_field_label.bind('click.chosen', function(evt) {
if (_this.is_multiple) {
return _this.container_mousedown(evt);
} else {
return _this.activate_field();
}
});
}
};
Chosen.prototype.show_search_field_default = function() {
if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
this.search_field.val(this.default_text);
return this.search_field.addClass("default");
} else {
this.search_field.val("");
return this.search_field.removeClass("default");
}
};
Chosen.prototype.search_results_mouseup = function(evt) {
var target;
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
if (target.length) {
this.result_highlight = target;
this.result_select(evt);
return this.search_field.focus();
}
};
Chosen.prototype.search_results_mouseover = function(evt) {
var target;
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
if (target) {
return this.result_do_highlight(target);
}
};
Chosen.prototype.search_results_mouseout = function(evt) {
if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
return this.result_clear_highlight();
}
};
Chosen.prototype.choice_build = function(item) {
var choice, close_link,
_this = this;
choice = $(' ', {
"class": "search-choice"
}).html("" + (this.choice_label(item)) + " ");
if (item.disabled) {
choice.addClass('search-choice-disabled');
} else {
close_link = $(' ', {
"class": 'search-choice-close',
'data-option-array-index': item.array_index
});
close_link.bind('click.chosen', function(evt) {
return _this.choice_destroy_link_click(evt);
});
choice.append(close_link);
}
return this.search_container.before(choice);
};
Chosen.prototype.choice_destroy_link_click = function(evt) {
evt.preventDefault();
evt.stopPropagation();
if (!this.is_disabled) {
return this.choice_destroy($(evt.target));
}
};
Chosen.prototype.choice_destroy = function(link) {
if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
this.show_search_field_default();
if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
this.results_hide();
}
link.parents('li').first().remove();
return this.search_field_scale();
}
};
Chosen.prototype.results_reset = function() {
this.reset_single_select_options();
this.form_field.options[0].selected = true;
this.single_set_selected_text();
this.show_search_field_default();
this.results_reset_cleanup();
this.form_field_jq.trigger("change");
if (this.active_field) {
return this.results_hide();
}
};
Chosen.prototype.results_reset_cleanup = function() {
this.current_selectedIndex = this.form_field.selectedIndex;
return this.selected_item.find("abbr").remove();
};
Chosen.prototype.result_select = function(evt) {
var high, item;
if (this.result_highlight) {
high = this.result_highlight;
this.result_clear_highlight();
if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
this.form_field_jq.trigger("chosen:maxselected", {
chosen: this
});
return false;
}
if (this.is_multiple) {
high.removeClass("active-result");
} else {
this.reset_single_select_options();
}
high.addClass("result-selected");
//Note: TU SELECTED
high.attr("tabindex","0");
high.attr("aria-selected","0");
//high.focus();//adding focus will read the selected in the screen reader but will fail for multiselect
// screen need to read how many selected from the list when multiple is turned on
item = this.results_data[high[0].getAttribute("data-option-array-index")];
item.selected = true;
this.form_field.options[item.options_index].selected = true;
this.selected_option_count = null;
if (this.is_multiple) {
this.choice_build(item);
} else {
this.single_set_selected_text(this.choice_label(item));
}
if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
this.results_hide();
}
this.show_search_field_default();
if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
this.form_field_jq.trigger("change", {
'selected': this.form_field.options[item.options_index].value
});
}
this.current_selectedIndex = this.form_field.selectedIndex;
evt.preventDefault();
return this.search_field_scale();
}
};
Chosen.prototype.single_set_selected_text = function(text) {
if (text == null) {
text = this.default_text;
}
if (text === this.default_text) {
this.selected_item.addClass("chosen-default");
} else {
this.single_deselect_control_build();
this.selected_item.removeClass("chosen-default");
}
return this.selected_item.find("span").html(text);
};
Chosen.prototype.result_deselect = function(pos) {
var result_data;
result_data = this.results_data[pos];
if (!this.form_field.options[result_data.options_index].disabled) {
result_data.selected = false;
this.form_field.options[result_data.options_index].selected = false;
this.selected_option_count = null;
this.result_clear_highlight();
if (this.results_showing) {
this.winnow_results();
}
this.form_field_jq.trigger("change", {
deselected: this.form_field.options[result_data.options_index].value
});
this.search_field_scale();
return true;
} else {
return false;
}
};
Chosen.prototype.single_deselect_control_build = function() {
if (!this.allow_single_deselect) {
return;
}
if (!this.selected_item.find("abbr").length) {
this.selected_item.find("span").first().after(" ");
}
return this.selected_item.addClass("chosen-single-with-deselect");
};
Chosen.prototype.get_search_text = function() {
return $('
').text($.trim(this.search_field.val())).html();
};
Chosen.prototype.winnow_results_set_highlight = function() {
var do_high, selected_results;
selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
if (do_high != null) {
return this.result_do_highlight(do_high);
}
};
Chosen.prototype.no_results = function(terms) {
var no_results_html;
no_results_html = $('' + this.results_none_found + ' " " ');
no_results_html.find("span").first().html(terms);
this.search_results.append(no_results_html);
return this.form_field_jq.trigger("chosen:no_results", {
chosen: this
});
};
Chosen.prototype.no_results_clear = function() {
return this.search_results.find(".no-results").remove();
};
Chosen.prototype.keydown_arrow = function() {
var next_sib;
if (this.results_showing && this.result_highlight) {
next_sib = this.result_highlight.nextAll("li.active-result").first();
if (next_sib) {
return this.result_do_highlight(next_sib);
}
} else {
return this.results_show();
}
};
Chosen.prototype.keyup_arrow = function() {
var prev_sibs;
if (!this.results_showing && !this.is_multiple) {
return this.results_show();
} else if (this.result_highlight) {
prev_sibs = this.result_highlight.prevAll("li.active-result");
if (prev_sibs.length) {
return this.result_do_highlight(prev_sibs.first());
} else {
if (this.choices_count() > 0) {
this.results_hide();
}
return this.result_clear_highlight();
}
}
};
Chosen.prototype.keydown_backstroke = function() {
var next_available_destroy;
if (this.pending_backstroke) {
this.choice_destroy(this.pending_backstroke.find("a").first());
return this.clear_backstroke();
} else {
next_available_destroy = this.search_container.siblings("li.search-choice").last();
if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
this.pending_backstroke = next_available_destroy;
if (this.single_backstroke_delete) {
return this.keydown_backstroke();
} else {
return this.pending_backstroke.addClass("search-choice-focus");
}
}
}
};
Chosen.prototype.clear_backstroke = function() {
if (this.pending_backstroke) {
this.pending_backstroke.removeClass("search-choice-focus");
}
return this.pending_backstroke = null;
};
Chosen.prototype.keydown_checker = function(evt) {
var stroke, _ref1;
stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
this.search_field_scale();
if (stroke !== 8 && this.pending_backstroke) {
this.clear_backstroke();
}
switch (stroke) {
case 8:
this.backstroke_length = this.search_field.val().length;
break;
case 9:
if (this.results_showing && !this.is_multiple) {
this.result_select(evt);
}
this.mouse_on_container = false;
break;
case 13:
if (this.results_showing) {
evt.preventDefault();
}
break;
case 32:
if (this.disable_search) {
evt.preventDefault();
}
break;
case 38:
evt.preventDefault();
this.keyup_arrow();
break;
case 40:
evt.preventDefault();
this.keydown_arrow();
break;
}
};
Chosen.prototype.search_field_scale = function() {
var div, f_width, h, style, style_block, styles, w, _i, _len;
if (this.is_multiple) {
h = 0;
w = 0;
style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
for (_i = 0, _len = styles.length; _i < _len; _i++) {
style = styles[_i];
style_block += style + ":" + this.search_field.css(style) + ";";
}
div = $('
', {
'style': style_block
});
div.text(this.search_field.val());
$('body').append(div);
w = div.width() + 25;
div.remove();
f_width = this.container.outerWidth();
if (w > f_width - 10) {
w = f_width - 10;
}
return this.search_field.css({
'width': w + 'px'
});
}
};
return Chosen;
})(AbstractChosen);
}).call(this);
//End chosen
//Radio jQuery
/* =============================================================
* radio.js v0.0.3
* ============================================================ */
!function ($) {
/* RADIO PUBLIC CLASS DEFINITION
* ============================== */
var Radio = function (element, options) {
this.init(element, options);
}
Radio.prototype = {
constructor: Radio
, init: function (element, options) {
var $el = this.$element = $(element)
this.options = $.extend({}, $.fn.radio.defaults, options);
$el.before(this.options.template);
this.setState();
}
, setState: function () {
var $el = this.$element
, $parent = $el.closest('.radio');
$el.prop('disabled') && $parent.addClass('disabled');
$el.prop('checked') && $parent.addClass('checked');
}
, toggle: function () {
var d = 'disabled'
, ch = 'checked'
, $el = this.$element
, checked = $el.prop(ch)
, $parent = $el.closest('.radio')
, $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body')
, $elemGroup = $parentWrap.find(':radio[name="' + $el.attr('name') + '"]')
, e = $.Event('toggle')
$elemGroup.not($el).each(function () {
var $el = $(this)
, $parent = $(this).closest('.radio');
if ($el.prop(d) == false) {
$parent.removeClass(ch) && $el.removeAttr(ch).trigger('change');
}
});
if ($el.prop(d) == false) {
if (checked == false) $parent.addClass(ch) && $el.attr(ch, true);
$el.trigger(e);
if (checked !== $el.prop(ch)) {
$el.trigger('change');
}
}
}
, setCheck: function (option) {
var ch = 'checked'
, $el = this.$element
, $parent = $el.closest('.radio')
, checkAction = option == 'check' ? true : false
, checked = $el.prop(ch)
, $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body')
, $elemGroup = $parentWrap.find(':radio[name="' + $el['attr']('name') + '"]')
, e = $.Event(option)
$elemGroup.not($el).each(function () {
var $el = $(this)
, $parent = $(this).closest('.radio');
$parent.removeClass(ch) && $el.removeAttr(ch);
});
$parent[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch);
$el.trigger(e);
if (checked !== $el.prop(ch)) {
$el.trigger('change');
}
}
}
/* RADIO PLUGIN DEFINITION
* ======================== */
// var old = $.fn.radio
/* $.fn.radio = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('radio')
, options = $.extend({}, $.fn.radio.defaults, $this.data(), typeof option == 'object' && option);
if (!data) $this.data('radio', (data = new Radio(this, options)));
if (option == 'toggle') data.toggle()
if (option == 'check' || option == 'uncheck') data.setCheck(option)
else if (option) data.setState();
});
}*/
/*$.fn.radio.defaults = {
template: ' '
}*/
/* RADIO NO CONFLICT
* ================== */
/*$.fn.radio.noConflict = function () {
$.fn.radio = old;
return this;
}*/
/* RADIO DATA-API
* =============== */
/*$(document).on('click.radio.data-api', '[data-toggle^=radio], .radio', function (e) {
var $radio = $(e.target);
e && e.preventDefault() && e.stopPropagation();
if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio');
$radio.find(':radio').radio('toggle');
});*/
/*$(function () {
$('[data-toggle="radio"]').each(function () {
var $radio = $(this);
$radio.radio();
});
});*/
// Radio Accessible
/*$('label.radio').on('keypress',function (e) {
var key = e.which;
if(key == 13 || key == 32) // the enter key code
{
var $radio = $(e.target);
e && e.preventDefault() && e.stopPropagation();
if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio');
$radio.find(':radio').radio('toggle');
}
});*/
}(window.jQuery);
//End Radio jQuery
//Checkbox jQuery
/* =============================================================
* checkbox v0.0.3
* ============================================================ */
!function ($) {
/* CHECKBOX PUBLIC CLASS DEFINITION
* ============================== */
var Checkbox = function (element, options) {
this.init(element, options);
}
Checkbox.prototype = {
constructor: Checkbox
, init: function (element, options) {
var $el = this.$element = $(element)
this.options = $.extend({}, $.fn.checkbox.defaults, options);
$el.before(this.options.template);
this.setState();
}
, setState: function () {
var $el = this.$element
, $parent = $el.closest('.checkbox');
$el.prop('disabled') && $parent.addClass('disabled');
$el.prop('checked') && $parent.addClass('checked');
}
, toggle: function () {
var ch = 'checked'
, $el = this.$element
, $parent = $el.closest('.checkbox')
, checked = $el.prop(ch)
, e = $.Event('toggle')
if ($el.prop('disabled') == false) {
$parent.toggleClass(ch) && checked ? $el.removeAttr(ch) : $el.prop(ch, ch);
$el.trigger(e).trigger('change');
}
}
, setCheck: function (option) {
var d = 'disabled'
, ch = 'checked'
, $el = this.$element
, $parent = $el.closest('.checkbox')
, checkAction = option == 'check' ? true : false
, e = $.Event(option)
$parent[checkAction ? 'addClass' : 'removeClass' ](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch);
$el.trigger(e).trigger('change');
}
}
/* CHECKBOX PLUGIN DEFINITION
* ======================== */
var old = $.fn.checkbox;
$.fn.checkbox = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('checkbox')
, options = $.extend({}, $.fn.checkbox.defaults, $this.data(), typeof option == 'object' && option);
if (!data) $this.data('checkbox', (data = new Checkbox(this, options)));
if (option == 'toggle') data.toggle()
if (option == 'check' || option == 'uncheck') data.setCheck(option)
else if (option) data.setState();
});
}
$.fn.checkbox.defaults = {
template: ' '
}
/* CHECKBOX NO CONFLICT
* ================== */
/*$.fn.checkbox.noConflict = function () {
$.fn.checkbox = old;
return this;
}*/
/* CHECKBOX DATA-API
* =============== */
/*$(document).on('click.checkbox.data-api', '[data-toggle^=checkbox], .checkbox', function (e) {
var $checkbox = $(e.target);
var key = e.which;
if (e.target.tagName != "A") {
e && e.preventDefault() && e.stopPropagation();
if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox');
$checkbox.find(':checkbox').checkbox('toggle');
}
});*/
// Going to to standard browser form components because of screen reader and accessibility
/*$(function () {
$('[data-toggle="checkbox"]').each(function () {
var $checkbox = $(this);
$checkbox.checkbox();
});
});*/
// Checkbox Accessible
/*$('label.checkbox').on('keypress',function (e) {
var key = e.which;
if(key == 13 || key == 32) // the enter key code
{
var $checkbox = $(e.target);
if (e.target.tagName != "A") {
e && e.preventDefault() && e.stopPropagation();
if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox');
$checkbox.find(':checkbox').checkbox('toggle');
}
}
});*/
}(window.jQuery);
//End jquery checkbox
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*!
* jQuery Smooth Scroll - v1.7.2 - 2016-01-23
* https://github.com/kswedberg/jquery-smooth-scroll
* Copyright (c) 2016 Karl Swedberg
* Licensed MIT
*/
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function($) {
var version = '1.7.2';
var optionOverrides = {};
var defaults = {
exclude: [],
excludeWithin: [],
offset: 0,
// one of 'top' or 'left'
direction: 'top',
// if set, bind click events through delegation
// supported since jQuery 1.4.2
delegateSelector: null,
// jQuery set of elements you wish to scroll (for $.smoothScroll).
// if null (default), $('html, body').firstScrollable() is used.
scrollElement: null,
// only use if you want to override default behavior
scrollTarget: null,
// fn(opts) function to be called before scrolling occurs.
// `this` is the element(s) being scrolled
beforeScroll: function() {},
// fn(opts) function to be called after scrolling occurs.
// `this` is the triggering element
afterScroll: function() {},
easing: 'swing',
speed: 400,
// coefficient for "auto" speed
autoCoefficient: 2,
// $.fn.smoothScroll only: whether to prevent the default click action
preventDefault: true
};
var getScrollable = function(opts) {
var scrollable = [];
var scrolled = false;
var dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop';
this.each(function() {
var el = $(this);
if (this === document || this === window) {
return;
}
if (document.scrollingElement && (this === document.documentElement || this === document.body)) {
scrollable.push(document.scrollingElement);
return false;
}
if (el[dir]() > 0) {
scrollable.push(this);
} else {
// if scroll(Top|Left) === 0, nudge the element 1px and see if it moves
el[dir](1);
scrolled = el[dir]() > 0;
if (scrolled) {
scrollable.push(this);
}
// then put it back, of course
el[dir](0);
}
});
if (!scrollable.length) {
this.each(function() {
// If no scrollable elements and has scroll-behavior:smooth because
// "When this property is specified on the root element, it applies to the viewport instead."
// and "The scroll-behavior property of the … body element is *not* propagated to the viewport."
// → https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior
if (this === document.documentElement && $(this).css('scrollBehavior') === 'smooth') {
scrollable = [this];
}
// If still no scrollable elements, fall back to ,
// if it's in the jQuery collection
// (doing this because Safari sets scrollTop async,
// so can't set it to 1 and immediately get the value.)
if (!scrollable.length && this.nodeName === 'BODY') {
scrollable = [this];
}
});
}
// Use the first scrollable element if we're calling firstScrollable()
if (opts.el === 'first' && scrollable.length > 1) {
scrollable = [scrollable[0]];
}
return scrollable;
};
$.fn.extend({
scrollable: function(dir) {
var scrl = getScrollable.call(this, {dir: dir});
return this.pushStack(scrl);
},
firstScrollable: function(dir) {
var scrl = getScrollable.call(this, {el: 'first', dir: dir});
return this.pushStack(scrl);
},
smoothScroll: function(options, extra) {
options = options || {};
if (options === 'options') {
if (!extra) {
return this.first().data('ssOpts');
}
return this.each(function() {
var $this = $(this);
var opts = $.extend($this.data('ssOpts') || {}, extra);
$(this).data('ssOpts', opts);
});
}
var opts = $.extend({}, $.fn.smoothScroll.defaults, options);
var clickHandler = function(event) {
var escapeSelector = function(str) {
return str.replace(/(:|\.|\/)/g, '\\$1');
};
var link = this;
var $link = $(this);
var thisOpts = $.extend({}, opts, $link.data('ssOpts') || {});
var exclude = opts.exclude;
var excludeWithin = thisOpts.excludeWithin;
var elCounter = 0;
var ewlCounter = 0;
var include = true;
var clickOpts = {};
var locationPath = $.smoothScroll.filterPath(location.pathname);
var linkPath = $.smoothScroll.filterPath(link.pathname);
var hostMatch = location.hostname === link.hostname || !link.hostname;
var pathMatch = thisOpts.scrollTarget || (linkPath === locationPath);
var thisHash = escapeSelector(link.hash);
if (thisHash && !$(thisHash).length) {
include = false;
}
if (!thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash)) {
include = false;
} else {
while (include && elCounter < exclude.length) {
if ($link.is(escapeSelector(exclude[elCounter++]))) {
include = false;
}
}
while (include && ewlCounter < excludeWithin.length) {
if ($link.closest(excludeWithin[ewlCounter++]).length) {
include = false;
}
}
}
if (include) {
if (thisOpts.preventDefault) {
event.preventDefault();
}
$.extend(clickOpts, thisOpts, {
scrollTarget: thisOpts.scrollTarget || thisHash,
link: link
});
$.smoothScroll(clickOpts);
}
};
if (options.delegateSelector !== null) {
this
.undelegate(options.delegateSelector, 'click.smoothscroll')
.delegate(options.delegateSelector, 'click.smoothscroll', clickHandler);
} else {
this
.unbind('click.smoothscroll')
.bind('click.smoothscroll', clickHandler);
}
return this;
}
});
$.smoothScroll = function(options, px) {
if (options === 'options' && typeof px === 'object') {
return $.extend(optionOverrides, px);
}
var opts, $scroller, scrollTargetOffset, speed, delta;
var scrollerOffset = 0;
var offPos = 'offset';
var scrollDir = 'scrollTop';
var aniProps = {};
var aniOpts = {};
if (typeof options === 'number') {
opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides);
scrollTargetOffset = options;
} else {
opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides);
if (opts.scrollElement) {
offPos = 'position';
if (opts.scrollElement.css('position') === 'static') {
opts.scrollElement.css('position', 'relative');
}
}
}
scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir;
if (opts.scrollElement) {
$scroller = opts.scrollElement;
if (!(/^(?:HTML|BODY)$/).test($scroller[0].nodeName)) {
scrollerOffset = $scroller[scrollDir]();
}
} else {
$scroller = $('html, body').firstScrollable(opts.direction);
}
// beforeScroll callback function must fire before calculating offset
opts.beforeScroll.call($scroller, opts);
scrollTargetOffset = (typeof options === 'number') ? options :
px ||
($(opts.scrollTarget)[offPos]() &&
$(opts.scrollTarget)[offPos]()[opts.direction]) ||
0;
aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset;
speed = opts.speed;
// automatically calculate the speed of the scroll based on distance / coefficient
if (speed === 'auto') {
// $scroller[scrollDir]() is position before scroll, aniProps[scrollDir] is position after
// When delta is greater, speed will be greater.
delta = Math.abs(aniProps[scrollDir] - $scroller[scrollDir]());
// Divide the delta by the coefficient
speed = delta / opts.autoCoefficient;
}
aniOpts = {
duration: speed,
easing: opts.easing,
complete: function() {
opts.afterScroll.call(opts.link, opts);
}
};
if (opts.step) {
aniOpts.step = opts.step;
}
if ($scroller.length) {
$scroller.stop().animate(aniProps, aniOpts);
} else {
opts.afterScroll.call(opts.link, opts);
}
};
$.smoothScroll.version = version;
$.smoothScroll.filterPath = function(string) {
string = string || '';
return string
.replace(/^\//, '')
.replace(/(?:index|default).[a-zA-Z]{3,4}$/, '')
.replace(/\/$/, '');
};
// default options
$.fn.smoothScroll.defaults = defaults;
}));
// - - - - - - -s
//Datatable
//DataTables for searchable data cells
//CDN
var includeDataTables = true;
function getDataTableAssets(){
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
loadjscssfile("https://static.heart.org/ahaecc/ecards/datatables/css/dataTables.bootstrap.css", "css");
loadjscssfile("https://static.heart.org/ahaecc/ecards/datatables/css/responsive.bootstrap.css", "css");
loadjscssfile("https://static.heart.org/ahaecc/ecards/datatables/js/jquery.dataTables.js", "js");
loadjscssfile("https://static.heart.org/ahaecc/ecards/datatables/js/dataTables.bootstrap.js", "js");
loadjscssfile("https://static.heart.org/ahaecc/ecards/datatables/js/dataTables.responsive.js", "js");
loadjscssfile("https://static.heart.org/ahaecc/ecards/datatables/js/dataTables.buttons.min.js", "js");
loadjscssfile("https://static.heart.org/ahaecc/ecards/datatables/js/buttons.html5.min.js", "js");
loadjscssfile("https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js", "js");
}
if(includeDataTables){
document.write(' ');
document.write(' ');
document.write('