/****** begin global default HPE page initialization JS for pages with HP.com CaaS header/footer (caas-globals.js) ******/
// Note: This file is used for global initialization code only, on pages that
// use the HP.com content-as-a-service header and footer.
// Set global variables to values appropriate for default HPE installations.
// Only do this if they are not already set:
if (typeof(HPUI_URL) == 'undefined')
var HPUI_URL = "/";
if (typeof(HPUI_LOCALE_COOKIE) == 'undefined')
var HPUI_LOCALE_COOKIE = "";
if (typeof(HPUI_LOCALE) == 'undefined')
var HPUI_LOCALE = "";
// Deprecated (but still supported):
if (typeof(HPUI_CSS_URL) == 'undefined')
var HPUI_CSS_URL = "/hpui/hpe/css";
if (typeof(HPUI_IMG_URL) == 'undefined')
var HPUI_IMG_URL = "/hpui/hpe/images";
if (typeof(HPUI_JS_URL) == 'undefined')
var HPUI_JS_URL = "/hpui/hpe/js";
/****** end global default HPE page initialization JS for pages with HP.com CaaS header/footer (caas-globals.js) ******/
/****** begin HPE buttons JS (buttons.js) ******/
/*** "Public" functions - may be used by feature developers ***/
/*** "Private" functions not for direct use by feature developers ***/
// Initialize all buttons in the given context.
function initButtons(context) {
// Ensure all buttons support event handlers to set disabled/enabled.
var allButtons = jQuery('input[type=button].hpui-critical-button,input[type=button].hpui-critical-slim-button,' +
'input[type=submit].hpui-critical-button,input[type=submit].hpui-critical-slim-button,' +
'input[type=reset].hpui-critical-button,input[type=reset].hpui-critical-slim-button,' +
'input[type=button].hpui-primary-button,input[type=button].hpui-primary-slim-button,' +
'input[type=submit].hpui-primary-button,input[type=submit].hpui-primary-slim-button,' +
'input[type=reset].hpui-primary-button,input[type=reset].hpui-primary-slim-button,' +
'input[type=button].hpui-secondary-button,input[type=button].hpui-secondary-slim-button,' +
'input[type=submit].hpui-secondary-button,input[type=submit].hpui-secondary-slim-button,' +
'input[type=reset].hpui-secondary-button,input[type=reset].hpui-secondary-slim-button', context);
allButtons.off('hpui-disable.hpui-button');
allButtons.on('hpui-disable.hpui-button', function(event) {
var button = jQuery(this);
// Set disabled attr - no need for screenreader text at this time.
button.attr('disabled', '');
// Let event propagate - if surrounded by link, then link handler
// set in initLinks (links.js) will take care of the rest.
});
allButtons.off('hpui-enable.hpui-button');
allButtons.on('hpui-enable.hpui-button', function(event) {
var button = jQuery(this);
// Remove disabled attr - no need for screenreader text at this time.
button.removeAttr('disabled');
// Let event propagate - if surrounded by link, then link handler
// set in initLinks (links.js) will take care of the rest.
});
// Ensure all button links support event handlers to set disabled/enabled.
// Only need to perform button specific actions; general link event handler
// set in initLinks (links.js) will take care of the link itself.
var allButtonLinks = jQuery('a.hpui-critical-button,a.hpui-critical-slim-button,' +
'a.hpui-primary-button,a.hpui-primary-slim-button,' +
'a.hpui-secondary-button,a.hpui-secondary-slim-button', context);
allButtonLinks.off('hpui-disable.hpui-button');
allButtonLinks.on('hpui-disable.hpui-button', function(event) {
var button = jQuery(this).children('input[type=button]');
// Set disabled attr - no need for screenreader text at this time.
if (button && button.length)
button.attr('disabled', '');
});
allButtonLinks.off('hpui-enable.hpui-button');
allButtonLinks.on('hpui-enable.hpui-button', function(event) {
var button = jQuery(this).children('input[type=button]');
//Remove disabled attr - no need for screenreader text at this time.
if (button && button.length)
button.removeAttr('disabled');
});
// Initialize button links.
allButtonLinks.each(function() {
var link = jQuery(this);
var button = link.children('input[type=button]');
if (button && button.length) {
// Ensure that initially button links and enclosed buttons are
// in consistent state.
if (link.attr('disabled'))
button.attr('disabled', '');
else
button.removeAttr('disabled');
// Button links do not need to be in the tab flow (the button
// inputs already are).
link.attr('tabindex', '-1');
}
});
}
/****** end HPE buttons JS (buttons.js) ******/
/****** begin HPE date picker JS (datepicker.js) ******/
/*** "Public" date picker methods ***/
// This hash maps lowercase locales (format ll eg "fr" or ll-cc, eg "zh-tw") to provided
// JQuery UI datepicker JS file tags (format ll eg "fr" or ll-CC, eg "zh-TW").
var HPUI_LOCALES_TO_DATEPICKER_MESSAGES = {
'en-au':'en-AU',
'en-ca':'en-CA',
'en-gb':'en-GB',
'en-ie':'en-IE',
'en-in':'en-IN',
'en-nz':'en-NZ',
'en-za':'en-ZA',
'es-ar':'es-AR',
'es-bo':'es-BO',
'es-cl':'es-CL',
'es-co':'es-CO',
'es-ec':'es-EC',
'es-mx':'es-MX',
'es-pe':'es-PE',
'es-pr':'es-PR',
'es-py':'es-PY',
'es-uy':'es-UY',
'es-ve':'es-VE',
'br-be':'fr-BE',
'fr-ca':'fr-CA',
'pt-br':'pt-BR',
'zh-hk':'zh-HK',
'zh-tw':'zh-TW',
'cs': 'cs',
'de': 'de',
'el': 'el',
'es': 'es',
'fr': 'fr',
'hu': 'hu',
'it': 'it',
'ja': 'ja',
'ko': 'ko',
'pl': 'pl',
'pt': 'pt',
'ru': 'ru',
'tr': 'tr',
'zh': 'zh'
};
/* Add the localization JS file. */
function hpuiAddDatepickerResources() {
// First determine the locale being requested: either the HPUI_LOCALE or the
// value of the HPUI_LOCALE_COOKIE or English by default. From init.js.
var requestedLocale = typeof (determineLocale) == 'function' ? determineLocale() : "en";
// From the locale being requested, determine the locale to actually use.
var localeToUse = "";
var requestedLanguage = requestedLocale;
if (requestedLocale.length > 2)
requestedLanguage = requestedLocale.substring(0, 2);
if (HPUI_LOCALES_TO_DATEPICKER_MESSAGES[requestedLocale.toLowerCase()])
// We will use the full locale if it is supported
localeToUse = HPUI_LOCALES_TO_DATEPICKER_MESSAGES[requestedLocale.toLowerCase()];
else if (HPUI_LOCALES_TO_DATEPICKER_MESSAGES[requestedLanguage.toLowerCase()])
// Else we will use the language if it is supported
localeToUse = HPUI_LOCALES_TO_DATEPICKER_MESSAGES[requestedLanguage.toLowerCase()];
else
// Else we will use English if neither full locale nor language are supported
localeToUse = "en";
// No need to proceed if locale has already been loaded.
if (loadedDatepickerResourcesForLocale == localeToUse)
return;
// Map locale into URL and add that JS into the DOM and return the URL.
// HPUI_JS_URL is a global variable for the root URL to the JS folder.
// From init.js.
var baseUrl = typeof (determineBaseJsUrl) == 'function' ? determineBaseJsUrl() : "";
var url = baseUrl + 'ui/i18n/jquery.ui.datepicker' + '-' + localeToUse + '.js';
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
loadedDatepickerResourcesForLocale = localeToUse;
return url;
}
/* Add screenreader messages to basic datepickers. */
function hpuiAddBasicDatepickerResources(context) {
// Get the message resources.
if (typeof(hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// For each preloader icon set the screenreader message if there is no content exist in it.
jQuery('input[type=text].hpui-datepicker,input[type=text].hpui-slim-datepicker', context).each(function() {
var textInput = jQuery(this);
if (!textInput.attr('id')) {
// Generate random ID if there was none (should never happen because JQuery UI
// generates one automatically)
textInput.attr('id', Math.floor(Math.random()*Math.pow(10,6)));
}
var label = jQuery("label[for='" + textInput.attr('id') + "']");
if (typeof label == "undefined" || label.length == 0) {
// if no label for the dropdown then make an empty one and insert it after the select
label = jQuery(" ");
textInput.parent('span.hpui-datepicker,span.hpui-slim-datepicker').prepend(label);
}
var labelText = jQuery.trim(label.text());
if ((typeof datepicker_screenreader == "string") && datepicker_screenreader) {
// non-empty screenreader text - add it to the label unless already present
if (!labelText || (labelText.indexOf(datepicker_screenreader) == -1)) {
label.append("" + datepicker_screenreader + " ");
}
}
});
}
/* Dynamically set the restricted date criteria. */
function hpuiRestrictDatepicker(id, val) {
var el = id;
var minDate = val ? val.minDate : null;
var maxDate = val ? val.maxDate : null;
var blockDates = val ? val.blockDates : null;
var blockWeekends = val ? val.blockWeekends : null;
// If passed a string, use it as an ID to select a JQuery object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Return short if not provided with a JQuery datepicker.
if (!el || !el.length || !(typeof el == 'object') ||
!(el instanceof jQuery) || !el.is(':data(datepicker)'))
return;
var optionObject = {};
// If the minDate after the maxDate, block all day and display current month.
if ( minDate && typeof minDate == 'string' && maxDate && typeof maxDate == 'string' && minDate > maxDate){
var today = dateToString(new Date());
minDate = maxDate = today;
blockDates = [today];
}
// Set the minimum date, if any. This must be a YYYYMMDD string.
if (minDate && typeof minDate == 'string') {
try {
minDate = jQuery.datepicker.parseDate(el.datepicker('option', 'altFormat'), minDate);
optionObject['minDate'] = minDate;
optionObject['hideIfNoPrevNext'] = true;
} catch (e) {
}
}
// Set the maximum date, if any. This must be a YYYYMMDD string.
if (maxDate && typeof maxDate == 'string') {
try {
maxDate = jQuery.datepicker.parseDate(el.datepicker('option', 'altFormat'), maxDate);
optionObject['maxDate'] = maxDate;
optionObject['hideIfNoPrevNext'] = true;
} catch (e) {
}
}
// Set a function to evaluate whether a given date should be selectable in
// the calendar or not, if restricted dates or weekends have been passed.
// Restricted dates must be YYYYMMDD strings.
if ((blockDates && jQuery.isArray(blockDates)) || blockWeekends) {
el.data('blockDates', blockDates);
el.data('blockWeekends', blockWeekends);
optionObject['beforeShowDay'] = function(date) {
var ok = [true, '', ''];
var no = [false, '', ''];
var datepicker = jQuery(this);
if (isRestrictedDate(datepicker, date)) {
return no;
} else {
return ok;
}
}
}
el.datepicker('option', optionObject);
// Finally, now we have restricted the date range, make sure any
// previously-selected date still falls within that range. Clear it if not.
// Do this while any callback function is temporarily disabled.
el.each(function() {
var datepicker = jQuery(this);
if (isRestrictedDate(datepicker, datepicker.attr('value'))) {
var placeholder = datepicker.datepicker('option', 'onSelect');
datepicker.datepicker('option', 'onSelect', null);
datepicker.trigger('hpui-clear');
if (placeholder && typeof(placeholder) == 'function') {
datepicker.datepicker('option', 'onSelect', placeholder);
}
}
});
}
/* Bind a datepicker to an element with an optional callback function for when a date is selected. */
function hpuiBindDatepicker(id, val) {
var el = id;
// If passed a string, use it as an ID to select a JQuery object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Return short if not provided with a JQuery object.
if (!el || !el.length || !(typeof el == 'object') || !(el instanceof jQuery))
return;
// Generate the base ID and name for the inputs to be created.
var baseID = val && typeof(val.baseID) == 'string' ? val.baseID : null;
if (!baseID && el.attr('id'))
baseID = el.attr('id');
var baseName = val && typeof(val.baseName) == 'string' ? val.baseName : null;
if (!baseName && el.attr('name'))
baseName = el.attr('name');
// Check for existing datepicker and alternate date hidden inputs. If
// forcible create option was specified, remove them.
var altInput = null;
var dateInput = el.prev('input[type=hidden].hpui-datepicker.hasDatepicker');
if (dateInput && dateInput.length) {
if (val && val.create) {
altInput = dateInput.prev('input[type=hidden].hpui-datepicker');
if (altInput && altInput.length)
altInput.remove();
dateInput.remove();
dateInput = altInput = null;
}
}
// To bind a datepicker to the given element, we create two hidden inputs
// before that element. One input is for tracking the display date and the
// datepicker is bound to it. The other is for tracking the internal date
// as an alternate date field.
var firstTime = false;
if (!dateInput || dateInput.length != 1) {
firstTime = true;
// Generate the main input for the displayable date value.
dateInput = jQuery(' ');
if (baseID)
dateInput.attr('id', baseID + '_date');
if (baseName)
dateInput.attr('name', baseName + '_altDate');
dateInput.insertBefore(el);
// Instantiate a datepicker on the second input. JQuery UI gives it the
// 'hasDatepicker' class at that point.
dateInput.datepicker();
}
altInput = dateInput.prev('input[type=hidden].hpui-datepicker');
if (!altInput || altInput.length != 1) {
// Generate the alt input for the internal date value.
altInput = jQuery(' ');
if (baseID)
altInput.attr('id', baseID + '_altDate');
if (baseName)
altInput.attr('name', baseName + '_altDate');
altInput.insertBefore(dateInput);
}
// Determine initial state (first time is always enabled).
var currentState = dateInput.attr('disabled') ? 'disable' : 'enable';
// Determine initial value (first time is the initial date option if any).
var currentValue = val && typeof(val.date) == 'string' ? val.date : '';
if (dateInput.attr('value'))
currentValue = dateInput.attr('value');
if (altInput.attr('value'))
currentValue = altInput.attr('value');
// Set options on the datepicker.
// dateFormat not set here - see the localization files.
var optionObject = {
'altFormat': 'yymmdd',
'altField': altInput,
'changeMonth': true,
'changeYear': true
};
// If given a callback function, set it to onSelect.
if (val && val.callback && typeof(val.callback) == 'function')
optionObject['onSelect'] = val.callback;
// Make the datepicker draggable if requested.
if (val && val.draggable) {
dateInput.addClass('hpui-draggable');
} else {
dateInput.removeClass('hpui-draggable');
}
// Set before-show and on-close callbacks to adjust the datepicker when it
// is opened and closed.
optionObject['beforeShow'] = function(input, datepicker) {
// Make the datepicker draggable if requested.
if (jQuery(this).hasClass('hpui-draggable'))
jQuery('#ui-datepicker-div').draggable();
}
optionObject['onClose'] = function(date) {
if (jQuery(this).hasClass('hpui-draggable'))
jQuery('#ui-datepicker-div').draggable('destroy');
}
// Register keydown event on the datepicker. Note the JQuery UI datepicker
// built-in keydown handler will already execute by the time this does.
// We just want to stop any further propagation up the DOM.
dateInput.off('keydown.hpui-datepicker');
dateInput.on('keydown.hpui-datepicker', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
});
// Register the custom enable event on the datepicker.
dateInput.off('hpui-enable.hpui-datepicker');
dateInput.on('hpui-enable.hpui-datepicker',
function() {
return function() {
var dateInput = jQuery(this);
var altInput = dateInput.prev('input[type=hidden].hpui-datepicker');
var el = dateInput.next();
dateInput.datepicker('enable');
dateInput.removeAttr('disabled');
if (altInput && altInput.length)
altInput.removeAttr('disabled');
if (el && el.length)
el.removeAttr('disabled');
}
}());
// Register the custom disable event on the datepicker.
dateInput.off('hpui-disable.hpui-datepicker');
dateInput.on('hpui-disable.hpui-datepicker',
function() {
return function() {
var dateInput = jQuery(this);
var altInput = dateInput.prev('input[type=hidden].hpui-datepicker');
var el = dateInput.next();
dateInput.datepicker('disable');
dateInput.attr('disabled', '');
if (altInput && altInput.length)
altInput.attr('disabled', '');
if (el && el.length)
el.attr('disabled', '');
}
}());
// Register the custom set value event on the datepicker.
dateInput.off('hpui-value.hpui-datepicker');
dateInput.on('hpui-value.hpui-datepicker',
function(event, val) {
var dateInput = jQuery(this);
if (val) {
// Set the datepicker to the given value. First try our
// canonical YYYYMMDD format. Then try the localized
// displayable format. Finally validate the date. If all
// of this fails, clear the datepicker using another trigger.
var date = stringToDate(dateInput, val);
if (date && !isRestrictedDate(dateInput, date))
dateInput.datepicker('setDate', date);
else
dateInput.trigger('hpui-clear');
} else {
// Clear the datepicker if not given a value.
dateInput.datepicker('setDate', null);
}
// If there is an on-select callback, invoke it - set the
// flag to tell the callback it was invoked from here, in case it
// cares.
var callback = dateInput.datepicker('option', 'onSelect');
if (typeof(callback) == 'function')
callback(dateInput.attr('value'), dateInput[0], true);
});
// Register the custom clear event on the datepicker.
dateInput.off('hpui-clear.hpui-datepicker');
dateInput.on('hpui-clear.hpui-datepicker',
function() {
return function() {
var dateInput = jQuery(this);
// Clear is same as setting a blank value.
dateInput.trigger('hpui-value', '');
}
}());
// Finally register the custom hpui-reset event on the datepicker. Only
// do this first time, since its parameters depend on the initial values.
if (firstTime) {
dateInput.off('hpui-reset.hpui-datepicker');
dateInput.on('hpui-reset.hpui-datepicker',
function(initValue, initState) {
return function() {
var dateInput = jQuery(this);
dateInput.trigger('hpui-value', initValue);
dateInput.trigger('hpui-' + initState);
}
}(currentValue, currentState));
}
// Set the current value and state into the datepicker, with callbacks
// temporarily disabled.
var placeholder = optionObject.onSelect;
optionObject['onSelect'] = null;
dateInput.trigger('hpui-value', currentValue);
dateInput.trigger('hpui-' + currentState);
if (placeholder && typeof(placeholder) == 'function') {
optionObject['onSelect'] = placeholder;
}
dateInput.datepicker('option',optionObject);
return dateInput;
}
/* Set the position for datepicker and open it. */
function hpuiShowDatepicker(id, position){
// Try to set focus on an element.
function tryFocus(focal) {
var hasTabIndex = focal.attr('tabindex');
if (!hasTabIndex)
focal.attr('tabindex', '0'); // tabindex makes it focusable
focal.focus();
if (!hasTabIndex)
focal.removeAttr('tabindex');
}
var el = id;
// If passed a string, use it as an ID to select a JQuery object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Return short if not provided with a JQuery datepicker.
if (!el || el.length != 1 || !(typeof el == 'object') ||
!(el instanceof jQuery) || !el.is(':data(datepicker)'))
return;
// Find the originally bound element (its just the next one).
var orig = el.next();
if (!orig || !orig.length)
return;
// By default, position the calendar at right bottom of the closest aligned
// element (ie closest element marked with class="hpui-datepicker-align")
// with flip enabled. If so such element, then launch from the next element
// after the enclosing span, presumed to be the original binded DOM element.
// This is just by default; passed-in properties can override.
if (!position || (typeof(position) != 'object'))
position = {};
if (!position.my || (typeof(position.my) != 'string'))
position.my = 'right top';
if (!position.at || (typeof(position.at) != 'string'))
position.at = 'right bottom';
if (!position.collision || (typeof(position.collision) != 'string'))
position.collision = 'flip';
var launch = el.closest('.hpui-datepicker-align');
if (!launch || !launch.length)
launch = orig;
if (!position.of)
position.of = launch;
else
launch = position.of;
// Make sure focus is established and keydown event handlers are set, so
// keystrokes are diverted into the datepicker. First try to set focus
// on original bound element; otherwise try to set it on the launch point.
var focal = orig;
if (!focal.is(':focus'))
tryFocus(focal);
if (!focal.is(':focus')) {
focal = launch;
focal.css('outline', 'none'); // no outline when focus on launch point
tryFocus(focal);
}
// Register keydown event on the focal element, to clear datepicker
// when backspace/delete keys are trapped, hide datepicker when tab key
// is detected, and divert all other keys to the datepicker itself.
focal.off('keydown.hpui-datepicker');
focal.on('keydown.hpui-datepicker',
function(event) {
if (event.keyCode == 8 || event.keyCode == 46) {
// 'Backspace', 'Delete' keys erase the date (ignore on
// disabled datepickers).
if (!el.attr('disabled')) {
el.trigger('hpui-clear');
el.datepicker('hide');
}
event.preventDefault();
event.stopImmediatePropagation();
} else if (event.keyCode == 9) {
// 'Tab' closes the datepicker.
if (!el.attr('disabled'))
el.datepicker('hide');
} else {
// Other keys get diverted to the datepicker.
event.target = el[0];
event.relatedTarget = focal[0];
el.trigger(event);
}
});
// Remove that keydown event handler when the datepicker is closed.
el.datepicker('option', 'onClose', function() {
focal.off('keydown.hpui-datepicker');
});
// Finally show the datepicker in the proper position.
// There is a corner-case timing bug: if the user clicks again (or double
// clicks) on the bound DOM element for this datepicker, then the datepicker
// will close (on mousedown) and then open again (on mouseup). When the
// close and open are very rapid, the close is still executing while the
// open is trying to execute, and consequently the position is mis-
// calculated, so the datepicker appears to flicker and jump to another
// place in the UI. Setting even a very short timeout will take care of
// that: 50 milliseconds.
var doShow = function() {
try {
el.datepicker('show');
jQuery('#ui-datepicker-div').position(position);
} catch (e) {
}
}
// UPADTE: The timeout workaround would cause the datepicker to not appear
// at all when launched from an action menu.
doShow();
setTimeout(doShow, 50);
}
/* Convert a YYYYMMDD or display-date string into a JS Date object, returning
* null if the conversion cannot proceed. */
function hpuiStringToDate(datepicker, val) {
return stringToDate(datepicker, val);
}
/* Convert a JS Date object to a YYYYMMDD string, returning null if the
* conversion cannot proceed. */
function hpuiDateToString(date) {
return dateToString(date);
}
/*** "Private" date picker methods ***/
// Global variable for tracking datepicker resources already loaded on this page.
var loadedDatepickerResourcesForLocale = "";
/* Convert a YYYYMMDD or display-date string into a JS Date object, returning
* null if the conversion cannot proceed. */
function stringToDate(datepicker, val) {
var date = null;
try {
date = jQuery.datepicker.parseDate(datepicker.datepicker('option', 'altFormat'), val);
} catch (e) {
try {
date = jQuery.datepicker.parseDate(datepicker.datepicker('option', 'dateFormat'), val);
} catch (e) {
}
}
return date;
}
/* Convert a JS Date object to a YYYYMMDD string, returning null if the
* conversion cannot proceed. */
function dateToString(date) {
if (!date || typeof(date) != 'object' || !(date instanceof Date))
return null;
var mm = (date.getMonth() + 1) > 9 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1);
var dd = date.getDate() > 9 ? date.getDate() : '0' + date.getDate();
var yyyy = date.getFullYear();
var yyyymmdd = yyyy.toString() + mm.toString() + dd.toString();
return yyyymmdd;
}
/* Return true/false indicating whether the given Date object is in the
* datepicker's restricted range. Instead of a Date object, a string can be
* given. */
function isRestrictedDate(datepicker, date) {
// Normalize parameters.
if (date && typeof(date) == 'string')
date = stringToDate(datepicker, date);
if (!date || typeof(date) != 'object' || !(date instanceof Date))
return false;
if (!datepicker || !datepicker.length || (typeof(datepicker) != 'object') ||
!(datepicker instanceof jQuery) || !(datepicker.is(':data(datepicker)')))
return false;
// Check if it is on or after the minimum date.
var minDate = datepicker.datepicker('option', 'minDate');
if (minDate && (date < minDate))
return true;
// Check if it is on or before the maximum date.
var maxDate = datepicker.datepicker('option', 'maxDate');
if (maxDate && (date > maxDate))
return true;
// Check if it is a weekend.
var blockWeekends = datepicker.data('blockWeekends');
if (blockWeekends) {
var weekend = !(jQuery.datepicker.noWeekends(date)[0]);
if (weekend)
return true;
}
// Finally check if it is a specific blocked date.
var blockDates = datepicker.data('blockDates');
if (blockDates && jQuery.isArray(blockDates)) {
var mmddyyyy = dateToString(date);
if (jQuery.inArray(mmddyyyy, blockDates) > -1)
return true;
}
// If survived all these checks, then the date is not restricted.
return false;
}
// Initialize date picker
function initDatepicker(baseDatepickerClass, baseTextClass, context) {
var spanSelector = 'span.' + baseDatepickerClass;
var hiddenInputSelector = 'input[type=hidden].' + baseDatepickerClass;
var textInputSelector = 'input[type=text].' + baseDatepickerClass;
var iconSelector = 'img.ui-datepicker-trigger';
// Find and process datepicker text inputs (phase 2).
var textInputs = jQuery(textInputSelector, context);
if (textInputs && textInputs.length) {
for (var i = 0; i < textInputs.length; i++) {
var textInput = jQuery(textInputs[i]);
var error = textInput.hasClass('hpui-error');
var disabled = textInput.attr('disabled');
var readonly = textInput.attr('readonly');
var currentValue = textInput.attr('value');
var currentState = readonly ? 'readonly' : 'enable';
currentState = disabled ? 'disable' : currentState;
// Check if a hidden input was provided by the feature developer.
// Its value, if any, becomes the initial value (trumping the one in
// the text input).
var hiddenInput = textInput.prev(hiddenInputSelector);
if (hiddenInput && hiddenInput.length)
if (hiddenInput.attr('value'))
currentValue = hiddenInput.attr('value');
// Generate a span container for the hidden and text inputs, and add
// it to the DOM, if not already there. (The span container ensures
// nowrap on the contained elements: the text input and the image
// tag that JQuery UI datepicker will insert next to it.)
var span = textInput.parent(spanSelector);
if (!span || !span.length) {
span = jQuery(' ');
textInput.wrap(span);
if (hiddenInput && hiddenInput.length) {
hiddenInput.detach();
hiddenInput.insertBefore(textInput);
}
span = textInput.parent(spanSelector);
}
// Finally force this text input to the proper text input class.
if (!textInput.hasClass(baseTextClass)) {
textInput.removeClass('hpui-input hpui-slim-input').addClass(baseTextClass);
// Reinitialize now we have added the text class - afterward
// this datepicker is fully initialized (even the below logic
// will have run), so just continue to the next.
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(span);
continue;
} else
textInput.removeClass('hpui-input hpui-slim-input').addClass(baseTextClass);
// Now instantiate a new datepicker on this datepicker text input.
textInput.datepicker();
// dateFormat not set here - see the localization files.
var optionObject = {
'altFormat' : 'yymmdd',
'showOn' : 'both',
'buttonImageOnly' : true,
'buttonText': '',
'changeMonth': true,
'changeYear': true
}
if (hiddenInput && hiddenInput.length)
optionObject['altField'] = hiddenInput;
// On show, the datepicker needs to be made draggable if
// hpui-draggable class was requested.
optionObject['beforeShow'] = function(input, datepicker) {
var textInput = jQuery(this);
if (textInput.hasClass('hpui-draggable'))
jQuery('#ui-datepicker-div').draggable();
}
// On select, the datepicker will now automatically update the text
// input value with the displayable localized date, and the hidden
// input value with the YYYYMMDD date. All we need to explicitly
// do is set the entered classname.
optionObject['onSelect'] = function(date) {
var textInput = jQuery(this);
if (!textInput.hasClass('hpui-error'))
textInput.addClass('hpui-entered');
}
// On close, we need to check and clear the entered classname if the
// datepicker is blank; also blur the focus.
optionObject['onClose'] = function(date) {
var textInput = jQuery(this);
if (!date)
textInput.removeClass('hpui-entered');
// Remove draggability if it was set on the calendar overlay.
if (textInput.hasClass('hpui-draggable'))
jQuery('#ui-datepicker-div').draggable('destroy');
}
// Register the custom enable event on the datepicker text input.
// Remember the text input assigns an event handler of its own; both will run.
// This one only needs to do the extra steps the basic text input one does not.
textInput.off('hpui-enable.hpui-datepicker');
textInput.on('hpui-enable.hpui-datepicker',
function() {
return function() {
var textInput = jQuery(this);
var hiddenInput = textInput.prev(hiddenInputSelector);
var imageUrl = typeof (determineBaseImagesUrl) == 'function' ? determineBaseImagesUrl() : ""; // from init.js
textInput.datepicker('enable');
// HPUI_IMG_URL is a global variable for the root URL to the images folder.
textInput.datepicker('option','buttonImage',imageUrl + 'calendar.png');
if (hiddenInput && hiddenInput.length)
hiddenInput.removeAttr('disabled').removeAttr('readonly');
var icon = textInput.next(iconSelector);
if (icon && icon.length)
icon.removeAttr('disabled');
}
}());
// Register the custom disable event on the datepicker text input.
// Remember the text input assigns an event handler of its own; both will run.
// This one only needs to do the extra steps the basic text input one does not.
textInput.off('hpui-disable.hpui-datepicker');
textInput.on('hpui-disable.hpui-datepicker',
function() {
return function() {
var textInput = jQuery(this);
var hiddenInput = textInput.prev(hiddenInputSelector);
var imageUrl = typeof (determineBaseImagesUrl) == 'function' ? determineBaseImagesUrl() : ""; // from init.js
textInput.datepicker('disable');
// HPUI_IMG_URL is a global variable for the root URL to the images folder.
textInput.datepicker('option','buttonImage', imageUrl + 'calendar_disabled.png');
if (hiddenInput && hiddenInput.length)
hiddenInput.attr('disabled', '').removeAttr('readonly');
var icon = textInput.next(iconSelector);
if (icon && icon.length)
icon.attr('disabled', '');
}
}());
// Register the custom readonly event on the datepicker text input.
// Remember the text input assigns an event handler of its own; both will run.
// This one only needs to do the extra steps the basic text input one does not.
textInput.off('hpui-readonly.hpui-datepicker');
textInput.on('hpui-readonly.hpui-datepicker',
function() {
return function() {
var textInput = jQuery(this);
var hiddenInput = textInput.prev(hiddenInputSelector);
var imageUrl = typeof (determineBaseImagesUrl) == 'function' ? determineBaseImagesUrl() : ""; // from init.js
// A readonly datepicker is same as disabled so far as the calendar widget goes.
textInput.datepicker('disable');
textInput.removeAttr('disabled');
// HPUI_IMG_URL is a global variable for the root URL to the images folder.
textInput.datepicker('option','buttonImage', imageUrl + 'calendar_disabled.png');
if (hiddenInput && hiddenInput.length)
hiddenInput.attr('readonly', '').removeAttr('disabled');
var icon = textInput.next(iconSelector);
if (icon && icon.length)
icon.attr('disabled', '');
}
}());
textInput.off('click.hpui-datepicker');
textInput.on('click.hpui-datepicker',
function (){
return function() {
jQuery(this).datepicker( "show" );
}
}());
// Forbid the keyboard events for date picker except 'Backspace',
// 'Delete', 'Shift', 'Tab', 'Enter'.
textInput.off('keydown.hpui-datepicker');
textInput.on('keydown.hpui-datepicker',
function(event) {
var textInput = jQuery(this);
if (event.keyCode == 8 || event.keyCode == 46) {
// 'Backspace', 'Delete' keys erase the date (ignore on
// disabled and readonly datepickers).
if (!textInput.attr('readonly') && !textInput.attr('disabled')) {
textInput.trigger('hpui-clear');
textInput.datepicker('hide');
}
event.preventDefault();
event.stopImmediatePropagation();
} else if (event.keyCode == 9) {
// 'Tab' behaves as usual.
} else if (event.keyCode == 13) {
event.preventDefault();
textInput.datepicker( "show" );
} else {
event.preventDefault();
}
});
// Forbid all paste content into input text.
textInput.off('paste');
textInput.on('paste.hpui-datepicker', function(event) {
event.preventDefault();
});
// Forbid all cut content into input text.
textInput.off('cut');
textInput.on('cut.hpui-datepicker', function(event) {
event.preventDefault();
});
// Bind value event to this datepicker text input.
// Remember the text input assigns an event handler of its own; both will run.
// This one only needs to do the extra steps the basic text input one does not.
textInput.off('hpui-value.hpui-datepicker');
textInput.on('hpui-value.hpui-datepicker',
function(event, val) {
var textInput = jQuery(this);
if (val) {
// Set the datepicker to the given value. First try our
// canonical YYYYMMDD format. Then try the localized
// displayable format. Finally validate the date. If all
// of this fails, clear the datepicker using another trigger.
var date = stringToDate(textInput, val);
if (date && !isRestrictedDate(textInput, date))
textInput.datepicker('setDate', date);
else
textInput.trigger('hpui-clear');
} else {
// Clear the datepicker if not given a value.
textInput.datepicker('setDate', null);
}
});
// Register the custom clear event on the datepicker.
textInput.off('hpui-clear.hpui-datepicker');
textInput.on('hpui-clear.hpui-datepicker',
function() {
return function() {
var textInput = jQuery(this);
// Clear is same as setting a blank value.
textInput.trigger('hpui-value', '');
}
}());
// Register the custom reset event on the input element.
// Remember the text input assigns an event handler of its own; both will run.
// This one only needs to do the extra steps the basic text input one does not.
textInput.off('hpui-reset.hpui-datepicker');
textInput.on('hpui-reset.hpui-datepicker',
function(initValue, initState) {
return function() {
var textInput = jQuery(this);
// Reset the text input value to the initial value which may
// have come from the hidden input. (The text input handler
// for this event only takes the value from the text input
// itself.)
textInput.trigger('hpui-value', initValue);
}
}(currentValue, currentState));
// For fix accessibility issue.
textInput.off('click.hpui-datepicker');
textInput.on('click.hpui-datepicker',
function (){
return function() {
jQuery(this).datepicker( "show" );
}
}());
// Finish initializing this datepicker by setting its value and
// state (disabled, readonly, enabled) according to the value and
// state of the text input. The reset event handles this.
textInput.trigger('hpui-reset');
textInput.datepicker('option',optionObject);
}
}
}
/****** end HPE date picker JS (datepicker.js) ******/
/****** begin HPE dropdowns JS (dropdowns.js) ******/
/*** "Public" functions - may be used by feature developers ***/
// Add screenreader messages for the given locale into the dropdowns
// within the given context (may be a JQuery Object, a string HTML ID, or the whole
// page by default).
function hpuiAddDropdownResources(context) {
// Get the message resources.
if (typeof(hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
jQuery("select.hpui-select, select.hpui-action-menu, select.hpui-slim-select, select.hpui-critical-link-menu, " +
"select.hpui-primary-link-menu, select.hpui-secondary-link-menu, select.hpui-filter-menu, " +
"select.hpui-sort-menu, select.hpui-multi-select, select.hpui-slim-multi-select", context).each(function() {
var dropdown = jQuery(this);
if (!dropdown.attr('id'))
// if no ID for the dropdown then skip it (should never happen
// as MSDropdown auto-generates ID when it doesn't exist)
return;
var label = jQuery("label[for='" + dropdown.attr('id') + "']");
if (typeof label == "undefined" || label.length == 0) {
// if no label for the dropdown then make an empty one and insert it after the select
label = jQuery(" ");
dropdown.after(label);
}
var labelText = jQuery.trim(label.text());
if (!labelText) {
// if new or existing label is empty, add screenreader text to it
if (dropdown.hasClass('hpui-select') || dropdown.hasClass('hpui-slim-select') ||
dropdown.hasClass('hpui-multi-select') || dropdown.hasClass('hpui-slim-multi-select')) {
if ((typeof dropdown_single_multi_select_screenreader == "string") && dropdown_single_multi_select_screenreader) {
//non-empty screenreader text
label.append("" + dropdown_single_multi_select_screenreader + " ");
}
} else if (dropdown.hasClass('hpui-action-menu')) {
if ((typeof dropdown_actionmenu_screenreader == "string") && dropdown_actionmenu_screenreader) {
//non-empty screenreader text
label.append("" + dropdown_actionmenu_screenreader + " ");
}
} else if (dropdown.hasClass('hpui-critical-link-menu') || dropdown.hasClass('hpui-primary-link-menu') || dropdown.hasClass('hpui-secondary-link-menu')) {
if ((typeof dropdown_linkmenu_screenreader == "string") && dropdown_linkmenu_screenreader) {
//non-empty screenreader text
label.append("" + dropdown_linkmenu_screenreader + " ");
}
} else if (dropdown.hasClass('hpui-filter-menu')) {
if ((typeof dropdown_filterselect_screenreader == "string") && dropdown_filterselect_screenreader) {
//non-empty screenreader text
label.append("" + dropdown_filterselect_screenreader + " ");
}
} else if (dropdown.hasClass('hpui-sort-menu')) {
if ((typeof dropdown_sortselect_screenreader == "string") && dropdown_sortselect_screenreader) {
//non-empty screenreader text
label.append("" + dropdown_sortselect_screenreader + " ");
}
}
}
});
}
/*** "Private" functions not for direct use by feature developers ***/
// Initialize all stateful dropdowns in the given context.
function initDropdowns(context) {
// Utility function to generate the readonly input structure as needed.
function generateReadonlyInputs(dropdown) {
var id = dropdown.attr('id');
var name = dropdown.attr('name');
// get the options that will need hidden inputs
var optionsNeeded = [];
var options = dropdown.get(0).options;
if (dropdown.attr('readonly'))
// get all non-disabled, selected options when the dropdown as a
// whole is readonly - these are the ones for the hidden inputs
for (var i = 0; i < options.length; i++) {
var option = options[i];
if (option.selected &&
(jQuery(option).attr('readonly') ||
!jQuery(option).attr('disabled')))
optionsNeeded.push(option);
}
else if (!dropdown.attr('disabled'))
// when the dropdown is enabled, just get the selected options
// that are readonly
for (var j = 0; j < options.length; j++) {
var option = options[j];
if (option.selected && jQuery(option).attr('readonly'))
optionsNeeded.push(option);
}
// remove any existing hidden input structure
jQuery('#' + id + "_msddnone").remove();
// generate the replacement structure, if any needed
if (optionsNeeded.length > 0) {
var div = jQuery('
');
div.attr('id', id + "_msddnone");
dropdown.parent().after(div);
for (var k = 0; k < optionsNeeded.length; k++) {
var option = jQuery(optionsNeeded[k]);
var input = jQuery(' ');
input.attr('name', name);
input.attr('value', option.val());
div.append(input);
}
}
}
// If there are any hpui-select or hpui-slim-select with "multiple" set,
// convert them to hpui-multi-select or hpui-slim-multi-select.
var wannaBeMultiple = jQuery('select[multiple].hpui-select,' +
'select[multiple].hpui-slim-select', context);
wannaBeMultiple.each(function() {
var dropdown = jQuery(this);
if (dropdown.hasClass('hpui-select'))
dropdown.removeClass('hpui-select').addClass('hpui-multi-select');
if (dropdown.hasClass('hpui-slim-select'))
dropdown.removeClass('hpui-slim-select').addClass('hpui-slim-multi-select');
});
// If there are any hpui-multi-select set, make sure "multiple" is set.
wannaBeMultiple = jQuery('select.hpui-multi-select,' +
'select.hpui-slim-multi-select', context);
wannaBeMultiple.attr('multiple', '');
// Various initialization properties for the different types of stateful dropdown,
// including multi-selects (that is why we normalized above, first).
var dropdownTypeArray = [{className: "hpui-select", isTitleSupported: true, isMultiple: false},
{className: "hpui-slim-select", isTitleSupported: true, isMultiple: false},
{className: "hpui-multi-select", isTitleSupported: false, isMultiple: true},
{className: "hpui-slim-multi-select", isTitleSupported: false, isMultiple: true},
{className: "hpui-filter-menu", isTitleSupported: true, isMultiple: false},
{className: "hpui-sort-menu", isTitleSupported: true, isMultiple: false}
];
// Initialize each of the types of stateful dropdown.
for (var _index = 0; _index < dropdownTypeArray.length; _index++) {
var dropdownType = dropdownTypeArray[_index];
var hpui_dropdowns_self = jQuery('select.' + dropdownTypeArray[_index].className, context);
if (hpui_dropdowns_self && hpui_dropdowns_self.length) {
for (i = 0; i < hpui_dropdowns_self.length; i++) {
var hpui_dropdown_self_obj = jQuery(hpui_dropdowns_self[i]);
var currentSelectedIndex = [];
var currentErrorIndex = [];
var currentDisabledIndex = [];
var currentReadonlyIndex = [];
var isMultiple = dropdownType.isMultiple;
var currentError = hpui_dropdown_self_obj.hasClass('hpui-error');
var disabled = hpui_dropdown_self_obj.attr('disabled');
var readonly = hpui_dropdown_self_obj.attr('readonly');
var currentState = readonly ? 'readonly' : 'enable';
currentState = disabled ? 'disable' : currentState;
// Remember which options are initially selected, error,
// disabled, and/or readonly. Error options are only supported
// for multi-select. Single selects can have only one (the
// last) selected option. Disabled and readonly are mutually
// exclusive (disabled trumps readonly).
var options = hpui_dropdown_self_obj.get(0).options;
for (var j = 0; j < options.length; j++) {
var option = jQuery(options[j]);
if (option.get(0).selected) {
if (isMultiple)
currentSelectedIndex.push(j);
else
currentSelectedIndex[0] = j;
}
if (option.hasClass('hpui-error')) {
if (isMultiple)
currentErrorIndex.push(j);
else
option.removeClass('hpui-error');
}
if (option.attr('disabled')) {
currentDisabledIndex.push(j);
} else if (option.attr('readonly')) {
currentReadonlyIndex.push(j);
}
// Title allowed: Strip hpui-heading from any option but the first.
// Title not allowed: strip hpui-heading throughout.
if (!dropdownType.isTitleSupported || j > 0)
option.removeClass('hpui-heading');
}
var visibleRows = getVisibleRows(hpui_dropdown_self_obj);
var isQualifiedFlag = checkVisibleRowIsQualified(visibleRows);
// Register custom reset event handler on the stateful dropdown.
hpui_dropdown_self_obj.off('hpui-reset.hpui-select');
hpui_dropdown_self_obj.on('hpui-reset.hpui-select',
{initSelectedIndex: currentSelectedIndex,
initError: currentError,
initState: currentState,
initErrorIndex: currentErrorIndex,
initDisabledIndex: currentDisabledIndex,
initReadonlyIndex: currentReadonlyIndex,
initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element
var dropdown = jQuery(this);
var selectedIndex = event.data.initSelectedIndex;
var errorIndex = event.data.initErrorIndex;
var disabledIndex = event.data.initDisabledIndex;
var readonlyIndex = event.data.initReadonlyIndex;
var error = event.data.initError;
var state = event.data.initState;
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// First tear-down the current MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
// Wipe clean the select
dropdown.removeClass('hpui-error');
dropdown.removeAttr('disabled').removeAttr('readonly');
// Wipe clean the individual options
for (var i = 0; i < dropdown.get(0).options.length; i++) {
var option = jQuery(dropdown.get(0).options[i]);
option.get(0).selected = false;
option.removeAttr('disabled').removeAttr('readonly');
option.removeClass('hpui-error');
}
// Select the initially selected options.
for (var j = 0; j < selectedIndex.length; j++) {
var option = jQuery(dropdown.get(0).options[selectedIndex[j]]);
option.get(0).selected = true;
}
// Set the initial option errors.
for (var k = 0; k < errorIndex.length; k++) {
var option = jQuery(dropdown.get(0).options[errorIndex[k]]);
option.addClass('hpui-error');
}
// Set the initially disabled options.
for (var l = 0; l < disabledIndex.length; l++) {
var option = jQuery(dropdown.get(0).options[disabledIndex[l]]);
option.attr('disabled', '');
}
// Set the initially readonly options.
for (var m = 0; m < readonlyIndex.length; m++) {
var option = jQuery(dropdown.get(0).options[readonlyIndex[m]]);
// Note readonly state for option is a combo of both
// disabled and readonly attributes.
option.attr('disabled', '');
option.attr('readonly', '');
}
// Set the error class on dropdown
if (error)
dropdown.addClass('hpui-error');
// Set the dropdown disabled/enabled/readonly state -
// note readonly state for select is a combo of both
// disabled and readonly attributes.
if (state == 'disable') {
dropdown.attr('disabled','');
if (typeof(disableLabel) == 'function') disableLabel(dropdown);
} else if (state == 'readonly') {
dropdown.attr('disabled','');
dropdown.attr('readonly','');
if (typeof(enableLabel) == 'function') enableLabel(dropdown);
} else {
if (typeof(enableLabel) == 'function') enableLabel(dropdown);
}
// Finally rebuild the MS dropdown structure, including
// any needed readonly input structure.
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
generateReadonlyInputs(dropdown);
});
// Register custom disable event handler on the stateful dropdown.
hpui_dropdown_self_obj.off('hpui-disable.hpui-select');
hpui_dropdown_self_obj.on('hpui-disable.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// disable option or whole select as appropriate:
if (option && option.length) {
option.attr('disabled', '');
option.removeAttr('readonly');
} else {
// set disabled and clear readonly
dropdown.attr('disabled', '');
dropdown.removeAttr('readonly');
// set the label (if any) to indicate disabled
if (typeof(disableLabel) == 'function') disableLabel(dropdown);
}
// teardown and rebuild the MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
// if this dropdown is in the readonly state, we must
// rebuild its hidden inputs now, since the set of
// readonly selected options may have changed
generateReadonlyInputs(dropdown);
});
// Register custom readonly event handler on the stateful dropdown.
hpui_dropdown_self_obj.off('hpui-readonly.hpui-select');
hpui_dropdown_self_obj.on('hpui-readonly.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// set readonly on option or whole select as needed -
// note that readonly is a combo of disabled and
// readonly attributes
if (option && option.length) {
option.attr('disabled', '');
option.attr('readonly', '');
} else {
dropdown.attr('disabled', '');
dropdown.attr('readonly', '');
// set the label (if any) to indicate non-disabled
if (typeof(enableLabel) == 'function') enableLabel(dropdown);
}
// teardown and rebuild the MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
// if this dropdown is in the readonly state, we must
// rebuild its hidden inputs now, since the set of
// readonly selected options may have changed
generateReadonlyInputs(dropdown);
});
// Register custom enable event handler on the stateful dropdown.
hpui_dropdown_self_obj.off('hpui-enable.hpui-select');
hpui_dropdown_self_obj.on('hpui-enable.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// enable option or whole select as appropriate:
if (option && option.length) {
option.removeAttr('disabled');
option.removeAttr('readonly');
} else {
// clear disabled and readonly state attributes
dropdown.removeAttr('disabled');
dropdown.removeAttr('readonly');
// set the label (if any) to indicate not disabled
if (typeof(enableLabel) == 'function') enableLabel(dropdown);
}
// teardown and rebuild the MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
// if this dropdown is in the readonly state, we must
// rebuild its hidden inputs now, since the set of
// readonly selected options may have changed
generateReadonlyInputs(dropdown);
});
// Register custom toggle event handler on stateful dropdowns.
hpui_dropdown_self_obj.off('hpui-toggle.hpui-select');
hpui_dropdown_self_obj.on('hpui-toggle.hpui-select', {},
function(event, val) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// if not triggered on an option, just return (no
// toggle effect at select level).
if (!option || !option.length)
return;
// toggle as needed, based on the given switch:
if (val == undefined) {
if (option.get(0).selected)
// when option is selected, clear value on
// that option
option.trigger('hpui-clear');
else
// when option is not selected, set value on
// that option
option.trigger('hpui-value');
} else if (val == true) {
// toggle on: set value on that option
option.trigger('hpui-value');
} else if (val == false) {
// toggle off: clear value on that option
option.trigger('hpui-clear');
}
// No need to do anymore, the above triggers take
// care of everything.
});
// Register custom value-setter event handler on stateful
// dropdowns. Different implementation for multi- and single-
// selects.
if (isMultiple) { // multi select
hpui_dropdown_self_obj.off('hpui-value.hpui-select');
hpui_dropdown_self_obj.on('hpui-value.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event, val) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// set the selection as needed:
if (option && option.length) {
// if triggered on an option, select that option
option.get(0).selected = true;
} else {
// if triggered on the select, select the option
// with the given value (if no such option, this
// does nothing; or if undefined value, this clears
// the select).
dropdown.val(val);
}
// do not reset error state!
// tear-down and rebuild the MS dropdown structure.
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
// if this dropdown is in the readonly state, we must
// rebuild its hidden inputs now, since the set of
// readonly selected options may have changed
generateReadonlyInputs(dropdown);
});
} else { // single select
hpui_dropdown_self_obj.off('hpui-value.hpui-select');
hpui_dropdown_self_obj.on('hpui-value.hpui-select', {},
function(event, val) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// set the selected option as needed:
if (option && option.length) {
// if triggered on an option, ignore value and just
// always select that option
option.get(0).selected = true;
} else {
// if triggered at select level, select the option
// with the given value (if no such option, this
// does nothing; or if undefined value, this clears
// the select).
dropdown.val(val);
}
// reset any error state (this also tears-down and
// rebuilds the MS dropdown structure so we don't
// need to do it here for the above)
dropdown.trigger('hpui-ok');
// if this dropdown is in the readonly state, we must
// rebuild its hidden inputs now, since the set of
// readonly selected options may have changed
generateReadonlyInputs(dropdown);
});
}
// Register custom event handler for clearing selected options
// in the stateful dropdown. Different implementations for
// multi and single select.
if (isMultiple) { // multi select
hpui_dropdown_self_obj.off('hpui-clear.hpui-select');
hpui_dropdown_self_obj.on('hpui-clear.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// clear the selection as needed:
if (option && option.length) {
// if triggered on an option, deselect that option
option.get(0).selected = false;
// and set OK on that option
option.trigger('hpui-ok');
// tear-down and rebuild the MS dropdown structure.
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
} else {
// if triggered on the select, deselect all options
var nextSelectedIndex = dropdown.get(0).selectedIndex;
while (nextSelectedIndex > -1) {
dropdown.children("option")[nextSelectedIndex].selected = false;
nextSelectedIndex = dropdown.get(0).selectedIndex;
}
// and set OK now on the select - this rebuilds
// the MS dropdown structure too
dropdown.trigger('hpui-ok');
}
// if this dropdown is in the readonly state, we must
// rebuild its hidden inputs now, since the set of
// readonly selected options may have changed
generateReadonlyInputs(dropdown);
});
} else {
hpui_dropdown_self_obj.off('hpui-clear.hpui-select');
hpui_dropdown_self_obj.on('hpui-clear.hpui-select', {},
function(event) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var selectedIndex = dropdown.get(0).selectedIndex;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// clear the selection as needed and revert to
// first option (single selects by definition never
// have no selected option at all, unlike multi):
if (option && option.length) {
// if triggered on an option, deselect that option
option.get(0).selected = false;
} else {
// if triggered on the select, always revert
dropdown.get(0).selectedIndex = 0;
}
// remove any error state (this also tears-down and
// rebuilds the MS dropdown structure so we don't
// need to do it here for the above)
dropdown.trigger('hpui-ok');
// if this dropdown is in the readonly state, we must
// rebuild its hidden inputs now, since the set of
// selected options may have changed
generateReadonlyInputs(dropdown);
});
}
// Register custom error status event on the stateful dropdown.
// Different implementation for multi- and single selects.
if (isMultiple) { // multi-select
hpui_dropdown_self_obj.off('hpui-error.hpui-select');
hpui_dropdown_self_obj.on('hpui-error.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// set error status on the option or select level:
if (option && option.length) { // option level
// add error status at select level, and at
// option level if selected
dropdown.addClass("hpui-error");
if (option.get(0).selected)
option.addClass("hpui-error");
} else { // select level
dropdown.addClass("hpui-error");
}
// teardown and rebuild MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
});
} else { // single-select
hpui_dropdown_self_obj.off('hpui-error.hpui-select');
hpui_dropdown_self_obj.on('hpui-error.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// set error class in every case at the select
// level; single select does not support option
// level error status
dropdown.addClass("hpui-error");
// teardown and rebuild MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
});
}
// Register custom OK status event on the stateful dropdown.
// Different implementation for multi- and single selects.
if (isMultiple) { // multi-select
hpui_dropdown_self_obj.off('hpui-ok.hpui-select');
hpui_dropdown_self_obj.on('hpui-ok.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element.
var option = null;
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// were we triggered on an option and bubbled-up here?
if (jQuery('#' + event.target.id).is('option'))
option = jQuery('#' + event.target.id);
// drop error status on the option or select level:
if (option && option.length) { // option level
// reset error on the option
option.removeClass("hpui-error");
// if no error options remain, reset error on the select
var options = dropdown.children("option");
var stillError = false;
for (var k = 0; k < options.length; k++)
if (jQuery(options[k]).hasClass("hpui-error"))
stillError = true;
if (!stillError)
dropdown.removeClass("hpui-error");
} else { // select level
// drop error class at select and option levels
dropdown.children("option").removeClass("hpui-error");
dropdown.removeClass("hpui-error");
}
// teardown and rebuild MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
});
} else { // single-select
hpui_dropdown_self_obj.off('hpui-ok.hpui-select');
hpui_dropdown_self_obj.on('hpui-ok.hpui-select',
{initVisibleRows: visibleRows,
initIsQualifiedFlag: isQualifiedFlag},
function(event) {
// 'this' is the element
var dropdown = jQuery(this);
var visibleRows = event.data.initVisibleRows;
var isQualifiedFlag = event.data.initIsQualifiedFlag;
// drop error class in every case at the select
// level; single select does not support option
// level error status
dropdown.removeClass("hpui-error");
// teardown and rebuild MS dropdown structure
dropdown.msDropdown().data("dd").destroy();
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown();
}
});
}
// Make sure no height attributes or size have been set - not
// supported, MSDropdown auto-calculates the proper height.
hpui_dropdown_self_obj.css('height', '');
hpui_dropdown_self_obj.css('min-height', '');
hpui_dropdown_self_obj.css('max-height', '');
hpui_dropdown_self_obj.removeAttr('size');
// If multiple not supported, then be sure multiple attribute
// not set.
if (!isMultiple)
hpui_dropdown_self_obj.removeAttr('multiple');
// Initialize the dropdown using the reset event handler.
hpui_dropdown_self_obj.trigger('hpui-reset');
}
}
}
}
// Initialize all stateless dropdowns in the given context.
function initStatelessDropdowns(context){
// Various initialization properties for the different types of stateless dropdown.
var dropdownTypeArray = [{className: "hpui-action-menu", isTitleFixed: true, titleWidth: "53px", isTitleBlank: true},
{className: "hpui-critical-link-menu", isTitleFixed: true, isTitleBlank: false},
{className: "hpui-primary-link-menu", isTitleFixed: true, isTitleBlank: false},
{className: "hpui-secondary-link-menu", isTitleFixed: true, isTitleBlank: false}
];
for(var i = 0; i < dropdownTypeArray.length; i++){
var dropdownType = dropdownTypeArray[i];
jQuery('select.' + dropdownType.className, context).each(function() {
var dropdown = jQuery(this);
// If title width is defined, set it.
if (dropdownType.titleWidth) {
dropdown.css("width", dropdownType.titleWidth);
dropdown.css("min-width", dropdownType.titleWidth);
dropdown.css("max-width", dropdownType.titleWidth);
}
// If title is fixed, then provide the option for it by default.
// The title text is blank by default.
if (dropdownType.isTitleFixed) {
var firstOption = null;
var options = dropdown.children("option");
if (options && options.length)
firstOption = jQuery(options[0]);
if (dropdownType.isTitleBlank) { // action menu
if (firstOption && !firstOption.html())
// if first option in action menu is blank, make it the heading
firstOption.addClass('hpui-heading');
else {
// otherwise make new blank heading option for the action menu
firstOption = jQuery(' ');
dropdown.prepend(firstOption);
}
} else { // other stateless menus
if (firstOption)
// if first option exists, make it the heading
firstOption.addClass('hpui-heading');
else {
// otherwise make new blank heading (the only option)
firstOption = jQuery(' ');
dropdown.prepend(firstOption);
}
}
// Make sure no other options get treated as pre-selected; the
// first option (ie the heading option) must be the pre-selected one.
dropdown.children("option").removeAttr('selected');
dropdown[0].selectedIndex = 0;
}
//get visibel row number
var visibleRows = getVisibleRows(dropdown);
// Multi-select, disabled, error and size not supported for stateless
// dropdowns. Remove if set, otherwise it may mess up display.
dropdown.removeAttr('disabled');
dropdown.removeAttr('multiple');
dropdown.removeAttr('size');
dropdown.removeClass('hpui-error');
dropdown.children("option").removeClass('hpui-error');
// Make sure only the first option, if any, has hpui-heading.
dropdown.children("option").slice(1).removeClass('hpui-heading');
// Make sure no height attributes have been set - not supported,
// MSDropdown auto-calculates the proper height.
dropdown.css('height', '');
dropdown.css('min-height', '');
dropdown.css('max-height', '');
var isQualifiedFlag = checkVisibleRowIsQualified(visibleRows);
if(typeof visibleRows != "undefined" && visibleRows && isQualifiedFlag) {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({isTitleFixed: dropdownType.isTitleFixed, visibleRows: visibleRows});
}else {
// Call msDropdown function to construct the dropdown.
dropdown.msDropdown({isTitleFixed: dropdownType.isTitleFixed});
}
});
}
}
function checkVisibleRowIsQualified(visibleRows) {
if(typeof visibleRows != "undefined" && visibleRows) {
var reg = /^([1-9]\d*)$/;
return reg.test(visibleRows);
}
return false;
}
function getVisibleRows(dropdown) {
var visibleRows = jQuery(dropdown[0]).attr("size");
if (typeof visibleRows != "undefined")
visibleRows = jQuery.trim(visibleRows);
//get the number of all options
var rowNumber = jQuery(dropdown[0]).children("option").length;
//get the number of heading option
var headingOptionLength = jQuery(dropdown[0]).find(".hpui-heading").length;
//check whether the rowNumber is blank or 'undefined'
if (typeof rowNumber != "undefined" && rowNumber) {
//if firstOption is not blank, the rowNumber includes the heading option, so cut one heading option
if (typeof headingOptionLength != "undefined" && headingOptionLength) {
rowNumber = rowNumber - 1;
}
if (typeof visibleRows != "undefined" && visibleRows) {
//if size that feature developer gave is more than actual size, just show all option without scroll bar
if (visibleRows > rowNumber)
visibleRows = rowNumber;
}
}
return visibleRows;
}
/****** end HPE dropdowns JS (dropdowns.js) ******/
/****** begin HPE expand-collapse JS (expand-collapse.js) ******/
/** * "Public" functions - may be used by feature developers ** */
// Add screenreader messages for the given locale into the expand-collapse
// structures within the given context (may be a JQuery Object, a string HTML ID,
// or the whole page by default).
function hpuiAddExpandCollapseResources(context) {
// Get the message resources.
if (typeof(hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
if (typeof expand_all_screenreader == 'string') {
expandAllScreenReaderText = expand_all_screenreader;
}
if (typeof collapse_all_screenreader == 'string') {
collapseAllScreenReaderText = collapse_all_screenreader;
}
if (typeof expand_screenreader == 'string') {
expandScreenReaderText = expand_screenreader;
}
if (typeof collapse_screenreader == 'string') {
collapseScreenReaderText = collapse_screenreader;
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// Rewrite the messages into the expand-collapse structures in the context.
jQuery('div.hpui-heading a.hpui-expand-icon', context).each(
function() {
jQuery(this).find('span.hpui-screenreader-text').text(expandAllScreenReaderText);
});
jQuery('div.hpui-heading a.hpui-collapse-icon', context).each(
function() {
jQuery(this).find('span.hpui-screenreader-text').text(collapseAllScreenReaderText);
});
jQuery('a.hpui-collapse-icon', context).each(
function() {
var collapseIcon = jQuery(this);
if (!collapseIcon.parent().hasClass('hpui-heading')) {
var screenReaderSpan = collapseIcon.find('span.hpui-screenreader-text');
if (screenReaderSpan && screenReaderSpan.length) {
screenReaderSpan.text(collapseScreenReaderText);
} else {
collapseIcon.append('' + collapseScreenReaderText + ' ');
}
}
});
jQuery('a.hpui-expand-icon', context).each(
function() {
var expandIcon = jQuery(this);
if (!expandIcon.parent().hasClass('hpui-heading')) {
var screenReaderSpan = expandIcon.find('span.hpui-screenreader-text');
if (screenReaderSpan && screenReaderSpan.length) {
screenReaderSpan.text(expandScreenReaderText);
} else {
expandIcon.append('' + expandScreenReaderText + ' ');
}
}
});
}
/** * "Private" functions not for direct use by feature developers ** */
var expandScreenReaderText = '+';
var collapseScreenReaderText = '-';
var expandAllScreenReaderText = '+';
var collapseAllScreenReaderText = '-';
// Initialize all expand-collapse disclosure sections in the given context.
function initExpandCollapse(context) {
// Define screen reading text.
// Add the divider class for last section and content.
var collapsedSections = jQuery('div.hpui-disclosures div.hpui-collapsed-section', context);
if (collapsedSections && collapsedSections.length) {
for ( var i = 0; i < collapsedSections.length; i++) {
var collapsedSection = jQuery(collapsedSections[i]);
if (!collapsedSection.next().next().hasClass('hpui-collapsed-section') && !collapsedSection.next().next().hasClass('hpui-expanded-section')) {
collapsedSection.css('border-bottom', '1px solid #CCCCCC');
}
var expandIcons = collapsedSection.find('a.hpui-expand-icon');
if (!expandIcons || !expandIcons.length) {
collapsedSection.prepend(' ');
}
}
}
var contents = jQuery('div.hpui-disclosures div.hpui-content', context);
if (contents && contents.length) {
for ( var i = 0; i < contents.length; i++) {
var content = jQuery(contents[i]);
if (!content.next().hasClass('hpui-collapsed-section') && !content.next().hasClass('hpui-expanded-section')) {
content.css('border-bottom', '1px solid #CCCCCC');
}
// Control the content hidden or display by section class name.
if (content.prev().hasClass('hpui-collapsed-section')) {
content.hide();
} else if (content.prev().hasClass('hpui-expanded-section')) {
content.show();
}
}
}
// Add the button icons automatically. Must do this re-entrantly in case
// this code reloads (eg from user navigating back).
var headers = jQuery('div.hpui-disclosures div.hpui-heading', context);
if (headers && headers.length) {
for ( var i = 0; i < headers.length; i++) {
var header = jQuery(headers[i]);
var expandIcons = header.find('a.hpui-expand-icon');
var collapseIcons = header.find('a.hpui-collapse-icon');
var headerScreenReadingText = jQuery.trim(header.text());
if (headerScreenReadingText) {
header.text('');
header.append('' + headerScreenReadingText + ' ');
}
if (!expandIcons || !expandIcons.length) {
header.append('' + expandAllScreenReaderText + ' ');
}
if (!collapseIcons || !collapseIcons.length) {
header.append('' + collapseAllScreenReaderText + ' ');
}
}
}
var expandedSections = jQuery('div.hpui-disclosures div.hpui-expanded-section', context);
if (expandedSections && expandedSections.length) {
for ( var i = 0; i < expandedSections.length; i++) {
var expandedSection = jQuery(expandedSections[i]);
var collapseIcons = expandedSection.find('a.hpui-collapse-icon');
if (!collapseIcons || !collapseIcons.length) {
expandedSection.prepend(' ');
}
}
}
// Expand and collapse content when clicking the sections.
function toggleDisclosureSection() {
return function() {
jQuery(this).css('border-bottom', '0px');
jQuery(this).next('div.hpui-content').slideToggle(
500,
function() {
if (jQuery(this).is(':visible')) {
var section = jQuery(this).prev('div.hpui-collapsed-section');
var icon = section.find('a.hpui-expand-icon');
icon.removeClass('hpui-expand-icon').addClass('hpui-collapse-icon');
icon.find('span.hpui-screenreader-text').text(collapseScreenReaderText);
section.addClass('hpui-expanded-section').removeClass('hpui-collapsed-section');
} else {
var section = jQuery(this).prev('div.hpui-expanded-section');
var icon = section.find('a.hpui-collapse-icon');
icon.removeClass('hpui-collapse-icon').addClass('hpui-expand-icon');
icon.find('span.hpui-screenreader-text').text(expandScreenReaderText);
section.addClass('hpui-collapsed-section').removeClass('hpui-expanded-section');
if (!jQuery(this).next().hasClass('hpui-collapsed-section') && !jQuery(this).next().hasClass('hpui-expanded-section')) {
section.css('border-bottom', '1px solid #CCCCCC');
}
}
});
}
}
// Expand the content when click the section.
jQuery('div.hpui-disclosures div.hpui-collapsed-section', context).off('click.hpui-disclosures');
jQuery('div.hpui-disclosures div.hpui-collapsed-section', context).on('click.hpui-disclosures', toggleDisclosureSection());
// Collapse the content when click the section.
jQuery('div.hpui-disclosures div.hpui-expanded-section', context).off('click.hpui-disclosures');
jQuery('div.hpui-disclosures div.hpui-expanded-section', context).on('click.hpui-disclosures', toggleDisclosureSection());
// Expand all the contents in disclosure.
jQuery('div.hpui-disclosures div.hpui-heading a.hpui-expand-icon', context).off('click.hpui-disclosures');
jQuery('div.hpui-disclosures div.hpui-heading a.hpui-expand-icon', context).on('click.hpui-disclosures',
function() {
jQuery(this).parent().parent().find('div.hpui-content:last').prev().css('border-bottom', '0px');
jQuery(this).parent().parent().find('div.hpui-content').slideDown(
500,
function() {
var section = jQuery(this).prev('div.hpui-collapsed-section');
var icon = section.find('a.hpui-expand-icon');
icon.removeClass('hpui-expand-icon').addClass('hpui-collapse-icon');
icon.find('span.hpui-screenreader-text').text(collapseScreenReaderText);
section.addClass('hpui-expanded-section').removeClass('hpui-collapsed-section');
});
});
// Collapse all the contents in disclosure.
jQuery('div.hpui-disclosures div.hpui-heading a.hpui-collapse-icon', context).off('click.hpui-disclosures');
jQuery('div.hpui-disclosures div.hpui-heading a.hpui-collapse-icon', context).on('click.hpui-disclosures',
function() {
jQuery(this).parent().parent().find('div.hpui-content').slideUp(
500,
function() {
var section = jQuery(this).prev('div.hpui-expanded-section');
var icon = section.find('a.hpui-collapse-icon');
icon.removeClass('hpui-collapse-icon').addClass('hpui-expand-icon');
icon.find('span.hpui-screenreader-text').text(expandScreenReaderText);
section.addClass('hpui-collapsed-section').removeClass('hpui-expanded-section');
if (!jQuery(this).next().hasClass('hpui-collapsed-section')
&& !jQuery(this).next().hasClass('hpui-expanded-section')) {
section.css('border-bottom', '1px solid #CCCCCC');
}
});
});
// Add or remove style for focus or blur section.
jQuery('div.hpui-disclosures div.hpui-collapsed-section a.hpui-expand-icon', context).off('focus');
jQuery('div.hpui-disclosures div.hpui-collapsed-section a.hpui-expand-icon', context).on('focus', function() {
jQuery(this).parent().addClass('hpui-section-focus');
});
jQuery('div.hpui-disclosures div.hpui-expanded-section a.hpui-collapse-icon', context).off('focus');
jQuery('div.hpui-disclosures div.hpui-expanded-section a.hpui-collapse-icon', context).on('focus', function() {
jQuery(this).parent().addClass('hpui-section-focus');
});
jQuery('div.hpui-disclosures div.hpui-collapsed-section a.hpui-expand-icon', context).off('blur');
jQuery('div.hpui-disclosures div.hpui-collapsed-section a.hpui-expand-icon', context).on('blur', function() {
jQuery(this).parent().removeClass('hpui-section-focus');
});
jQuery('div.hpui-disclosures div.hpui-expanded-section a.hpui-collapse-icon', context).off('blur');
jQuery('div.hpui-disclosures div.hpui-expanded-section a.hpui-collapse-icon', context).on('blur', function() {
jQuery(this).parent().removeClass('hpui-section-focus');
});
// Ensure all expand/collapse icons are in the tab flow and trigger click on 'enter' key.
var icons = jQuery('a.hpui-expand-icon,a.hpui-collapse-icon', context).each(function(index) {
var icon = jQuery(this);
// Set screenreader text on this icon, except in case of expand/collapse-all icons because
// they have already been set (above).
if (!icon.parent().hasClass('hpui-heading')) {
if (icon.hasClass('hpui-expand-icon')) {
icon.html('' + expandScreenReaderText + ' ');
} else {
icon.html('' + collapseScreenReaderText + ' ');
}
}
// Insert into the normal tabflow. No need to do this if tab flow or an href
// is set.
if (!icon.attr('tabindex') && !icon.attr('href'))
icon.attr('tabindex', '0');
// Register keypress event handler to trigger click on 'enter', for accessibility.
// No need to do this if an href is set.
if (!icon.attr('href')) {
icon.off('keypress.hpui-expand-collapse');
icon.on('keypress.hpui-expand-collapse', function(event) {
var link = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
link.trigger('click');
}
});
}
});
}
/** **** end HPE expand-collapse JS (expand-collapse.js) ***** */
/****** begin HPE form elements JS (form-elements.js) ******/
/*** "Public" form element methods - start with prefix "hpui" - for use by feature developers ***/
function hpuiSetEnabled(id) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-enable');
}
function hpuiSetDisabled(id) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-disable');
}
function hpuiSetReadonly(id) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-readonly');
}
function hpuiClear(id) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-clear');
}
function hpuiSetValue(id, val) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
if (typeof val == 'undefined')
val = '';
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-value', val);
}
function hpuiReset(id) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery) {
if (el.is('form'))
el.trigger('hpui-form-reset');
else
el.trigger('hpui-reset');
}
}
function hpuiToggle(id, on) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-toggle', on);
}
function hpuiSetError(id) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-error');
}
function hpuiSetOK(id) {
var el = id;
// If given a string, assume it is an HTML ID and select that object.
if (id && (typeof id == 'string'))
el = jQuery('#' + id);
// Make sure we have a JQuery object; return short otherwise.
if (el && el.length && typeof el == 'object' && el instanceof jQuery)
el.trigger('hpui-ok');
}
// Add screenreader messages for the given locale into the form elements
// in the given context (may be a JQuery Object, a string HTML ID,
// or the whole page by default).
function hpuiAddFormResources(context) {
// Get the message resources.
if (typeof(hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// Rewrite the messages into the checkboxes in the context.
jQuery('input[type=checkbox].hpui-checkbox', context).each(function() {
var input = jQuery(this);
var anchor = input.prev('a.hpui-checkbox');
setCheckboxScreenreaderText(input, anchor);
});
// Rewrite the messages into the radio buttons in the context.
jQuery('input[type=radio].hpui-radio', context).each(function() {
var input = jQuery(this);
var anchor = input.prev('a.hpui-radio');
setRadioScreenreaderText(input, anchor);
});
// Rewrite the messages into the file inputs in the context.
jQuery('input[type=file].hpui-file', context).each(function() {
var fileInput = jQuery(this);
var span = fileInput.prev('span.hpui-file');
var textInput = span.find('input[type=text].hpui-input.hpui-file');
var ieVersion = -1;
var buttonInput;
if (typeof(getInternetExplorerVersion) == 'function')
ieVersion = getInternetExplorerVersion();
// For IE8 the browse button is actually a span.
if (ieVersion > 0 && ieVersion < 9)
buttonInput = span.find('span.hpui-secondary-button.hpui-file');
else
buttonInput = span.find('input[type=button].hpui-secondary-button.hpui-file');
setFileScreenreaderText(fileInput, textInput, buttonInput);
});
jQuery('input[type=file].hpui-slim-file', context).each(function() {
var fileInput = jQuery(this);
var span = fileInput.prev('span.hpui-slim-file');
var textInput = span.find('input[type=text].hpui-slim-input.hpui-slim-file');
var ieVersion = -1;
var buttonInput;
if (typeof(getInternetExplorerVersion) == 'function')
ieVersion = getInternetExplorerVersion();
// For IE8 the browse button is actually a span.
if (ieVersion > 0 && ieVersion < 9)
buttonInput = span.find('span.hpui-secondary-slim-button.hpui-slim-file');
else
buttonInput = span.find('input[type=button].hpui-secondary-slim-button.hpui-slim-file');
setFileScreenreaderText(fileInput, textInput, buttonInput);
});
}
/*** "Private" form element methods ***/
// Initialize file inputs in the given context.
function initFileInputs(baseFileClass, baseTextClass, baseButtonClass, context) {
var spanSelector = 'span.' + baseFileClass;
var fileInputSelector = 'input[type=file].' + baseFileClass;
var textInputSelector = 'input[type=text].' + baseTextClass + '.' + baseFileClass;
var uploadSelector = 'input[type=button].' + baseFileClass + ',' +
'input[type=submit].' + baseFileClass + ',' +
'input[type=reset].' + baseFileClass;
var buttonSelector;
var ieVersion = -1;
if (typeof(getInternetExplorerVersion) == 'function')
ieVersion = getInternetExplorerVersion();
// Find and process all file inputs.
var hpui_file_input_self = jQuery(fileInputSelector, context);
if (hpui_file_input_self && hpui_file_input_self.length) {
for (var n = 0; n < hpui_file_input_self.length; n++) {
var hpui_file_input_self_obj = jQuery(hpui_file_input_self[n]);
var error = hpui_file_input_self_obj.hasClass('hpui-error');
var disabled = hpui_file_input_self_obj.attr('disabled');
var width = hpui_file_input_self_obj.css('width');
var size = hpui_file_input_self_obj.attr('size');
var currentState = disabled ? 'disable' : 'enable';
// For IE8 we cannot use display none as that disables the file input.
// Instead hide the file input by making it transparent and
// shrinking it to minimal size; also remove the tab-stop.
if (ieVersion > 0 && ieVersion < 9) {
// hpui_file_input_self_obj.css('visibility', 'hidden');
hpui_file_input_self_obj.css('width', '0px');
hpui_file_input_self_obj.css('opacity', '0');
hpui_file_input_self_obj.css('filter', 'alpha(opacity=0)');
hpui_file_input_self_obj.attr('tabindex', '-1');
} else {
hpui_file_input_self_obj.css('display', 'none');
}
// Instantiate the rest of the required structure if its not already there.
var hpui_file_span = hpui_file_input_self_obj.prev(spanSelector);
if (!hpui_file_span || !hpui_file_span.length) {
// Generate a new text input for this file input.
var hpui_text_input = jQuery(' ');
hpui_text_input.attr('tabindex', '-1'); // disable tab key
hpui_text_input.addClass(baseTextClass).addClass(baseFileClass);
if (error) hpui_text_input.addClass('hpui-error');
if (disabled) hpui_text_input.attr('disabled', '');
else hpui_text_input.attr('readonly', 'readonly');
if (width) hpui_text_input.css('width', width);
if (size) hpui_text_input.attr('size', size);
// Generate a default-text span for this file input, if any.
var hpui_default_text = hpui_file_input_self_obj.next('.hpui-default-text');
if (hpui_default_text && hpui_default_text.length)
hpui_default_text = hpui_default_text.detach();
// Generate a new browse button for this file input. Different
// technique depending on browser - IE8 needs a fake (span) button,
// but we prefer to use a real button input for other browsers.
var hpui_button, hpui_button_text;
if (ieVersion > 0 && ieVersion < 9) {
hpui_button_text = hpui_file_input_self_obj.attr('title');
if (hpui_button_text)
hpui_file_input_self_obj.removeAttr('title');
else
hpui_button_text = "";
hpui_button = jQuery('' + hpui_button_text + ' ');
hpui_button.addClass(baseButtonClass).addClass(baseFileClass);
if (disabled)
hpui_button.attr('disabled', '');
else
hpui_button.attr('tabindex', '0');
buttonSelector = 'span.' + baseButtonClass + '.' + baseFileClass;
} else {
hpui_button = jQuery(' ');
hpui_button.addClass(baseButtonClass).addClass(baseFileClass);
if (disabled)
hpui_button.attr('disabled', '');
hpui_button_text = hpui_file_input_self_obj.attr('title');
if (hpui_button_text) {
hpui_button.attr('value', hpui_button_text);
hpui_file_input_self_obj.removeAttr('title');
}
buttonSelector = 'input[type=button].' + baseButtonClass + '.' + baseFileClass;
}
// Generate a span container for the above.
hpui_file_span = jQuery(' ');
// IE 10, 9, and 8 only: generate a fake label container for the text
// and button inputs. This is to workaround a security constraint
// in IE prior to version 11: these versions of IE only allow a file
// input to be legally triggered from the original file input itself
// or an associated label. Since this code hides the original file
// input and generates a visible text and button input for the user
// to interact with instead, in these versions of IE this is not legal,
// and the file input will be ignored and reset, and the form submit
// aborted, when the form is submitted. But since these versions of
// IE allow anything declared a label for the file input to legally
// trigger the file input, if we wrap our text and button inputs in
// a label, this will satisfy IE. Since this is an IE-specific hack,
// we only do this for the needed versions of IE: 10 and earlier. The
// "hpui-fake" class means this label will not be selected later (see
// getLabel(...) function).
if (ieVersion > 0 && ieVersion < 11) {
var ieID = generateId(hpui_file_input_self_obj);
var ieLabel = jQuery(' ');
ieLabel.append(hpui_text_input);
if (hpui_default_text) ieLabel.append(hpui_default_text);
ieLabel.append(hpui_button);
hpui_file_span.append(ieLabel);
} else {
hpui_file_span.append(hpui_text_input);
if (hpui_default_text) hpui_file_span.append(hpui_default_text);
hpui_file_span.append(hpui_button);
}
// Set screenreader text into the span, and add it to the DOM.
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(hpui_file_span);
hpui_file_input_self_obj.before(hpui_file_span);
setFileScreenreaderText(hpui_file_input_self_obj, hpui_text_input, hpui_button);
// If there is an upload button, disable it and wrap all of this -
// the span container for the above, the file input, and the upload
// button - inside another span container.
var hpui_upload = hpui_file_input_self_obj.next(uploadSelector);
if (hpui_upload && hpui_upload.length) {
// Always initialize to disabled.
hpui_upload.attr('disabled', '');
var hpui_parent_span = hpui_file_input_self_obj.parent(spanSelector);
if (!hpui_parent_span || !hpui_parent_span.length) {
hpui_parent_span = jQuery(' ');
hpui_file_input_self_obj.wrap(hpui_parent_span);
hpui_file_span.detach();
hpui_upload.detach();
hpui_file_span.insertBefore(hpui_file_input_self_obj);
hpui_upload.insertAfter(hpui_file_input_self_obj);
// To eliminate gap between browse and upload buttons.
hpui_file_span.css('float', 'left');
}
}
}
// Register change handler to copy filename value to text input.
hpui_file_input_self_obj.off('change.hpui-file');
hpui_file_input_self_obj.on('change.hpui-file', function() {
return function() {
var fileInput = jQuery(this);
var textInput = fileInput.prev(spanSelector).find(textInputSelector);
var buttonInput = fileInput.prev(spanSelector).find(buttonSelector);
var upload = fileInput.next(uploadSelector);
// Backfill the filename into the text input.
if (textInput && textInput.length) {
var filename = fileInput.val();
// Some browsers prepend path info - strip this for user security.
// Paths may be delimited by \ or / chars on different systems.
var j = Math.max(filename.lastIndexOf("/"), filename.lastIndexOf("\\"));
if (j != -1) {
if (j < filename.length - 1)
filename = filename.substring(j + 1);
else
filename = "";
}
// Set the text input value equal to the file input value.
textInput.trigger('hpui-value', filename);
}
// Enable or disable the upload button, if any.
if (upload) {
if (fileInput.val())
upload.removeAttr('disabled');
else
upload.attr('disabled', '');
}
// Update the screenreader text
setFileScreenreaderText(fileInput, textInput, buttonInput);
}
}());
// Register the disable event on the file element.
hpui_file_input_self_obj.off('hpui-disable.hpui-file');
hpui_file_input_self_obj.on('hpui-disable.hpui-file', function() {
return function() {
var fileInput = jQuery(this);
var buttonInput = fileInput.prev(spanSelector).find(buttonSelector);
var textInput = fileInput.prev(spanSelector).find(textInputSelector);
fileInput.attr('disabled', ''); // disable file input
if (buttonInput && buttonInput.length)
buttonInput.attr('disabled', ''); // disable button
if (textInput && textInput.length)
textInput.trigger('hpui-disable'); // disable text input
disableLabel(fileInput); // disable label if any
// Update the screenreader text
setFileScreenreaderText(fileInput, textInput, buttonInput);
}
}());
// Register the enable event on the file element.
hpui_file_input_self_obj.off('hpui-enable.hpui-file');
hpui_file_input_self_obj.on('hpui-enable.hpui-file', function() {
return function() {
var fileInput = jQuery(this);
var buttonInput = fileInput.prev(spanSelector).find(buttonSelector);
var textInput = fileInput.prev(spanSelector).find(textInputSelector);
fileInput.removeAttr('disabled'); // enable file input
if (buttonInput && buttonInput.length)
buttonInput.removeAttr('disabled'); // enable button
if (textInput && textInput.length)
textInput.trigger('hpui-readonly'); // enable text input (readonly)
enableLabel(fileInput); // enable label if any
// Update the screenreader text
setFileScreenreaderText(fileInput, textInput, buttonInput);
}
}());
// Register the reset event on the file element.
hpui_file_input_self_obj.off('hpui-reset.hpui-file');
hpui_file_input_self_obj.on('hpui-reset.hpui-file', function(initState) {
return function() {
var fileInput = jQuery(this);
var textInput = fileInput.prev(spanSelector).find(textInputSelector);
var buttonInput = fileInput.prev(spanSelector).find(buttonSelector);
// Reset to initial enabled/disabled state - this takes care
// of file input, button, text input and label.
fileInput.trigger('hpui-' + initState);
// Reset to initial value (file elements are always blank initially):
//
// First clear the file input. Some browsers let us just set
// it to blank, others require replacing it with a new one (a clone
// of the original, so all attributes and event handlers remain):
fileInput.replaceWith(fileInput.val('').clone(true));
// Then reset the text input.
if (textInput && textInput.length)
textInput.trigger('hpui-reset');
// Update the screenreader text
setFileScreenreaderText(fileInput, textInput, buttonInput);
}
}(currentState));
// Register the clear event on the file element.
hpui_file_input_self_obj.off('hpui-clear.hpui-file');
hpui_file_input_self_obj.on('hpui-clear.hpui-file', function() {
return function() {
var fileInput = jQuery(this);
var textInput = fileInput.prev(spanSelector).find(textInputSelector);
var buttonInput = fileInput.prev(spanSelector).find(buttonSelector);
// Clear the file input. Some browsers let us just set it to
// to blank, others require replacing it with a new one (a clone
// of the original, so all attributes and event handlers remain):
fileInput.replaceWith(fileInput.val('').clone(true));
// Then clear the text input.
if (textInput && textInput.length)
textInput.trigger('hpui-clear');
// Update the screenreader text
setFileScreenreaderText(fileInput, textInput, buttonInput);
}
}());
// Register the error status event on the file element.
hpui_file_input_self_obj.off('hpui-error.hpui-file');
hpui_file_input_self_obj.on('hpui-error.hpui-file', function() {
return function() {
var fileInput = jQuery(this);
var textInput = fileInput.prev(spanSelector).find(textInputSelector);
// Just set error status on the text input.
if (textInput && textInput.length)
textInput.trigger('hpui-error');
}
}());
// Register the OK status event on the file element.
hpui_file_input_self_obj.off('hpui-ok.hpui-file');
hpui_file_input_self_obj.on('hpui-ok.hpui-file', function() {
return function() {
var fileInput = jQuery(this);
var textInput = fileInput.prev(spanSelector).find(textInputSelector);
// Just set OK status on the text input.
if (textInput && textInput.length)
textInput.trigger('hpui-ok');
}
}());
// Note: cannot register hpui-value event handler on file input
// due to browser security constraints (browsers do not let you
// programatically set a file input value). So hpui-value event
// will be ignored by file inputs.
}
}
// Find and process all file text inputs.
var hpui_text_input_self = jQuery(textInputSelector, context);
if (hpui_text_input_self && hpui_text_input_self.length) {
for (var i = 0; i < hpui_text_input_self.length; i++) {
var hpui_text_input_self_obj = jQuery(hpui_text_input_self[i]);
// Override default keydown event handler (except for tab and enter keys).
hpui_text_input_self_obj.off('keydown.hpui-file');
hpui_text_input_self_obj.on('keydown.hpui-file', function(event) {
var textInput = jQuery(this);
var key = event.keyCode; // number value, not string
if (key != 9) { // tab key handled as usual
event.preventDefault(); // other keys canceled...
textInput.trigger('click'); // and handled like click
}
});
// Override default click event handler, to open file browser.
// This no-ops in IE 10 and lower, which is OK (see comments above
// about how we use a fake label tag instead in those browsers).
hpui_text_input_self_obj.off('click.hpui-file');
hpui_text_input_self_obj.on('click.hpui-file', function(event) {
var textInput = jQuery(this);
var fileInput = textInput.parent(spanSelector).next(fileInputSelector);
if (fileInput && fileInput.length) {
// Cancel default click action and blur immediately.
event.stopImmediatePropagation();
event.preventDefault();
textInput.blur();
// Trigger file browser to open.
fileInput.trigger('click');
}
});
// Remove any focus event handler to prevent keyboard focus.
hpui_text_input_self_obj.off('focus');
hpui_text_input_self_obj.on('focus.hpui-file', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
});
hpui_text_input_self_obj.off('mousedown');
hpui_text_input_self_obj.on('mousedown.hpui-file', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
});
hpui_text_input_self_obj.off('mouseup');
hpui_text_input_self_obj.on('mouseup.hpui-file', function(event) {
event.stopImmediatePropagation();
event.preventDefault();
});
}
}
// Find and process all button inputs.
var hpui_file_button_self = jQuery(buttonSelector, context);
if (hpui_file_button_self && hpui_file_button_self.length) {
for (var i = 0; i < hpui_file_button_self.length; i++) {
var hpui_file_button_self_obj = jQuery(hpui_file_button_self[i]);
// Register click handler to open file browser.
// This no-ops in IE 10 and lower, which is OK (see comments above
// about how we use a fake label tag instead in those browsers).
hpui_file_button_self_obj.off('click.hpui-file');
hpui_file_button_self_obj.on('click.hpui-file', function() {
var buttonInput = jQuery(this);
var fileInput = buttonInput.parent(spanSelector).next(fileInputSelector);
if (fileInput && fileInput.length)
// Trigger file browser to open.
fileInput.trigger('click');
});
}
}
}
// Initialize text inputs in the given context.
function initTextInputs(baseClass, context) {
// Find and process all HPUI text inputs of this current class in this page.
var hpui_input_self = jQuery('input[type=text].' + baseClass +
',input[type=password].' + baseClass, context);
if (hpui_input_self && hpui_input_self.length) {
for (var i = 0; i < hpui_input_self.length; i++) {
var hpui_input_self_obj = jQuery(hpui_input_self[i]);
var preValue = hpui_input_self_obj.next('.hpui-default-text').html();
var disabled = hpui_input_self_obj.attr('disabled');
var readonly = hpui_input_self_obj.attr('readonly')
var error = hpui_input_self_obj.hasClass('hpui-error');
var currentClass = error ? baseClass + ' hpui-error' : baseClass;
var currentValue = hpui_input_self_obj.attr('value');
var currentState = readonly ? 'readonly' : 'enable';
currentValue = currentValue ? currentValue : '';
currentState = disabled ? 'disable' : currentState;
// Register the focus event on the input element.
hpui_input_self_obj.off('focus.hpui-input');
hpui_input_self_obj.on('focus.hpui-input', function(preVal) {
return function() {
var input = jQuery(this);
// Ignore focus on disabled and readonly inputs.
if (input.attr('disabled') || input.attr('readonly')) {
return;
}
// On focus, clear current value if filled with default value
if (input.attr('value') == preVal)
input.attr('value', '');
// On focus, set entered class (but leave error state alone)
if (!input.hasClass('hpui-error'))
input.addClass('hpui-entered');
}
}(preValue));
// Register the blur event on the input element.
hpui_input_self_obj.off('blur.hpui-input')
hpui_input_self_obj.on('blur.hpui-input', function() {
return function() {
var input = jQuery(this);
// Ignore blur on disabled and readonly inputs.
if (input.attr('disabled') || input.attr('readonly'))
return;
// On blur, reinitialize value and style based on current value.
// For datepickers, we do not need to do this as the
// datepicker's onSelect and onClose take care of this.
if (!input.hasClass('hpui-datepicker') && !input.hasClass('hpui-slim-datepicker'))
input.trigger('hpui-value', input.attr('value'));
}
}());
// Register the custom disable event on the input element.
hpui_input_self_obj.off('hpui-disable.hpui-input');
hpui_input_self_obj.on('hpui-disable.hpui-input', function() {
return function() {
var input = jQuery(this);
// Set disabled in the HTML.
input.attr('disabled', '').removeAttr('readonly');
// Set disabled style on corresponding label, if any.
disableLabel(input);
}
}());
// Register the custom enable event on the input element.
hpui_input_self_obj.off('hpui-enable.hpui-input');
hpui_input_self_obj.on('hpui-enable.hpui-input', function() {
return function() {
var input = jQuery(this);
// Set enabled in the HTML.
input.removeAttr('disabled').removeAttr('readonly');
// Set enabled style on corresponding label, if any.
enableLabel(input);
}
}());
// Register the custom readonly event on the input element.
hpui_input_self_obj.off('hpui-readonly.hpui-input');
hpui_input_self_obj.on('hpui-readonly.hpui-input', function() {
return function() {
var input = jQuery(this);
// Set readonly in the HTML.
input.attr('readonly', '').removeAttr('disabled');
// Set enabled style on corresponding label, if any.
enableLabel(input);
}
}());
// Register the custom reset event on the input element.
hpui_input_self_obj.off('hpui-reset.hpui-input');
hpui_input_self_obj.on('hpui-reset.hpui-input',
function(initValue, initClass, initState) {
return function() {
var input = jQuery(this);
// Reset the text input style
input.removeClass('hpui-entered hpui-error').addClass(initClass);
// Reset the text input disabled/readonly/enabled state
input.trigger('hpui-' + initState);
// Reset the text input value
input.trigger('hpui-value', initValue);
}
}(currentValue, currentClass, currentState));
// Register the custom error status event on the input element.
hpui_input_self_obj.off('hpui-error.hpui-input');
hpui_input_self_obj.on('hpui-error.hpui-input', function() {
return function() {
var input = jQuery(this);
// Set error class in every case.
input.addClass('hpui-error').removeClass('hpui-entered');
// Reinitialize value and style based on current value.
input.trigger('hpui-value', input.attr('value'));
}
}());
// Register the custom OK status event on the input element.
hpui_input_self_obj.off('hpui-ok.hpui-input');
hpui_input_self_obj.on('hpui-ok.hpui-input', function() {
return function() {
var input = jQuery(this);
// Remove error class in every case.
input.removeClass('hpui-error').removeClass('hpui-entered');
// Reinitialize value and style based on current value.
input.trigger('hpui-value', input.attr('value'));
}
}());
// Register the custom value event on the input element.
hpui_input_self_obj.off('hpui-value.hpui-input');
hpui_input_self_obj.on('hpui-value.hpui-input',
{preVal:preValue},
function(event, val) {
var input = jQuery(this);
// Set the value for the text input.
input.attr('value', val);
// If the value is blank, override with any default value.
if (!input.attr('value') && event.data.preVal)
input.attr('value', event.data.preVal);
// If there is no error, and the value is not blank and not
// defaulted, set the entered class.
if (!input.hasClass('hpui-error')) {
if (input.attr('value') && (input.attr('value') != event.data.preVal))
input.addClass('hpui-entered');
else
input.removeClass('hpui-entered');
} else
input.removeClass('hpui-entered');
// If the value is set when in focus, trigger focus event to set
// proper styles.
if (input.is(':focus'))
input.trigger('focus');
});
// Register the custom clear event on the input element.
hpui_input_self_obj.off('hpui-clear.hpui-input');
hpui_input_self_obj.on('hpui-clear.hpui-input', function() {
return function() {
var input = jQuery(this);
// Clear value and style - same as setting value to blank.
input.trigger('hpui-value', '');
}
}());
// Initialize text input state (disabled, readonly, enabled, value
// and class) based on current state.
hpui_input_self_obj.trigger('hpui-reset');
}
}
}
// Initialize textareas in the given context.
function initTextareas(context) {
// Find an process all HPUI textareas in this page.
var hpui_input_self = jQuery('textarea.hpui-textarea', context);
if (hpui_input_self && hpui_input_self.length) {
for (var i = 0; i < hpui_input_self.length; i++) {
var hpui_input_self_obj = jQuery(hpui_input_self[i]);
var preValue = hpui_input_self_obj.next('.hpui-default-text').html();
var error = hpui_input_self_obj.hasClass('hpui-error');
var disabled = hpui_input_self_obj.attr('disabled');
var readonly = hpui_input_self_obj.attr('readonly');
var currentValue = hpui_input_self_obj.val();
var currentClass = error ? 'hpui-textarea hpui-error' : 'hpui-textarea';
var currentState = readonly ? 'readonly' : 'enable';
currentState = disabled ? 'disable' : currentState;
// Add modifier classes - at this time, just a font class.
hpui_input_self_obj.addClass('hpui-textarea-font');
// Register the focus event on the textarea.
hpui_input_self_obj.off('focus.hpui-textarea');
hpui_input_self_obj.on('focus.hpui-textarea', function(preVal) {
return function(){
var input = jQuery(this);
// Ignore focus on disabled and readonly inputs.
if (input.attr('disabled') || input.attr('readonly')) {
return;
}
// On focus, clear current value if filled with default value
if (input.val() == preVal)
input.val('');
// On focus, set entered class (but leave error state alone)
if (!input.hasClass('hpui-error'))
input.addClass('hpui-entered');
}
}(preValue));
// Register the blur event on the textarea.
hpui_input_self_obj.off('blur.hpui-textarea');
hpui_input_self_obj.on('blur.hpui-textarea', function() {
return function(){
var input = jQuery(this);
// Ignore blur on disabled and readonly inputs.
if (input.attr('disabled') || input.attr('readonly'))
return;
// On blur, reinitialize value and style based on current value.
input.trigger('hpui-value', input.val());
}
}());
// Register the custom disable event on the textarea.
hpui_input_self_obj.off('hpui-disable.hpui-textarea');
hpui_input_self_obj.on('hpui-disable.hpui-textarea', function() {
return function() {
var input = jQuery(this);
// Set disabled in the HTML.
input.attr('disabled', '').removeAttr('readonly');
// Disable resize and scroll regardless of class.
input.resizable({handles: "se"});
input.resizable('disable');
input.css('overflow', 'hidden');
// Set disabled style on corresponding label, if any.
disableLabel(input);
}
}());
// Register the custom enable event on the textarea.
hpui_input_self_obj.off('hpui-enable.hpui-textarea');
hpui_input_self_obj.on('hpui-enable.hpui-textarea', function() {
return function() {
var input = jQuery(this);
var resizable = input.hasClass('hpui-resizable');
// Set enabled in the HTML.
input.removeAttr('disabled').removeAttr('readonly');
// Set enabled resize and scroll behaviors per class.
input.resizable({handles: "se"});
input.resizable(resizable ? 'enable' : 'disable');
if (resizable)
input.css('overflow', 'hidden');
else {
input.css('overflow-y', 'auto');
input.css('overflow-x', 'hidden');
}
// Set enabled style on corresponding label, if any.
enableLabel(input);
}
}());
// Register the custom readonly event on the textarea.
hpui_input_self_obj.off('hpui-readonly.hpui-textarea');
hpui_input_self_obj.on('hpui-readonly.hpui-textarea', function() {
return function() {
var input = jQuery(this);
var resizable = input.hasClass('hpui-resizable');
// Set readonly in the HTML.
input.attr('readonly', '').removeAttr('disabled');
// Set readonly resize and scroll behaviors per class.
input.resizable({handles: "se"});
input.resizable(resizable ? 'enable' : 'disable');
if (resizable)
input.css('overflow', 'hidden');
else {
input.css('overflow-y', 'auto');
input.css('overflow-x', 'hidden');
}
// Set enabled style on corresponding label, if any.
enableLabel(input);
}
}());
// Register the custom error status event on the textarea.
hpui_input_self_obj.off('hpui-error.hpui-textarea');
hpui_input_self_obj.on('hpui-error.hpui-textarea', function() {
return function() {
var input = jQuery(this);
// Set error class in every case.
input.addClass('hpui-error').removeClass('hpui-entered');
// Reinitialize value and style based on current value.
input.trigger('hpui-value', input.val());
}
}());
// Register the custom OK status event on the textarea.
hpui_input_self_obj.off('hpui-ok.hpui-textarea');
hpui_input_self_obj.on('hpui-ok.hpui-textarea', function() {
return function() {
var input = jQuery(this);
// Remove error class in every case.
input.addClass('hpui-textarea');
input.removeClass('hpui-error').removeClass('hpui-entered');
// Reinitialize value and style based on current value.
input.trigger('hpui-value', input.val());
}
}());
// Register the custom value event on the textarea.
hpui_input_self_obj.off('hpui-value.hpui-textarea');
hpui_input_self_obj.on('hpui-value.hpui-textarea', {preVal:preValue}, function(event, val) {
var input = jQuery(this);
// Set the value for the textarea.
input.val(val);
// If the value is blank, override with any default value.
if (!input.val() && event.data.preVal)
input.val(event.data.preVal);
// If the value is not blank and not any default, set the
// entered class; otherwise set the base class. But if an error
// class, leave this alone.
if (!input.hasClass('hpui-error')) {
if (input.val() && (input.val() != event.data.preVal))
input.addClass('hpui-entered');
else
input.removeClass('hpui-entered');
} else
input.removeClass('hpui-entered');
// If the value is set when in focus, trigger focus event to set
// proper styles.
if (input.is(':focus'))
input.trigger('focus');
});
// Register the custom clear event on the textarea.
hpui_input_self_obj.off('hpui-clear.hpui-textarea');
hpui_input_self_obj.on('hpui-clear.hpui-textarea', function() {
return function() {
var input = jQuery(this);
// Clear value and style - same as setting value to blank.
input.trigger('hpui-value', '');
}
}());
// Initialize textarea state (disabled, readonly, enabled) based
// on current state.
hpui_input_self_obj.trigger('hpui-' + currentState);
// Initialize textarea value based on current value.
hpui_input_self_obj.trigger('hpui-value', currentValue);
// Register the custom reset event on the text field element (this
// can only happen after the width and height have been set by
// JQuery Resizable, which happened above)
var currentWidth = hpui_input_self_obj.width();
var currentHeight = hpui_input_self_obj.height();
hpui_input_self_obj.off('hpui-reset.hpui-textarea');
hpui_input_self_obj.on('hpui-reset.hpui-textarea',
function(initValue, initClass, initWidth, initHeight, initState) {
return function() {
var input = jQuery(this);
// Reset the textarea size.
input.resizable('destroy');
input.width(initWidth);
input.height(initHeight);
// Reset the textarea style.
input.removeClass('hpui-error hpui-entered').addClass(initClass);
// Reset the textarea disabled/readonly/enabled state.
input.trigger('hpui-' + initState);
// Reset the textarea value.
input.trigger('hpui-value', initValue);
}
}(currentValue, currentClass, currentWidth, currentHeight, currentState));
}
}
}
// Initialize checkboxes in the given context.
function initCheckboxes(context) {
// Find and process all HPUI checkboxes in this page.
var hpui_checkbox_self = jQuery('input[type=checkbox].hpui-checkbox', context);
if (hpui_checkbox_self && hpui_checkbox_self.length) {
for (var i = 0; i < hpui_checkbox_self.length; i++) {
var hpui_checkbox_self_obj = jQuery(hpui_checkbox_self[i]);
var error = hpui_checkbox_self_obj.hasClass('hpui-error');
var disabled = hpui_checkbox_self_obj.attr('disabled');
var readonly = hpui_checkbox_self_obj.attr('readonly');
var checked = hpui_checkbox_self_obj.attr('checked');
var currentClass = error ? 'hpui-checkbox hpui-error' : 'hpui-checkbox';
var currentChecked = checked ? 'checked' : '';
var currentState = readonly ? 'readonly' : 'enable';
currentState = disabled ? 'disable' : currentState;
// Generate an anchor tag and prepend it to the checkbox input, if
// it does not already exist. And make sure the input display is
// turned off and screenreader text is set.
hpui_checkbox_self_obj.css({display:'none'});
var hpui_checkbox = hpui_checkbox_self_obj.prev('a.hpui-checkbox');
if (!hpui_checkbox || !hpui_checkbox.length) {
hpui_checkbox = jQuery(" ");
// Initialize screenreading text.
setCheckboxScreenreaderText(hpui_checkbox_self_obj, hpui_checkbox);
// Attach the new checkbox to the DOM.
hpui_checkbox_self_obj.before(hpui_checkbox);
}
// Register the click event on the label, to trigger click on anchor
// instead of default action.
var labelEl = getLabel(hpui_checkbox_self_obj);
if (labelEl) {
labelEl.off('click.hpui-checkbox');
labelEl.on('click.hpui-checkbox', {anchor:hpui_checkbox}, function(event) {
event.preventDefault();
event.data.anchor.trigger('click');
});
}
// Register the click event on the anchor. As a click event, this
// propagates to the standard click handler first, and may be
// canceled by the standard handler. It delegates to the standard
// click handler to toggle the checkbox state, then syncs the CSS
// class, screenreader text and anchor state with it.
hpui_checkbox.off('click.hpui-checkbox');
hpui_checkbox.on('click.hpui-checkbox',
{input:hpui_checkbox_self_obj},
function(event) {
var anchor = jQuery(this);
var input = event.data.input;
// Ignore click on disabled and readonly inputs.
if (anchor.attr('disabled') || anchor.attr('readonly'))
return;
// Trigger the native checkbox click. Note: In JQuery this does not affect the 'checked'
// attribute, just the internal state.
input.trigger(event);
// If the native handling canceled the event, stop.
if (event.isDefaultPrevented() || event.isPropagationStopped() || event.isImmediatePropagationStopped())
return;
// Now sync CSS class and anchor state with checkbox state.
anchor.removeClass('hpui-error'); // Remove error state, if any
input.removeClass('hpui-error'); // Remove error state, if any
// Because the native checkbox click handler (see above) only affected the internal state,
// use .prop method to query state of the checkbox. Then forcibly set the 'checked'
// attribute accordingly for all subsequent logic to use. (This is for backward-compatibility
// with all the other existing code in this JS file, which expects the .attr('checked') method
// to reflect not just the state of the 'checked' attribute but also the internal state of thecheckbox.)
if (input.prop('checked')) {
anchor.attr('checked', 'checked');
input.attr('checked', 'checked');
} else {
anchor.removeAttr('checked');
input.removeAttr('checked');
}
// Set screenreading text.
setCheckboxScreenreaderText(input, anchor);
});
// Register custom event on the input to toggle (or set/unset) the
// checked state and then set the class consistent with that. This
// does not propagate to the standard click handler, nor use it to
// set the checkbox checked state (compare with click handler
// above).
hpui_checkbox_self_obj.off('hpui-toggle.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-toggle.hpui-checkbox',
{anchor:hpui_checkbox},
function(event, on) {
var anchor = event.data.anchor;
var input = jQuery(this);
if (on == undefined)
on = input.attr('checked') ? false : true;
// Clear any error class on anchor and checkbox
if ((on && !input.attr('checked')) ||
(!on && input.attr('checked'))) {
anchor.removeClass('hpui-error');
input.removeClass('hpui-error');
}
// Set checked or unchecked on anchor and checkbox
if (on) {
anchor.attr('checked', 'checked');
input.attr('checked', 'checked');
} else {
anchor.removeAttr('checked');
input.removeAttr('checked');
}
// Set screenreading text.
setCheckboxScreenreaderText(input, anchor);
});
// Register the custom disable event on the input element.
hpui_checkbox_self_obj.off('hpui-disable.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-disable.hpui-checkbox', function(anchor) {
return function() {
var input = jQuery(this);
// Set disabled in the HTML.
anchor.attr('disabled', '').removeAttr('readonly');
input.attr('disabled', '').removeAttr('readonly');
// Set disabled style on corresponding label, if any.
disableLabel(input);
// Set screenreading text.
setCheckboxScreenreaderText(input, anchor);
}
}(hpui_checkbox));
// Register the custom enable event on the input element.
hpui_checkbox_self_obj.off('hpui-enable.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-enable.hpui-checkbox', function(anchor) {
return function() {
var input = jQuery(this);
// Set enabled in the HTML.
anchor.removeAttr('disabled').removeAttr('readonly');
input.removeAttr('disabled').removeAttr('readonly');
// Set enabled style on corresponding label, if any.
enableLabel(input);
// Set screenreading text.
setCheckboxScreenreaderText(input, anchor);
}
}(hpui_checkbox));
// Register the custom readonly event on the input element.
hpui_checkbox_self_obj.off('hpui-readonly.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-readonly.hpui-checkbox', function(anchor) {
return function() {
var input = jQuery(this);
// Set enabled in the HTML.
anchor.attr('readonly', '').removeAttr('disabled');
input.attr('readonly', '').removeAttr('disabled');
// Set enabled style on corresponding label, if any.
enableLabel(input);
// Set screenreading text.
setCheckboxScreenreaderText(input, anchor);
}
}(hpui_checkbox));
// Register the custom error status event on the input element.
hpui_checkbox_self_obj.off('hpui-error.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-error.hpui-checkbox', function(anchor) {
return function() {
var input = jQuery(this);
// Set error class in every case.
input.addClass('hpui-error');
anchor.addClass('hpui-error');
}
}(hpui_checkbox));
// Register the custom OK status event on the input element.
hpui_checkbox_self_obj.off('hpui-ok.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-ok.hpui-checkbox', function(anchor) {
return function() {
var input = jQuery(this);
// Remove error class in every case.
input.removeClass('hpui-error');
anchor.removeClass('hpui-error');
}
}(hpui_checkbox));
// Register the custom value event on the input element.
hpui_checkbox_self_obj.off('hpui-value.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-value.hpui-checkbox',
function(event, val) {
var input = jQuery(this);
// Value event with blank value is same as toggle-off; value
// event with any non-blank value is same as toggle-on.
var on = val;
input.trigger('hpui-toggle', on);
});
// Register the custom clear event on the input element.
hpui_checkbox_self_obj.off('hpui-clear.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-clear.hpui-checkbox', function() {
var input = jQuery(this);
// Clear event is same as toggle-off.
input.trigger('hpui-toggle', false);
});
// Register the custom reset event on the input element.
hpui_checkbox_self_obj.off('hpui-reset.hpui-checkbox');
hpui_checkbox_self_obj.on('hpui-reset.hpui-checkbox',
function(anchor, initOn, initClass, initState) {
return function() {
var input = jQuery(this);
// Set the checkbox to proper checked/unchecked state
input.trigger('hpui-toggle', initOn);
// Reset class on checkbox and associated anchor to initial class
input.removeClass('hpui-error').addClass(initClass);
anchor.removeClass('hpui-error').addClass(initClass);
// Reset disabled and/or readonly states to initial state
input.trigger('hpui-' + initState);
}
}(hpui_checkbox, currentChecked, currentClass, currentState));
// Initialize checkbox state (disabled, readonly, enabled,
// checked/unchecked and class) based on current values
hpui_checkbox_self_obj.trigger('hpui-reset');
}
}
}
// Initialize radio buttons in the given context.
function initRadioButtons(context) {
// Setup checked/unchecked state across a radio button group
function normalizeHPUIradios(input, anchor, group, on) {
if (on) {
// Uncheck all radio buttons in this group.
group.prev('a.hpui-radio').removeAttr('checked');
group.removeAttr('checked');
// Then checkmark this radio button.
anchor.attr('checked', 'checked');
input.attr('checked', 'checked');
// Finally set screenreading text across the group.
group.each(function() {
var input = jQuery(this);
var anchor = input.prev('a.hpui-radio');
setRadioScreenreaderText(input, anchor);
});
} else {
// Uncheck this radio button. No side-effect on the group.
anchor.removeAttr('checked');
input.removeAttr('checked');
// Finally set screenreading text.
setRadioScreenreaderText(input, anchor);
}
}
// Get radion buttons just in this group
function getHPUIradios(all, name) {
return all.filter(function(index) {
return (jQuery(this).attr('name') == name) ? true : false;
});
}
// Find and process all HPUI radio buttons in the page.
var hpui_radioButton_self = jQuery('input[type=radio].hpui-radio', context);
if (hpui_radioButton_self && hpui_radioButton_self.length) {
// For each radio button element create an anchor element for the
// styling and insert before the radio button, if it does not already
// exist. And make sure the input display is off.
for (var i = 0; i < hpui_radioButton_self.length; i++) {
var hpui_radioButton_self_obj = jQuery(hpui_radioButton_self[i]);
var error = hpui_radioButton_self_obj.hasClass('hpui-error');
var currentClass = error ? 'hpui-radio hpui-error' : 'hpui-radio';
var hpui_radioButton = hpui_radioButton_self_obj.prev('a.hpui-radio');
hpui_radioButton_self_obj.css({display:'none'});
if (!hpui_radioButton || !hpui_radioButton.length) {
hpui_radioButton = jQuery(" ");
// Attach the new anchor into the DOM.
hpui_radioButton_self_obj.before(hpui_radioButton);
}
}
// For each radio button element find all the related elements and set
// them to their normalized initial state across the associated radio
// button group. Normalized means: if the page started with 2+ radio
// buttons both checked in the same group (an illegal state), the first
// one "wins" and the other is unchecked. We can only do this after all
// the radios have been initialized with their anchor tags in the loop
// above.
for(i = 0; i < hpui_radioButton_self.length; i++){
var hpui_radioButton_self_obj = jQuery(hpui_radioButton_self[i]);
var hpui_radioButton = hpui_radioButton_self_obj.prev('a.hpui-radio');
var name = hpui_radioButton_self_obj.attr('name');
var checked = hpui_radioButton_self_obj.attr('checked');
var radioButtonGroup = getHPUIradios(hpui_radioButton_self, name);
normalizeHPUIradios(hpui_radioButton_self_obj, hpui_radioButton, radioButtonGroup, checked);
}
// Finally, for each radio button element initialized above, setup its
// event handlers based on its normalized initial state. This can only
// be done after the above loop.
for (var i = 0; i < hpui_radioButton_self.length; i++){
var hpui_radioButton_self_obj = jQuery(hpui_radioButton_self[i]);
var hpui_radioButton = hpui_radioButton_self_obj.prev('a.hpui-radio');
var error = hpui_radioButton_self_obj.hasClass('hpui-error');
var name = hpui_radioButton_self_obj.attr('name');
var disabled = hpui_radioButton_self_obj.attr('disabled');
var readonly = hpui_radioButton_self_obj.attr('readonly');
var checked = hpui_radioButton_self_obj.attr('checked');
var radioButtonGroup = getHPUIradios(hpui_radioButton_self, name);
var currentClass = error ? 'hpui-radio hpui-error' : 'hpui-radio';
var currentChecked = checked ? 'checked' : '';
var currentState = readonly ? 'readonly' : 'enable';
currentState = disabled ? 'disable' : currentState;
// Add click event on the label text.
var labelEl = getLabel(hpui_radioButton_self_obj);
if (labelEl) {
labelEl.off('click.hpui-radio');
labelEl.on('click.hpui-radio', {anchor:hpui_radioButton}, function(event) {
event.preventDefault();
event.data.anchor.trigger('click');
});
}
// Register the click event on the anchor. As a click event, this
// propagates to the standard click handler first, and may be
// canceled by the standard handler. It delegates to the standard
// click handler to toggle the radio button state, then syncs the
// CSS class and anchor state with it.
hpui_radioButton.off('click.hpui-radio');
hpui_radioButton.on('click.hpui-radio',
{input:hpui_radioButton_self_obj,
group:radioButtonGroup},
function(event) {
var anchor = jQuery(this);
var input = event.data.input;
var group = event.data.group;
// Do nothing if the radio is disabled or readonly.
if (anchor.attr('disabled') || anchor.attr('readonly'))
return;
// Remember whether to reset the error CSS class - will do that
// only if this button is about to change state (ie is not
// already checked).
var resetError = !input.attr('checked');
// Trigger the native radio button click. Note: In JQuery this does not affect the 'checked'
// attribute, just the internal state.
input.trigger(event);
// If the native handling canceled the event, stop.
if (event.isDefaultPrevented() || event.isPropagationStopped() || event.isImmediatePropagationStopped())
return;
// Now sync CSS class and anchor state with radio state across
// the group.
if (resetError) {
group.prev('a.hpui-radio').removeClass('hpui-error');
group.removeClass('hpui-error');
}
normalizeHPUIradios(input, anchor, group, true);
});
// Register the custom toggle event on the input element.
hpui_radioButton_self_obj.off('hpui-toggle.hpui-radio');
hpui_radioButton_self_obj.on('hpui-toggle.hpui-radio',
{anchor:hpui_radioButton,
group:radioButtonGroup},
function(event, on) {
var anchor = event.data.anchor;
var group = event.data.group;
var input = jQuery(this);
if (on == undefined)
on = input.attr('checked') ? false : true;
// Clear any error class, if any, through the whole group, if a
// checked-state change is occuring.
if ((on && !input.attr('checked')) ||
(!on && input.attr('checked'))) {
group.prev('a.hpui-radio').removeClass('hpui-error');
group.removeClass('hpui-error');
}
// Set unchecked or checked throughout the group.
normalizeHPUIradios(input, anchor, group, on);
});
// Register the custom disable event on the input element.
hpui_radioButton_self_obj.off('hpui-disable.hpui-radio');
hpui_radioButton_self_obj.on('hpui-disable.hpui-radio', function(anchor) {
return function() {
var input = jQuery(this);
anchor.attr('disabled', '').removeAttr('readonly');
input.attr('disabled', '').removeAttr('readonly');
disableLabel(input);
// Finally set screenreading text.
setRadioScreenreaderText(input, anchor);
}
}(hpui_radioButton));
// Register the custom enable event on the input element.
hpui_radioButton_self_obj.off('hpui-enable.hpui-radio');
hpui_radioButton_self_obj.on('hpui-enable.hpui-radio', function(anchor) {
return function() {
var input = jQuery(this);
anchor.removeAttr('disabled').removeAttr('readonly');
input.removeAttr('disabled').removeAttr('readonly');
enableLabel(input);
// Finally set screenreading text.
setRadioScreenreaderText(input, anchor);
}
}(hpui_radioButton));
// Register the custom readonly event on the input element.
hpui_radioButton_self_obj.off('hpui-readonly.hpui-radio');
hpui_radioButton_self_obj.on('hpui-readonly.hpui-radio', function(anchor) {
return function() {
var input = jQuery(this);
anchor.attr('readonly', '').removeAttr('disabled');
input.attr('readonly', '').removeAttr('disabled');
enableLabel(input);
// Finally set screenreading text.
setRadioScreenreaderText(input, anchor);
}
}(hpui_radioButton));
// Register the custom error status event on the input element.
hpui_radioButton_self_obj.off('hpui-error.hpui-radio');
hpui_radioButton_self_obj.on('hpui-error.hpui-radio', function(anchor) {
return function() {
var radio = jQuery(this);
// Set error class in every case.
radio.addClass('hpui-error');
anchor.addClass('hpui-error');
}
}(hpui_radioButton));
// Register the custom OK status event on the input element.
hpui_radioButton_self_obj.off('hpui-ok.hpui-radio');
hpui_radioButton_self_obj.on('hpui-ok.hpui-radio', function(anchor) {
return function() {
var radio = jQuery(this);
// Remove error class in every case.
radio.removeClass('hpui-error');
anchor.removeClass('hpui-error');
}
}(hpui_radioButton));
// Register the custom value event on the input element.
hpui_radioButton_self_obj.off('hpui-value.hpui-radio');
hpui_radioButton_self_obj.on('hpui-value.hpui-radio',
function(event, val) {
var radio = jQuery(this);
// Value event with blank value is same as toggle-off; value
// event with any non-blank value is same as toggle-on.
var on = val;
radio.trigger('hpui-toggle', on);
});
// Register the custom clear event on the input element.
hpui_radioButton_self_obj.off('hpui-clear.hpui-radio');
hpui_radioButton_self_obj.on('hpui-clear.hpui-radio', function() {
var radio = jQuery(this);
// Clear event is same as toggle-off.
radio.trigger('hpui-toggle', false);
});
// Register the custom reset event on the input element.
hpui_radioButton_self_obj.off('hpui-reset.hpui-radio');
hpui_radioButton_self_obj.on('hpui-reset.hpui-radio',
{anchor: hpui_radioButton,
group: radioButtonGroup,
initOn: currentChecked,
initClass: currentClass,
initState: currentState},
function(event, resetOne) {
if (resetOne) {
var input = jQuery(this);
var anchor = event.data.anchor;
// Reset this button's checked/unchecked to initial state
if (event.data.initOn) {
input.attr('checked', 'checked');
anchor.attr('checked', 'checked');
} else {
input.removeAttr('checked');
anchor.removeAttr('checked');
}
// Reset this button's class to initial state
input.removeClass('hpui-error').addClass(event.data.initClass);
anchor.removeClass('hpui-error').addClass(event.data.initClass);
// Reset this button's disabled/readonly to initial state
input.trigger('hpui-' + event.data.initState);
} else {
// Reset all buttons in this radio-button group
event.data.group.each(function() {
jQuery(this).trigger('hpui-reset', true);
});
}
});
// Initialize radio button state (disabled, readonly, enabled,
// checked/unchecked and class) based on current values
hpui_radioButton_self_obj.trigger('hpui-reset', true);
}
}
}
// Initialize forms in the given context.
function initForms(context) {
/* There is a better way to do form reset such that non-HPUI form elements
* will get reset too. Comment this out, and see following code.
*
var allForms = jQuery('form', context);
allForms.off("reset.hpui-form");
allForms.on("reset.hpui-form", function(event) {
event.preventDefault();
resetForm(this);
});
*/
// Register our custom form reset handler.
var allForms = jQuery('form', context);
allForms.off("hpui-form-reset");
allForms.on("hpui-form-reset", function(event) {
var form = this;
// Do standard form reset first.
form.reset();
// Do our custom form reset second.
resetForm(form);
});
// Overload all form reset buttons so that they do standard form reset
// first, then our custom form reset second.
var allResetButtons = jQuery('input[type=reset]', context);
allResetButtons.off("click.hpui-reset");
allResetButtons.on("click.hpui-reset", function(event) {
// First prevent standard reset from triggering afterwards.
event.preventDefault();
// Next, trigger our custom reset event on this reset button's form.
var form = jQuery(this).closest('form');
form.trigger('hpui-form-reset');
});
}
// Enable associated label
function enableLabel(el) {
var labelEl = getLabel(el);
if (labelEl)
labelEl.removeClass("hpui-disabled-text");
}
// Disable associated label
function disableLabel(el) {
var labelEl = getLabel(el);
if (labelEl)
labelEl.addClass("hpui-disabled-text");
}
// Get associated label
function getLabel(obj) {
var label_obj = null;
if (obj) {
var obj_id = obj.attr("id");
if (obj_id) {
label_obj = jQuery("label[for='" + obj_id + "']:not(.hpui-fake)");
}
}
return label_obj;
}
// Get ID attribute or generate one if non-existent
function generateId(obj) {
var obj_id = null;
if (obj) {
obj_id = obj.attr("id");
if (!obj_id) {
obj_id = Math.floor(Math.random()*Math.pow(10,6)); // 6-digit random number
obj.attr("id", obj_id);
}
}
return obj_id;
}
// Set screenreader text for a file input
function setFileScreenreaderText(fileInput, textInput, buttonInput) {
// First empty out the current screenreader text if any.
textInput.prev('span.hpui-screenreader-text').remove();
textInput.prev('span.hpui-screenreader-text').remove();
textInput.prev('span.hpui-screenreader-text').remove();
textInput.prev('label.hpui-label').remove();
// Next copy the label, if any, to screenreader text.
var label = getLabel(fileInput);
var makeNewLabel = generateId(fileInput);
var screenreaderLabelText, screenreaderFileText, screenreaderMessageText;
// Set screenreader text equal to the file input label text.
if (label) {
var labelText = label.text();
if (labelText) {
// Generate a span container for a screen-reading duplicate of the label text, and add it to the DOM.
screenreaderLabelText = jQuery("" + labelText + " ");
textInput.before(screenreaderLabelText);
makeNewLabel = makeNewLabel && true;
}
}
// Add screenreader message from message catalog, if any.
if ((typeof file_screenreader == 'string') && (typeof file_disabled_screenreader == 'string') &&
(typeof file_entered_screenreader == 'function') && (typeof file_hint_screenreader == 'function')) {
var val = textInput.val();
if (val) {
var hint = textInput.next('.hpui-default-text');
if (val != hint.text())
screenreaderFileText = jQuery("" + file_entered_screenreader(val) + " ");
else
screenreaderFileText = jQuery("" + file_hint_screenreader(val) + " ");
textInput.before(screenreaderFileText);
}
if (fileInput.attr('disabled'))
screenreaderMessageText = jQuery("" + file_disabled_screenreader + " ");
else
screenreaderMessageText = jQuery("" + file_screenreader + " ");
textInput.before(screenreaderMessageText);
makeNewLabel = makeNewLabel && true;
}
// Wrap a label tag for the browse button around the screenreader text, if applicable.
if (makeNewLabel) {
var buttonId = fileInput.attr('id') + "_go";
var screenreaderLabel = jQuery(" ");
if (screenreaderLabelText) {
screenreaderLabelText.detach();
screenreaderLabel.append(screenreaderLabelText);
}
if (screenreaderFileText) {
screenreaderFileText.detach();
screenreaderLabel.append(screenreaderFileText);
}
if (screenreaderMessageText) {
screenreaderMessageText.detach();
screenreaderLabel.append(screenreaderMessageText);
}
textInput.before(screenreaderLabel);
buttonInput.attr('id', buttonId);
}
}
// Set screenreader text into a checkbox
function setCheckboxScreenreaderText(input, anchor) {
// First empty out the current screenreader text if any.
anchor.empty();
// Next copy the label, if any, to screenreader text inside the anchor.
var label = getLabel(input);
if (label) {
var labelText = label.text();
if (labelText)
anchor.append("" + labelText + " ");
}
// Next attach the screenreader text for the current state, from the message catalog.
if ((typeof checkbox_on_screenreader == 'string') &&
(typeof checkbox_off_screenreader == 'string') &&
(typeof checkbox_on_disabled_screenreader == 'string') &&
(typeof checkbox_off_disabled_screenreader == 'string') &&
(typeof checkbox_on_readonly_screenreader == 'string') &&
(typeof checkbox_off_readonly_screenreader == 'string')) {
if (input.attr('disabled')) {
if (input.attr('checked'))
anchor.append("" + checkbox_on_disabled_screenreader + " ");
else
anchor.append("" + checkbox_off_disabled_screenreader + " ");
// Trigger generic screenreader text generation as for all disabled anchors.
anchor.trigger('hpui-disable.hpui-link');
} else if (input.attr('readonly')) {
if (input.attr('checked'))
anchor.append("" + checkbox_on_readonly_screenreader + " ");
else
anchor.append("" + checkbox_off_readonly_screenreader + " ");
// Trigger generic screenreader text generation as for all non-disabled anchors.
anchor.trigger('hpui-enable.hpui-link');
} else {
if (input.attr('checked'))
anchor.append("" + checkbox_on_screenreader + " ");
else
anchor.append("" + checkbox_off_screenreader + " ");
// Trigger generic screenreader text generation as for all non-disabled anchors.
anchor.trigger('hpui-enable.hpui-link');
}
}
}
// Set screenreader text into a radio button
function setRadioScreenreaderText(input, anchor) {
// First, empty out the current screenreader text if any.
anchor.empty();
// Next copy the label, if any, to screenreader text inside the anchor.
//check label tag and the label text --- By June
var label = getLabel(input);
if (label) {
var labelText = label.text();
if (labelText)
anchor.append("" + labelText + " ");
}
// Next attach the screenreader text for the current state, from the message catalog.
if ((typeof radio_on_screenreader == 'string') &&
(typeof radio_off_screenreader == 'string') &&
(typeof radio_on_disabled_screenreader == 'string') &&
(typeof radio_off_disabled_screenreader == 'string') &&
(typeof radio_on_readonly_screenreader == 'string') &&
(typeof radio_off_readonly_screenreader == 'string')) {
if (input.attr('disabled')) {
if (input.attr('checked'))
anchor.append("" + radio_on_disabled_screenreader + " ");
else
anchor.append("" + radio_off_disabled_screenreader + " ");
// Trigger generic screenreader text generation as for all disabled anchors.
anchor.trigger('hpui-disable.hpui-link');
} else if (input.attr('readonly')) {
if (input.attr('checked'))
anchor.append("" + radio_on_readonly_screenreader + " ");
else
anchor.append("" + radio_off_readonly_screenreader + " ");
// Trigger generic screenreader text generation as for all non-disabled anchors.
anchor.trigger('hpui-enable.hpui-link');
} else {
if (input.attr('checked'))
anchor.append("" + radio_on_screenreader + " ");
else
anchor.append("" + radio_off_screenreader + " ");
// Trigger generic screenreader text generation as for all non-disabled anchors.
anchor.trigger('hpui-enable.hpui-link');
}
}
}
// Reset HPUI form elements within a given form
function resetForm(form) {
jQuery(
// Normal text inputs
'input[type=text].hpui-input,' +
'input[type=password].hpui-input,' +
// Slim text inputs
'input[type=text].hpui-slim-input,' +
'input[type=password].hpui-slim-input,' +
// Datepickers - already reset as text inputs
// Textareas
'textarea.hpui-textarea,' +
// Checkboxes
'input[type=checkbox].hpui-checkbox,' +
// Radio buttons
'input[type=radio].hpui-radio,' +
// File inputs
'input[type=file].hpui-file,' +
'input[type=file].hpui-slim-file,' +
// Dropdowns
'select.hpui-select,' +
'select.hpui-slim-select,' +
'select.hpui-multi-select,' +
'select.hpui-slim-multi-select,' +
'select.hpui-filter-menu,' +
'select.hpui-sort-menu',
// Find the above within the form and reset each such element
form).each(function() {
jQuery(this).trigger('hpui-reset');
});
}
/****** end HPE form elements JS (form-elements.js) ******/
/****** begin HPE icons JS (icons.js) ******/
/*** "Public" functions - may be used by feature developers ***/
// Add screenreader messages for the given locale into the icons
// within the given context (may be a JQuery Object, a string HTML ID,
// or the whole page by default).
// Note: expand-collapse icons are covered in expand-collapse.js instead.
// Note: shopping-cart icon is covered in shopping-cart.js instead.
function hpuiAddIconResources(context) {
// Get the message resources.
if (typeof(hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// For each preloader icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-small-preloader-icon, div.hpui-small-preloader-icon, span.hpui-small-preloader-icon, ' +
'a.hpui-large-preloader-icon, div.hpui-large-preloader-icon, span.hpui-large-preloader-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_preloader_screenreader == 'string') {
icon.html(''+icon_preloader_screenreader+' ');
}
});
// For each print icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-print-icon, div.hpui-print-icon, span.hpui-print-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_print_screenreader == 'string') {
icon.html(''+icon_print_screenreader+' ');
}
});
// For each share icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-share-icon, div.hpui-share-icon, span.hpui-share-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_share_screenreader == 'string') {
icon.html(''+icon_share_screenreader+' ');
}
});
// For each subscribe icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-subscribe-icon, div.hpui-subscribe-icon, span.hpui-subscribe-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_subscribe_screenreader == 'string') {
icon.html(''+icon_subscribe_screenreader+' ');
}
});
// For each standalone "OK" status icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-standalone-ok-icon, div.hpui-standalone-ok-icon, span.hpui-standalone-ok-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_standalone_OK_screenreader == 'string') {
icon.html(''+icon_standalone_OK_screenreader+' ');
}
});
// For each standalone "error" status icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-standalone-error-icon, div.hpui-standalone-error-icon, span.hpui-standalone-error-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_standalone_error_screenreader == 'string') {
icon.html(''+icon_standalone_error_screenreader+' ');
}
});
// For each info icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-info-icon, div.hpui-info-icon, span.hpui-info-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_info_screenreader == 'string') {
icon.html(''+icon_info_screenreader+' ');
}
});
// For each help icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-help-icon, div.hpui-help-icon, span.hpui-help-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_help_screenreader == 'string') {
icon.html(''+icon_help_screenreader+' ');
}
});
// For each OK icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-ok-icon, div.hpui-ok-icon, span.hpui-ok-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_OK_screenreader == 'string') {
icon.html(''+icon_OK_screenreader+' ');
}
});
// For each unknown icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-unknown-icon, div.hpui-unknown-icon, span.hpui-unknown-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_unknown_screenreader == 'string') {
icon.html(''+icon_unknown_screenreader+' ');
}
});
// For each error icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-error-icon, div.hpui-error-icon, span.hpui-error-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_error_screenreader == 'string') {
icon.html('' + icon_error_screenreader + ' ');
}
});
// For each warning icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-warn-icon, div.hpui-warn-icon, span.hpui-warn-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_warn_screenreader == 'string') {
icon.html('' + icon_warn_screenreader + ' ');
}
});
// For each calendar icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-calendar-icon, div.hpui-calendar-icon, span.hpui-calendar-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_calendar_screenreader == 'string') {
icon.html('' + icon_calendar_screenreader + ' ');
}
});
// For each forum icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-forum-icon, div.hpui-forum-icon, span.hpui-forum-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_forum_screenreader == 'string') {
icon.html('' + icon_forum_screenreader + ' ');
}
});
// For each service icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-service-icon, div.hpui-service-icon, span.hpui-service-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_service_screenreader == 'string') {
icon.html('' + icon_service_screenreader + ' ');
}
});
// For each chat icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-chat-icon, div.hpui-chat-icon, span.hpui-chat-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_chat_screenreader == 'string') {
icon.html('' + icon_chat_screenreader + ' ');
}
});
// For each mail icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-mail-icon, div.hpui-mail-icon, span.hpui-mail-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_mail_screenreader == 'string') {
icon.html('' + icon_mail_screenreader + ' ');
}
});
// For each contact icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-contact-icon, div.hpui-contact-icon, span.hpui-contact-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_contact_screenreader == 'string') {
icon.html('' + icon_contact_screenreader + ' ');
}
});
// For each download icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-download-icon, div.hpui-download-icon, span.hpui-download-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_download_screenreader == 'string') {
icon.html('' + icon_download_screenreader + ' ');
}
});
// For each settings icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-settings-icon, div.hpui-settings-icon, span.hpui-settings-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_settings_screenreader == 'string') {
icon.html('' + icon_settings_screenreader + ' ');
}
});
// For each refresh icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-refresh-icon, div.hpui-refresh-icon, span.hpui-refresh-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_refresh_screenreader == 'string') {
icon.html('' + icon_refresh_screenreader + ' ');
}
});
// For each reports icon set the screenreader message if there is no content exist in it.
jQuery('a.hpui-reports-icon, div.hpui-reports-icon, span.hpui-reports-icon', context).each(function() {
var icon = jQuery(this);
var text = jQuery.trim(icon.text());
var title = jQuery.trim(icon.attr('title'));
if (!text && !title && typeof icon_reports_screenreader == 'string') {
icon.html('' + icon_reports_screenreader + ' ');
}
});
}
/*** "Private" functions not for direct use by feature developers ***/
// Initialize all icons in the given context.
// Note: expand-collapse icons are covered in expand-collapse.js instead.
// Note: shopping-cart icon is covered in shopping-cart.js instead.
function initIcons(context) {
var icons = jQuery('a.hpui-calendar-icon, a.hpui-warn-icon, a.hpui-error-icon, a.hpui-error-icon2, ' +
'a.hpui-ok-icon, a.hpui-unknown-icon, a.hpui-help-icon, a.hpui-info-icon, ' +
'a.hpui-standalone-ok-icon, a.hpui-standalone-error-icon, ' +
'a.hpui-print-icon, a.hpui-share-icon, a.hpui-subscribe-icon, ' +
'a.hpui-small-preloader-icon, a.hpui-large-preloader-icon', context).each(function(index) {
var icon = jQuery(this);
// Insert into the normal tabflow. No need to do this if tab flow or an href
// is set.
if (!icon.attr('tabindex') && !icon.attr('href'))
icon.attr('tabindex', '0');
// Register keypress event handler to trigger click on 'enter', for accessibility.
// No need to do this if an href is set.
if (!icon.attr('href')) {
icon.off('keypress.hpui-icons');
icon.on('keypress.hpui-icons', function(event) {
var link = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
link.trigger('click');
}
});
}
});
}
/****** end HPE icons JS (icons.js) ******/
/****** begin HPE page initialization JS (init.js) ******/
// Note: This file is used for global initialization code only.
/*** "Public" functions ***/
// Just one public function here, hpuiInitialize - takes a JQuery object or an
// HTML ID string, and initializes that element - otherwise assumes document.
function hpuiInitialize(el) {
if (!el || !el.length || (typeof el != 'object') || !(el instanceof jQuery)) {
if (el && typeof el == 'string') {
el = jQuery('#' + el);
} else {
el = document;
}
}
// Pre-initialization of tables
if (typeof(preInitTables) == 'function') preInitTables(el);
// Begin main initialization of all elements
// Localizations for datepickers only (must execute first)
if (typeof(hpuiAddDatepickerResources) == 'function') hpuiAddDatepickerResources();
// Dropdowns
if (typeof(initDropdowns) == 'function') initDropdowns(el);
if (typeof(initStatelessDropdowns) == 'function') initStatelessDropdowns(el);
// Form elements
if (typeof(initTextInputs) == 'function') initTextInputs('hpui-input', el);
if (typeof(initTextInputs) == 'function') initTextInputs('hpui-slim-input', el);
if (typeof(initDatepicker) == 'function') initDatepicker('hpui-datepicker', 'hpui-input', el); // must come after text inputs
if (typeof(initDatepicker) == 'function') initDatepicker('hpui-slim-datepicker', 'hpui-slim-input', el); // must come after text inputs
if (typeof(initTextareas) == 'function') initTextareas(el);
if (typeof(initCheckboxes) == 'function') initCheckboxes(el);
if (typeof(initRadioButtons) == 'function') initRadioButtons(el);
if (typeof(initFileInputs) == 'function') initFileInputs('hpui-file', 'hpui-input', 'hpui-secondary-button', el);
if (typeof(initFileInputs) == 'function') initFileInputs('hpui-slim-file', 'hpui-slim-input', 'hpui-secondary-slim-button', el);
if (typeof(initForms) == 'function') initForms(el);
// Expand-collapse
if (typeof(initExpandCollapse) == 'function') initExpandCollapse(el);
// Lists
if (typeof(initExpandableListButtons) == 'function') initExpandableListButtons(el);
// Icons
if (typeof(initIcons) == 'function') initIcons(el);
// Links
if (typeof(initLinks) == 'function') initLinks(el);
// Dividers
// Typography
// Buttons
if (typeof(initButtons) == 'function') initButtons(el);
// Navigation
if (typeof(initMegaMenus) == 'function') initMegaMenus(el);
// Overlays
if (typeof(initProgressIndicators) == 'function') initProgressIndicators(el);
// Shopping cart
if (typeof(initShoppingCart) == 'function') initShoppingCart(el);
// Tables
if (typeof(initTables) == 'function') initTables(el);
// Localizations (must execute after all other main initialization)
if (typeof(hpuiAddLocalizedResources) == 'function') hpuiAddLocalizedResources(el);
// Post-initialization of tables
if (typeof(postInitTables) == 'function') postInitTables(el);
}
/*** "Private" functions ***/
//Set global variables to defaults for local dev guide (all URL values are paths
//relative to content HTML folders) - only do this if they are not already set:
if (typeof(HPUI_URL) == 'undefined')
var HPUI_URL = "";
if (typeof(HPUI_LOCALE_COOKIE) == 'undefined')
var HPUI_LOCALE_COOKIE = "";
if (typeof(HPUI_LOCALE) == 'undefined')
var HPUI_LOCALE = "";
//Deprecated (but still supported):
if (typeof(HPUI_CSS_URL) == 'undefined')
var HPUI_CSS_URL = "../../css";
if (typeof(HPUI_IMG_URL) == 'undefined')
var HPUI_IMG_URL = "../../images";
if (typeof(HPUI_JS_URL) == 'undefined')
var HPUI_JS_URL = "../../js";
// Function to determine base URL for JS files in the HPUI package.
function determineBaseJsUrl(){
var baseUrl = '/hpui/hpe/js/';
if ((typeof(HPUI_URL) == 'string') && HPUI_URL) {
baseUrl = (HPUI_URL.lastIndexOf('/') == HPUI_URL.length - 1) ? HPUI_URL : HPUI_URL + '/';
baseUrl += "hpui/hpe/js/";
} else if ((typeof(HPUI_JS_URL) == 'string') && HPUI_JS_URL) {
baseUrl = (HPUI_JS_URL.lastIndexOf('/') == HPUI_JS_URL.length - 1) ? HPUI_JS_URL : HPUI_JS_URL + '/';
}
return baseUrl;
}
// Function to determine base URL for CSS files in the HPUI package.
function determineBaseCssUrl(){
var baseUrl = '/hpui/hpe/css/';
if ((typeof(HPUI_URL) == 'string') && HPUI_URL) {
baseUrl = (HPUI_URL.lastIndexOf('/') == HPUI_URL.length - 1) ? HPUI_URL : HPUI_URL + '/';
baseUrl += "hpui/hpe/css/";
} else if ((typeof(HPUI_CSS_URL) == 'string') && HPUI_CSS_URL) {
baseUrl = (HPUI_CSS_URL.lastIndexOf('/') == HPUI_CSS_URL.length - 1) ? HPUI_CSS_URL : HPUI_CSS_URL + '/';
}
return baseUrl;
}
// Function to determine base URL for image files in the HPUI package.
function determineBaseImagesUrl(){
var baseUrl = '/hpui/hpe/images/';
if ((typeof(HPUI_URL) == 'string') && HPUI_URL) {
baseUrl = (HPUI_URL.lastIndexOf('/') == HPUI_URL.length - 1) ? HPUI_URL : HPUI_URL + '/';
baseUrl += "hpui/hpe/images/";
} else if ((typeof(HPUI_IMG_URL) == 'string') && HPUI_IMG_URL) {
baseUrl = (HPUI_IMG_URL.lastIndexOf('/') == HPUI_IMG_URL.length - 1) ? HPUI_IMG_URL : HPUI_IMG_URL + '/';
}
return baseUrl;
}
// Returns the version of Windows Internet Explorer or a -1
// (indicating the use of another browser).
function getInternetExplorerVersion() {
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat( RegExp.$1 );
}
return rv;
}
// Now initialize the whole page on document ready:
jQuery(document).ready(function() {
hpuiInitialize();
});
/****** end HPE page initialization JS (init.js) ******/
/****** begin HPE links JS (links.js) ******/
/*** "Public" functions - may be used by feature developers ***/
// Add screenreader messages for the given locale into the tooltip and help links
// within the given context (may be a JQuery Object, a string HTML ID, or the whole
// page by default).
function hpuiAddLinkResources(context) {
// Get the message resources.
if (typeof(hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// For each tooltip link set, add the screenreader message and title as needed.
jQuery('a.hpui-tooltip-link, a.hpui-standalone-tooltip-link, a.hpui-image-tooltip-link', context).each(function() {
var tooltipLink = jQuery(this);
var tooltipLinkText = jQuery.trim(tooltipLink.text());
var tooltipLinkTitle = jQuery.trim(tooltipLink.attr('title'));
var tooltipLinkScreenreaderText = jQuery.trim(tooltipLink.children("span.hpui-screenreader-text:last").text());
tooltipLinkText = jQuery.trim(tooltipLinkText.replace(tooltipLinkScreenreaderText, ''));
if (typeof tooltip_screenreader == 'string')
if (tooltipLinkScreenreaderText != tooltip_screenreader)
tooltipLink.append(" " + tooltip_screenreader + " ");
if (typeof tooltip_title == 'string')
// Remember, initial generated/default title is a single-space.
// Only set title to message if non-default title not already set, and
// no tooltip link text.
if (!tooltipLinkText && !tooltipLinkTitle && tooltip_title)
tooltipLink.attr('title', tooltip_title);
});
// For each contextual help link set, add the screenreader message and title as needed.
jQuery('a.hpui-help-link, a.hpui-standalone-help-link', context).each(function() {
var helpLink = jQuery(this);
var helpLinkText = jQuery.trim(helpLink.text());
var helpLinkTitle = jQuery.trim(helpLink.attr('title'));
var helpLinkScreenreaderText = jQuery.trim(helpLink.children("span.hpui-screenreader-text:last").text());
helpLinkText = jQuery.trim(helpLinkText.replace(helpLinkScreenreaderText, ''));
if (typeof contextual_help_screenreader == 'string')
if (helpLinkScreenreaderText != contextual_help_screenreader)
helpLink.append(" " + contextual_help_screenreader + " ");
if (typeof contextual_help_title == 'string')
// Only set title to message if non-default title not already set, and
// no help link text.
if (!helpLinkText && !helpLinkTitle)
helpLink.attr('title', contextual_help_title);
});
// For each callout link set, add the screenreader message and title as needed.
jQuery('a.hpui-callout-link, a.hpui-standalone-callout-link', context).each(function() {
var calloutLink = jQuery(this);
var calloutLinkText = jQuery.trim(calloutLink.text());
var calloutLinkTitle = jQuery.trim(calloutLink.attr('title'));
var calloutLinkScreenreaderText = jQuery.trim(calloutLink.children("span.hpui-screenreader-text:last").text());
calloutLinkText = jQuery.trim(calloutLinkText.replace(calloutLinkScreenreaderText, ''));
if (typeof callout_screenreader == 'string')
if (calloutLinkScreenreaderText != callout_screenreader)
calloutLink.append(" " + callout_screenreader + " ");
if (typeof callout_title == 'string')
// Only set title to message if non-default title not already set, and
// no callout link text.
if (!calloutLinkText && !calloutLinkTitle)
calloutLink.attr('title', callout_title);
});
// For each link, update screenreader text as needed.
jQuery('a', context).each(function() {
var link = jQuery(this);
// Update screenreader text based on link status.
setLinkScreenreaderText(link);
});
}
/*** "Private" functions not for direct use by feature developers ***/
function generatingTitle() {
var htmlForTitle = jQuery(this).next().html();
return htmlForTitle;
}
function adjustArrowPosition(el, position, tooltipEl, feedback) {
var pl = position.left;
var pw = tooltipEl.width();
var pr = pl + pw;
var tl = feedback.target.left;
var tw = feedback.target.width;
var tr = tl + tw;
var distance1 = 20;
// The fixed distance between the arrow and left edge or right edge of the
// tooltip.
var arrowWidth = 30;
// The width of the arrow image.
var distance2 = distance1 + arrowWidth / 2;
// Under normal situations, the distance between the tooltip's left edge and
// the anchor's left edge
// should larger than distance2 so that there will be enough space to keep
// the fixed distance between the tooltip's left edge and the arrow image.
// i.e.the arrow image is close to the tooltip's left edge .
// var distance3 = distance1 + arrowWidth;
// Under normal situations, the distance between the tooltip's right edge
// and the anchor's right edge
// should larger than distance3 so that there will be enough space to keep
// the fixed distance between the tooltip's right edge and the arrow image.
// i.e. the arrow image is close to the tooltip's right edge.
if (pl + distance1 < tl) {
// The tooltip's left edge is too far away from the anchor's left edge,
// so the arrow image should be moved right toward.
if (pr < tr) {
// The right of tooltip is smaller than the right of anchor.
if (pr - tl > distance2) {
// Enough space to keep the fixed distance on the right.
el.css('right', distance1 + 'px');
} else {
el.css('right', 0 + 'px');
// Display the arrow on very right against the tooltip.
}
} else {
if (pr - tl > distance2 && pr - tr < distance1) {
// Enough space to keep the fixed distance on the right.
el.css('right', distance1 + 'px');
} else {
el.css('left', tw / 2 + tl - pl - arrowWidth / 2 + 'px');
// Display the arrow on the middle of the anchor.
}
}
} else {
if (tr - pl > distance2) {
el.css('left', distance1 + 'px');
// Enough space to keep the fixed distance on the left.
} else {
el.css('left', 0 + 'px');
// Display the arrow on the very left against the tooltip.
}
}
}
// Set a link into the disabled state.
function disableLink(anchor) {
// Save-off and remove any href or onclick so nothing will happen when the link is activated.
if (anchor.attr('onclick')) {
anchor.data('onclick', anchor.attr('onclick'));
anchor.removeAttr('onclick');
}
if (anchor.attr('href')) {
anchor.data('href', anchor.attr('href'));
anchor.removeAttr('href');
}
// Save any tabbable tabindex, then set tabindex so the link will be not tabbable.
if (anchor.attr('tabindex') !== '-1')
if (anchor.attr('tabindex') || anchor.attr('tabindex') === '0')
anchor.data('tabindex', anchor.attr('tabindex'));
anchor.attr('tabindex', '-1');
// Set disabled attr so correct CSS style will be selected.
anchor.attr('disabled', '');
// Append 'disabled' screenreading message to the end of the link text.
setLinkScreenreaderText(anchor);
}
// Set a link into the enabled state.
function enableLink(anchor) {
// Restore any href or onclick so it takes effect when the link is activated.
if (anchor.data('onclick'))
anchor.attr('onclick', anchor.data('onclick'));
if (anchor.data('href'))
anchor.attr('href', anchor.data('href'));
// Remove any non-tabbable tabindex, then restore any tabindex that had been saved.
if (anchor.attr('tabindex') === '-1')
anchor.removeAttr('tabindex');
if (anchor.data('tabindex') !== '-1')
if (anchor.data('tabindex') || anchor.data('tabindex') === '0')
anchor.attr('tabindex', anchor.data('tabindex'));
// Remove disabled attr so correct CSS style will be selected.
anchor.removeAttr('disabled');
// Remove 'disabled' screenreading message from the end of the link text.
setLinkScreenreaderText(anchor);
}
// Initialize all links in the given context.
function initLinks(context) {
// Initialization for each image tooltip links in image tag
// (must do this before all generic link initialization):
var imageTooltipLinks = jQuery('img.hpui-tooltip-link', context).each(function(index) {
var tooltipEl = jQuery(this);
// If there is no anchor of class="hpui-image-tooltip-link" which is parent of the img,
// create the anchor with class="hpui-image-tooltip-link" and enclose the img inside the anchor
// and insert the anchor into the DOM where the img was.
var anchor = tooltipEl.parent('a');
if (!anchor || !anchor.length) {
anchor = jQuery(' ');
tooltipEl.wrap(anchor);
} else {
anchor.addClass('hpui-image-tooltip-link');
}
tooltipEl.removeClass("hpui-tooltip-link");
});
// Ensure all disabled links are made non-clickable and support event handlers
// to set disabled/enabled.
var allLinks = jQuery('a', context);
allLinks.off('click.hpui-link');
allLinks.on('click.hpui-link', function(event) {
var anchor = jQuery(this);
// Check disabled attr and do nothing if set.
if (anchor.attr('disabled')) {
event.stopImmediatePropagation();
event.preventDefault();
}
});
allLinks.off('hpui-disable.hpui-link');
allLinks.on('hpui-disable.hpui-link', function(event) {
disableLink(jQuery(this));
});
allLinks.off('hpui-enable.hpui-link');
allLinks.on('hpui-enable.hpui-link', function(event) {
enableLink(jQuery(this));
});
// Ensure all onclick links are in the tab flow by default and open on
// 'enter' key.
var onclickLinks = jQuery('a[onclick]', context).each(function(index) {
var anchor = jQuery(this);
// Insert into the normal tabflow. No need to do this if tab flow or an href
// is set.
if (!anchor.attr('tabindex') && !anchor.attr('href'))
anchor.attr('tabindex', '0');
// Register keypress event handler to trigger click on 'enter', for accessibility.
// No need to do this if an href is set.
if (!anchor.attr('href')) {
anchor.off('keypress.hpui-link');
anchor.on('keypress.hpui-link', function(event) {
var link = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
link.trigger('click');
event.stopImmediatePropagation();
event.preventDefault();
}
});
}
});
// Initialization for each inline and standalone contextual help link:
var helpLinks = jQuery('a.hpui-help-link,a.hpui-standalone-help-link', context).each(function(index) {
var helpEl = jQuery(this);
if (!jQuery.trim(helpEl.attr('title')))
// Add title to the element otherwise it doesn't work under IE.
// Empty title is sufficient; per U/E no need for shopping cart links to have title text anymore.
helpEl.attr('title', '');
// Insert the link into normal tabflow by default.
if (!helpEl.attr('tabindex') && !helpEl.attr('href'))
helpEl.attr('tabindex', '0');
// Register click event handler to open the contextual help layer.
helpEl.off('click.hpui-help');
helpEl.on('click.hpui-help', function(event) {
var link = jQuery(this);
var target = link.attr('data-id');
if (target) {
if (typeof(hpuiOpenContextualHelp) == 'function') hpuiOpenContextualHelp(jQuery('#' + target), link, event);
}
});
// Register keypress event handler to do likewise on 'enter', for accessibility.
helpEl.off('keypress.hpui-help');
helpEl.on('keypress.hpui-help', function(event) {
var link = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
link.trigger('click');
event.stopImmediatePropagation();
event.preventDefault();
}
});
});
// Initialization for each inline and standalone callout link:
var calloutLinks = jQuery('a.hpui-callout-link,a.hpui-standalone-callout-link', context).each(function(index) {
var calloutLink = jQuery(this);
var calloutEl = jQuery('#' + calloutLink.attr('data-id'));
if (!jQuery.trim(calloutLink.attr('title')))
// Add title to the element otherwise it doesn't work under IE.
// Empty title is sufficient; per U/E no need for shopping cart links to have title text anymore.
calloutLink.attr('title', '');
// Insert the link into normal tabflow by default.
if (!calloutLink.attr('tabindex') && !calloutLink.attr('href'))
calloutLink.attr('tabindex', '0');
// Register hover event handlers to open/close the callout layer.
calloutLink.off('mouseenter.hpui-callout-link');
calloutLink.on('mouseenter.hpui-callout-link', function(event) {
if (typeof(hpuiOpenCallout) == 'function') hpuiOpenCallout(calloutEl, calloutLink, event);
});
var closeDialog;
calloutLink.off('mouseleave.hpui-callout-link');
calloutLink.on('mouseleave.hpui-callout-link', function(event) {
closeDialog = setTimeout(function() {
calloutEl.dialog("close");
}, 1000);
});
calloutEl.off('mouseenter.hpui-callout');
calloutEl.on('mouseenter.hpui-callout', function(event) {
clearTimeout(closeDialog);
});
calloutEl.off('mouseleave.hpui-callout');
calloutEl.on('mouseleave.hpui-callout', function(event) {
// workaround problem in FF where mouseleave event sometimes fires
// immediately after mouseenter by delaying closure for 0.2 sec
//calloutEl.dialog("close");
closeDialog = setTimeout(function() {
calloutEl.dialog("close");
}, 200);
});
calloutEl.children().off('focusout.hpui-callout');
calloutEl.children().on('focusout.hpui-callout', function(event) {
closeDialog = setTimeout(function() {
calloutEl.dialog("close");
}, 1000);
});
calloutEl.children().off('focusin.hpui-callout');
calloutEl.children().on('focusin.hpui-callout', function(event) {
clearTimeout(closeDialog);
});
// Register keypress event handler to do likewise on 'enter', for accessibility.
calloutLink.off('keypress.hpui-callout-link');
calloutLink.on('keypress.hpui-callout-link', function(event) {
var link = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
link.trigger('mouseenter');
event.stopImmediatePropagation();
event.preventDefault();
}
});
});
// Initialization for each image tooltip links in anchor:
var aImageTooltipLinks = jQuery('a.hpui-image-tooltip-link',context).each(function(index) {
var tooltipEl = jQuery(this);
var tooltipDisabled = tooltipEl.attr('disabled');
var tooltipTitle = jQuery.trim(tooltipEl.attr('title'));
var image = tooltipEl.find('img');
var imgAlt = image.attr('alt');
var imgTitle = jQuery.trim(image.attr('title'));
var imgSrc = image.attr('src');
// If the anchor has no title: if there is an img title, set the anchor title to the img title.
// In any case, remove the title from the img.
if (!tooltipTitle && imgTitle) {
tooltipEl.attr('title', imgTitle);
tooltipTitle = imgTitle;
}
image.removeAttr('title');
// If blank title and not disabled, then set title to space because otherwise
// JQuery UI Tooltip does not work in IE or Firefox.
if (!tooltipTitle && !tooltipDisabled)
tooltipEl.attr('title', ' ');
// Set disable/enable event handlers to keep title up-to-date.
tooltipEl.off('hpui-disable.hpui-tooltip-link');
tooltipEl.on('hpui-disable.hpui-tooltip-link', function(event) {
var anchor = jQuery(this);
if (!jQuery.trim(anchor.attr('title')))
anchor.removeAttr('title');
});
tooltipEl.off('hpui-enable.hpui-tooltip-link');
tooltipEl.on('hpui-enable.hpui-tooltip-link', function(event) {
var anchor = jQuery(this);
if (!jQuery.trim(anchor.attr('title')))
anchor.attr('title', ' ');
});
// If the anchor has no href, set the anchor tabindex attribute to "0".
if (!tooltipEl.attr('href')) {
if (!tooltipEl.attr('tabindex')) {
tooltipEl.attr('tabindex', '0');
}
}
// Initialize the JQuery UI tooltip construct.
tooltipEl.tooltip({
content: generatingTitle,
track: true,
position: {
my: "left-35 bottom-10",
at: "center-2 top",
collisionPosition:"flip",
using: function(position, feedback) {
jQuery(this).css(position);
if (feedback.vertical == 'bottom') {
jQuery(this).children('.hpui-arrow-bottom, .hpui-arrow-top').remove();
adjustArrowPosition(jQuery("").addClass("hpui-arrow-bottom").appendTo(this),
position, jQuery(this), feedback);
} else if (feedback.vertical == 'top') {
jQuery(this).children('.hpui-arrow-bottom, .hpui-arrow-top').remove();
adjustArrowPosition(jQuery("
").addClass("hpui-arrow-top").appendTo(this),
position, jQuery(this), feedback);
}
}
}
})
});
// Initialization for each inline tooltip links:
var tooltipLinks = jQuery('a.hpui-tooltip-link', context).each(function(index) {
var tooltipEl = jQuery(this);
var tooltipDisabled = tooltipEl.attr('disabled');
var tooltipTitle = jQuery.trim(tooltipEl.attr('title'));
// Insert the link into normal tabflow by default.
if (!tooltipEl.attr('tabindex') && !tooltipEl.attr('href'))
tooltipEl.attr('tabindex', '0');
// If blank title and not disabled, then set title to space because otherwise
// JQuery UI Tooltip does not work in IE or Firefox.
if (!tooltipTitle && !tooltipDisabled)
tooltipEl.attr('title', ' ');
// Set disable/enable event handlers to keep title up-to-date.
tooltipEl.off('hpui-disable.hpui-tooltip-link');
tooltipEl.on('hpui-disable.hpui-tooltip-link', function(event) {
var anchor = jQuery(this);
// Note: hpui-disable.hpui-link event handler will have executed first.
if (!jQuery.trim(anchor.attr('title')))
anchor.removeAttr('title');
});
tooltipEl.off('hpui-enable.hpui-tooltip-link');
tooltipEl.on('hpui-enable.hpui-tooltip-link', function(event) {
var anchor = jQuery(this);
// Note: hpui-disable.hpui-link event handler will have executed first.
if (!jQuery.trim(anchor.attr('title')))
anchor.attr('title', ' ');
});
// Initialize the tooltip.
tooltipEl.tooltip({
content: generatingTitle,
position: {
my: "left-35 bottom-10",
at: "center-2 top",
collisionPosition:"flip",
using: function(position, feedback) {
jQuery(this).css(position);
if (feedback.vertical == 'bottom') {
adjustArrowPosition(jQuery("
").addClass("hpui-arrow-bottom").appendTo(this),
position, jQuery(this), feedback);
} else if (feedback.vertical == 'top') {
adjustArrowPosition(jQuery("
").addClass("hpui-arrow-top").appendTo(this),
position, jQuery(this), feedback);
}
}
}
});
})
// Initialization for each standalone tooltip link:
var sTooltipLinks = jQuery('a.hpui-standalone-tooltip-link', context).each(function(index) {
var tooltipEl = jQuery(this);
var tooltipDisabled = tooltipEl.attr('disabled');
var tooltipTitle = jQuery.trim(tooltipEl.attr('title'));
// Insert the link into normal tabflow by default.
if (!tooltipEl.attr('tabindex') && !tooltipEl.attr('href'))
tooltipEl.attr('tabindex', '0');
// If blank title and not disabled, then set title to space because otherwise
// JQuery UI Tooltip does not work in IE or Firefox.
if (!tooltipTitle && !tooltipDisabled)
tooltipEl.attr('title', ' ');
// Set disable/enable event handlers to keep title up-to-date.
tooltipEl.off('hpui-disable.hpui-tooltip-link');
tooltipEl.on('hpui-disable.hpui-tooltip-link', function(event) {
var anchor = jQuery(this);
// Note: hpui-disable.hpui-link event handler will have executed first.
if (!jQuery.trim(anchor.attr('title')))
anchor.removeAttr('title');
});
tooltipEl.off('hpui-enable.hpui-tooltip-link');
tooltipEl.on('hpui-enable.hpui-tooltip-link', function(event) {
var anchor = jQuery(this);
// Note: hpui-disable.hpui-link event handler will have executed first.
if (!jQuery.trim(anchor.attr('title')))
anchor.attr('title', ' ');
});
// Initialize the tooltip.
tooltipEl.tooltip({
content : generatingTitle,
position : {
my : "center1 bottom-10",
at: "right-45 top",
collisionPosition:'flip',
using : function(position, feedback) {
jQuery(this).css(position);
if (feedback.vertical == 'bottom') {
adjustArrowPosition(jQuery("
").addClass("hpui-arrow-bottom").appendTo(this),
position, jQuery(this), feedback);
} else if (feedback.vertical == 'top') {
adjustArrowPosition(jQuery("
").addClass("hpui-arrow-top").appendTo(this),
position, jQuery(this), feedback);
}
}
}
});
});
// Finally, ensure all disabled links are set disabled. This must come last, after the above
// steps have had a chance to initialize the tabindex when needed.
var allDisabledLinks = jQuery('a[disabled]', context);
allDisabledLinks.each(function() {
disableLink(jQuery(this));
});
}
// Add the 'disabled' screenreader message to a disabled link, or
// remove it from an enabled link.
function setLinkScreenreaderText(link) {
var disabled = link.attr('disabled');
var linkScreenreaders = link.children("span.hpui-screenreader-text");
if (typeof link_disabled_screenreader != 'string')
return;
if (disabled) {
var already = false;
linkScreenreaders.each(function() {
var linkScreenreader = jQuery(this);
var linkScreenreaderText = linkScreenreader.text();
if (linkScreenreaderText == link_disabled_screenreader)
already = true;
});
if (!already)
link.append("
" + link_disabled_screenreader + " ");
} else {
linkScreenreaders.each(function() {
var linkScreenreader = jQuery(this);
var linkScreenreaderText = linkScreenreader.text();
if (linkScreenreaderText == link_disabled_screenreader)
linkScreenreader.remove();
});
}
}
/****** end HPE links JS (links.js) ******/
/****** begin HPE lists JS (lists.js) ******/
/*** "Public" functions - may be used by feature developers ***/
/*** "Private" functions not for direct use by feature developers ***/
function addExpandCollapseButton(listItem) {
var icon = listItem.children('a.hpui-expand-icon,a.hpui-collapse-icon');
var listContent = listItem.children('div.hpui-content');
if (listContent && listContent.length &&
(listItem.hasClass('hpui-expanded-section') ||
listItem.hasClass('hpui-collapsed-section'))) {
listItem.css("padding-left", "0px");
if (!icon || !icon.length) {
if (listItem.hasClass("hpui-expanded-section")) {
listItem.prepend("
");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(listItem);
listItem.find("div.hpui-content").first().slideToggle(500);
} else {
listItem.prepend("
");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(listItem);
}
}
}
}
function addContentWrapperDiv(content) {
var contents = content.children();
if (contents.length == 1) {
if ((contents.prop("tagName") == "OL") || (contents.prop("tagName") == "UL"))
if (contents.first().hasClass("hpui-expandable-list"))
return;
if ((contents.prop("tagName") == "DIV"))
return;
}
var original = content.html();
content.empty();
content.append("
" + original + "
");
}
function doExpandCollapse(icon) {
icon.nextAll("div.hpui-content").first().slideToggle(500);
if (icon.hasClass("hpui-expand-icon"))
icon.removeClass("hpui-expand-icon").addClass("hpui-collapse-icon");
else
icon.removeClass("hpui-collapse-icon").addClass("hpui-expand-icon");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(icon.parent());
}
// Initialize expand/collapse lists in the given context.
function initExpandableListButtons(context){
// Add the button icons automatically. Must do this re-entrantly in case
// this code reloads (eg from user navigating back).
jQuery("ol.hpui-expandable-list li,ul.hpui-expandable-list li", context).each(function() {
addExpandCollapseButton(jQuery(this));
});
// Add the content wrapper div automatically. Must do this re-entrantly in
// case this code reloads (eg from user navigating back).
jQuery("ol.hpui-expandable-list li div.hpui-content," +
"ul.hpui-expandable-list li div.hpui-content", context).each(function() {
addContentWrapperDiv(jQuery(this));
});
// Register the button click handler. Must do this re-entrantly in case this
// code reloads (eg from user navigating back). Also, register keypress
// handler for 'enter' key to trigger click handler on the buttons.
var buttons = jQuery('ol.hpui-expandable-list li a.hpui-expand-icon,' +
'ol.hpui-expandable-list li a.hpui-collapse-icon,' +
'ul.hpui-expandable-list li a.hpui-expand-icon,' +
'ul.hpui-expandable-list li a.hpui-collapse-icon', context);
buttons.off('click.hpui-expandable-list');
buttons.on('click.hpui-expandable-list', function() {
doExpandCollapse(jQuery(this));
});
/*
buttons.off('keypress.hpui-expandable-list');
buttons.on('keypress.hpui-expandable-list', function(event) {
var icon = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
icon.trigger('click');
}
});
*/
}
/****** end HPE lists JS (lists.js) ******/
/****** begin HPE messages JS (messages.js) ******/
/*** "Public" functions - may be used by feature developers ***/
// This hash maps lowercase locales (format ll eg "fr" or ll-cc, eg "zh-tw") to
// Java locale tags (format ll eg "fr" or ll_CC, eg "zh_TW") of provided message
// bundles.
var HPUI_LOCALES_TO_MESSAGES = {
'zh-hk':'zh_HK',
'zh-tw':'zh_TW',
'cs': 'cs',
'de': 'de',
'el': 'el',
'es': 'es',
'fr': 'fr',
'hu': 'hu',
'it': 'it',
'ja': 'ja',
'ko': 'ko',
'pl': 'pl',
'pt': 'pt',
'ru': 'ru',
'tr': 'tr',
'zh': 'zh'
};
// General purpose method for including messages from the message catalog.
// Does not do anything with them; just defines them.
function hpuiAddMessageResources() {
// First determine the locale being requested: either the HPUI_LOCALE or the
// value of the HPUI_LOCALE_COOKIE or English by default. From init.js.
var requestedLocale = typeof (determineLocale) == 'function' ? determineLocale() : "en";
// From the locale being requested, determine the locale to actually use.
var localeToUse = "";
var requestedLanguage = requestedLocale;
if (requestedLocale.length > 2)
requestedLanguage = requestedLocale.substring(0, 2);
if (HPUI_LOCALES_TO_MESSAGES[requestedLocale.toLowerCase()])
// We will use the full locale if it is supported
localeToUse = HPUI_LOCALES_TO_MESSAGES[requestedLocale.toLowerCase()];
else if (HPUI_LOCALES_TO_MESSAGES[requestedLanguage.toLowerCase()])
// Else we will use the language if it is supported
localeToUse = HPUI_LOCALES_TO_MESSAGES[requestedLanguage.toLowerCase()];
else
// Else we will use English if neither full locale nor language are supported
localeToUse = "en";
// No need to proceed if locale has already been loaded.
if (loadedMessagesForLocale == localeToUse)
return;
// Instantiate the message properties. Each message property
// will be allocated in a variable or function of the same name
// when this returns. HPUI_URL and HPUI_JS_URL are alternative
// global variables for the root URL to the JS folder. From init.js.
var baseUrl = typeof (determineBaseJsUrl) == 'function' ? determineBaseJsUrl() : "";
if (typeof(jQuery.i18n.properties) == 'function') {
jQuery.i18n.properties({
name: 'messages',
language: localeToUse,
// cache: true, // does not work :-(
path: baseUrl + 'messages/i18n/'
});
}
loadedMessagesForLocale = localeToUse;
}
// Gets the localized messages (eg for screenreader) from the message catalog and
// rewrites them into all other widgets in the given context (page by default)
// where screenreader text may be required: tabs, links, icons, etc.
function hpuiAddLocalizedResources(context) {
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// Rewrite the localizations into the given context.
if (typeof(hpuiAddBasicDatepickerResources) == 'function') hpuiAddBasicDatepickerResources(context);
if (typeof(hpuiAddExpandCollapseResources) == 'function') hpuiAddExpandCollapseResources(context);
if (typeof(hpuiAddFormResources) == 'function') hpuiAddFormResources(context);
if (typeof(hpuiAddLinkResources) == 'function') hpuiAddLinkResources(context);
if (typeof(hpuiAddIconResources) == 'function') hpuiAddIconResources(context); // must come after links
if (typeof(hpuiAddTabResources) == 'function') hpuiAddTabResources(context);
if (typeof(hpuiAddShoppingCartResources) == 'function') hpuiAddShoppingCartResources(context);
if (typeof(hpuiAddDropdownResources) == 'function') hpuiAddDropdownResources(context);
}
/*** "Private" functions not for direct use by feature developers ***/
// Global variable for tracking message resources already loaded on this page.
// Needed because JQuery I18n properties plugin 'cache' property does not work.
var loadedMessagesForLocale = "";
// Determine locale to use.
function determineLocale() {
var requestedLocale = "";
if (typeof(HPUI_LOCALE) == 'string')
requestedLocale = HPUI_LOCALE;
if (!requestedLocale &&
(typeof(HPUI_LOCALE_COOKIE) == 'string') &&
(typeof(jQuery.cookie) == 'function') &&
HPUI_LOCALE_COOKIE)
requestedLocale = jQuery.cookie(HPUI_LOCALE_COOKIE);
if (!requestedLocale)
requestedLocale = "en";
return requestedLocale;
}
/****** end HPE messages JS (messages.js) ******/
/****** begin HPE navigations JS (navigations.js) ******/
/** * "Public" functions - may be used by feature developers ** */
// Add screenreader messages for the given locale into the tabs within the given
// context (may be a JQuery Object, a string HTML ID, or the whole page by
// default).
function hpuiAddTabResources(context) {
// Get the message resources.
if (typeof (hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object')
|| !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// For each tab set, add the screenreader message if not already set.
jQuery('div.hpui-tabs > ul > li > a', context).each(
function() {
var tabAnchor = jQuery(this);
var screenreaderText = tabAnchor.children(
"span.hpui-screenreader-text:last").text();
if ((typeof tabs_screenreader == 'string')
&& (screenreaderText != tabs_screenreader))
tabAnchor.append("
"
+ tabs_screenreader + " ");
});
}
// Initialize one tab set, using JQuery UI Tabs plus some enhancements for
// URLs in tab links and better sizing of tab width.
function hpuiTabs(options) {
// Make sure we got table options.
if (!options || !options.id)
return;
var tabsID = options.id;
// Select the tab set for the given ID - return immediately unless one and only one is found.
var tabDiv = jQuery("div.hpui-tabs#" + tabsID);
if (tabDiv && tabDiv.length == 1) {
// Remove id option to as it would be unrecognized by JQuery.
delete options.id;
// Make sure tabs marked disabled have not also been made active.
if (jQuery.inArray(options.active, options.disabled) > -1) {
delete options.active;
}
var tabUL = tabDiv.find("ul:first");
tabUL.find("li > a").each(function() {
var tabAnchor = jQuery(this);
var tabID = getTabID(tabAnchor);
// When there is no tab ID on this tab heading, generate one and assign to the heading.
if (!tabID) {
tabID = Math.floor(Math.random()*Math.pow(10,6)); // Randomly generate a length 6 integer.
tabAnchor.attr("href", "#" + tabID);
}
// When there is no tab content div for this tab heading, generate one after the headings.
var tabContentPanel = jQuery("div#" + tabID);
if (!tabContentPanel || tabContentPanel.length == 0) {
tabUL.after("
");
}
});
// Augment the given options with 'beforeActivate' option which makes the tabs linkable to a URL.
options.beforeActivate = function(event, ui) {
var tabNewHref = ui.newTab.children('a:first').attr('href');
var tabNewRel = ui.newTab.children('a:first').attr('rel');
if (tabNewRel) {
location.href = tabNewRel;
} else {
location.href = tabNewHref;
}
ui.newTab.focus();
};
// Initialize JQuery UI Tabs with the options.
tabDiv.tabs(options);
// JQuery UI Tabs uses fixed-width tabs that wrap poorly within a constrained width. So
// resize the tabs to fit within one line instead.
resizeTabs(tabDiv);
}
}
/** * "Private" functions not for direct use by feature developers ** */
function resizeTabs(tabDiv) {
var tabUl = tabDiv.children("ul");
var tabLi = tabUl.children("li");
var tabAnchor = tabLi.children("a");
var tabLiNumber = tabLi.length;
var tabLiTextArray = new Array();
//Get font style from tab.
var tabLiFontSize = tabAnchor.css("font-size");
var tabLiFontWeight = tabAnchor.css("font-weight");
var tabLiLineHeight = tabAnchor.css("line-height");
var tabLiFloat = tabAnchor.css("float");
var tabAnchorPaddingTop = tabAnchor.css("padding-top");
var tabAnchorPaddingRight = tabAnchor.css("padding-right");
var tabLiSumWidth = 0;
//According tab to create a table.
var tableID = Math.floor(Math.random()*Math.pow(10,6));
var tableDivId = Math.floor(Math.random()*Math.pow(10,6));
jQuery(window).on("load" , function(){
for(var i = 0; i < tabLiNumber; i++){
var tabLiEveText = tabLi.eq(i).children("a").html();
tabLiTextArray.push(tabLiEveText);
var tabLiWidth = tabLi.eq(i).outerWidth(true);
tabLiSumWidth += tabLiWidth;
}
// When the table need wrap line of text, set the table width to 1px to reduce the space between every td,
// otherwise set table width for the width of div which is outer of tabs.
var tableWidth = 1;
if(tabLiSumWidth <= tabDiv.width()){
tableWidth = tabDiv.width();
}
tabDiv.append("
"+"
");
jQuery("#"+tableDivId).append("
");
var table = jQuery("#"+tableID);
var tableTr = table.find("tr");
for(var i=0; i
"+tabLiText+"");
}
var tableTd = tableTr.find("td");
var tableTdHeight = tableTd.outerHeight();
if( tabUl.width() < tableTr.width()) {
tabUl.css("width" , tableTr.width());
}
for (var i = 0; i < tabLiNumber; i++) {
var tableTdWidth = tableTd.eq(i).outerWidth();
if (tableTdHeight >= 2*(parseInt(tabLiFontSize) + parseInt(tabAnchorPaddingTop))) {
tabLi.eq(i).children("a").css("white-space", "pre-wrap");
}
tabLi.eq(i).css("width" , tableTdWidth-1);
tabLi.eq(i).css("height" , tableTdHeight);
}
table.css("display", "none");
});
}
// Return the tab ID given a tab heading anchor.
function getTabID(tabAnchor) {
var tabID = tabAnchor.attr("href");
if (tabID) {
if (tabID.indexOf("#") == 0) {
if (tabID.length > 1)
tabID = tabID.substring(1);
else
tabID = "";
}
} else {
tabID = "";
}
return tabID;
}
/** **** end HPE navigations JS (navigations.js) ***** */
/****** begin HPE overlays JS (overlays.js) ******/
/*** "Public" functions for use by feature developers ***/
// Positioning function for contextual help overlay when opened.
function hpuiOpenContextualHelp(contextualHelpDialog, contextualHelpLink, event) {
// Make sure we got passed JQuery objects; return short otherwise.
if (!contextualHelpDialog || !contextualHelpDialog.length ||
(typeof contextualHelpDialog != 'object') ||
!(contextualHelpDialog instanceof jQuery) ||
!(contextualHelpDialog.is(':data(dialog)')))
return;
if (!contextualHelpLink || !contextualHelpLink.length ||
(typeof contextualHelpLink != 'object') ||
!(contextualHelpLink instanceof jQuery))
return;
// Calculate and set the contextual help overlay position.
var offset = contextualHelpLink.offset();
var dialog_position_x = (offset.left - jQuery(window).scrollLeft()) > jQuery(window).width()/2;
var dialog_position_y = (offset.top - jQuery(window).scrollTop()) > jQuery(window).height()/2;
if (dialog_position_y) {
if (dialog_position_x) {
contextualHelpDialog.dialog( "option", "position", { my: "right bottom", at: "right bottom", of: contextualHelpLink, offset: "-50% -90%" } );
} else {
contextualHelpDialog.dialog( "option", "position", { my: "left bottom", at: "left bottom", of: contextualHelpLink, offset: "50% -90%" } );
}
} else {
if (dialog_position_x){
contextualHelpDialog.dialog( "option", "position", { my: "right top", at: "right top", of: contextualHelpLink, offset: "-50% 90%" } );
} else {
contextualHelpDialog.dialog( "option", "position", { my: "left top", at: "left top", of: contextualHelpLink, offset: "50% 90%" } );
}
}
// Show the contextual help overlay.
contextualHelpDialog.dialog( "open" );
// Cancel event propagation if we were passed a trigger event for the open.
if (event) {
event.stopImmediatePropagation();
event.preventDefault();
}
}
// Positioning function for callout overlay when opened.
function hpuiOpenCallout(calloutDialog, calloutLink, event) {
// Make sure we got passed JQuery objects; return short otherwise.
if (!calloutDialog || !calloutDialog.length ||
(typeof calloutDialog != 'object') ||
!(calloutDialog instanceof jQuery) ||
!(calloutDialog.is(':data(dialog)')))
return;
if (!calloutLink || !calloutLink.length ||
(typeof calloutLink != 'object') ||
!(calloutLink instanceof jQuery))
return;
// Calculate and set the callout overlay position.
var offset = calloutLink.offset();
var dialog_position_x = (offset.left - jQuery(window).scrollLeft()) > jQuery(window).width()/2;
var dialog_position_y = (offset.top - jQuery(window).scrollTop()) > jQuery(window).height()/2;
// Remove the previously appended arrows
calloutDialog.children("div.hpui-arrow-bottom, div.hpui-arrow-top, div.hpui-mini-shopping-cart-arrow-bottom, div.hpui-mini-shopping-cart-arrow-top").remove();
if (dialog_position_y) {
if (dialog_position_x) {
calloutDialog.append("
");
calloutDialog.dialog( "option", "position", { my: "right bottom", at: "right bottom", of: calloutLink, offset: "-25% -145%" } );
} else {
calloutDialog.append("
");
calloutDialog.dialog( "option", "position", { my: "left bottom", at: "left bottom", of: calloutLink, offset: "25% -145%" } );
}
} else {
if (dialog_position_x){
calloutDialog.append("
");
calloutDialog.dialog( "option", "position", { my: "right top", at: "right top", of: calloutLink, offset: "-25% 145%" } );
} else {
calloutDialog.append("
");
calloutDialog.dialog( "option", "position", { my: "left top", at: "left top", of: calloutLink, offset: "25% 145%" } );
}
}
// Show the callout overlay.
calloutDialog.dialog( "open" );
// Cancel event propagation if we were passed a trigger event for the open.
if (event) {
event.stopImmediatePropagation();
event.preventDefault();
}
}
// Positioning function for alert overlay when opened.
function hpuiOpenAlert(alertDialog, container, event) {
// Make sure we got passed a JQuery dialog; return short otherwise.
if (!alertDialog || !alertDialog.length ||
(typeof alertDialog != 'object') ||
!(alertDialog instanceof jQuery) ||
!(alertDialog.is(':data(dialog)')))
return;
// Make sure the container is a DOM element or window; return short otherwise.
if (!container || !(container.nodeType || container == window))
return;
// Center the alert overlay in the given container and show it.
alertDialog.dialog( "option", "position", { my: "center center", at: "center center", of: container } );
alertDialog.dialog( "open" );
// Cancel event propagation if we were passed a trigger event for the open.
if (event) {
event.stopImmediatePropagation();
event.preventDefault();
}
}
// Positioning function for dialog overlay when opened.
function hpuiOpenDialog(dialogDialog, container, event) {
// Make sure we got passed a JQuery dialog; return short otherwise.
if (!dialogDialog || !dialogDialog.length ||
(typeof dialogDialog != 'object') ||
!(dialogDialog instanceof jQuery) ||
!(dialogDialog.is(':data(dialog)')))
return;
// Make sure the container is a DOM element or window; return short otherwise.
if (!container || !(container.nodeType || container == window))
return;
// Center the dialog overlay in the given container and show it.
dialogDialog.dialog( "option", "position", { my: "center center", at: "center center", of: container } );
dialogDialog.dialog( "open" );
// Cancel event propagation if we were passed a trigger event for the open.
if (event) {
event.stopImmediatePropagation();
event.preventDefault();
}
}
// Positioning function for dialog overlay when opened.
function hpuiOpenForm(formDialog, container, event) {
// Make sure we got passed a JQuery dialog; return short otherwise.
if (!formDialog || !formDialog.length ||
(typeof formDialog != 'object') ||
!(formDialog instanceof jQuery) ||
!(formDialog.is(':data(dialog)')))
return;
// Make sure the container is a DOM element or window; return short otherwise.
if (!container || !(container.nodeType || container == window))
return;
formDialog.dialog( "option", "position", { my: "center center", at: "center center", of: container } );
formDialog.dialog( "open" );
// Cancel event propagation if we were passed a trigger event for the open.
if (event) {
event.stopImmediatePropagation();
event.preventDefault();
}
}
// Positioning function for progress indicator overlay when opened.
function hpuiOpenProgressIndicator(progressDialog, container, event) {
// Make sure we got passed a JQuery dialog; return short otherwise.
if (!progressDialog || !progressDialog.length ||
(typeof progressDialog != 'object') ||
!(progressDialog instanceof jQuery) ||
!(progressDialog.is(':data(dialog)')))
return;
// Make sure the container is a DOM element or window; return short otherwise.
if (!container || !(container.nodeType || container == window))
return;
progressDialog.dialog( "option", "position", { my: "center center", at: "center center", of: container } );
progressDialog.dialog( "open" );
// HPUI_URL and HPUI_IMG_URL are alternative global variables for the root URL
// to the images folder.
var baseUrl = typeof (determineBaseImagesUrl) == 'function' ? determineBaseImagesUrl() : ""; // from init.js
// Set timeout on the progress indicator image to ensure it starts animating.
setTimeout(function() {
jQuery("iframe.hpui-progress-indicator").attr("src", baseUrl + 'HPE_animated_large_blue_gray.gif');
}, 300);
// Cancel event propagation if we were passed a trigger event for the open.
if (event) {
event.stopImmediatePropagation();
event.preventDefault();
}
}
/*** "Private" functions - not for use by feature developers ***/
// Function for closing any open progress indicators when the page loads.
function hideAllProgressIndicators() {
var indicators = jQuery("div.hpui-progress-indicator,iframe.hpui-progress-indicator");
if (indicators && indicators.length) {
for (var i = 0; i < indicators.length; i++) {
var indicator = jQuery(indicators[i]);
indicator.parent().dialog("close");
}
}
}
// Initialize progress indicators in the given context.
function initProgressIndicators(context) {
// Convert div to iframe.
// HPUI_IMG_URL is a global variable for the root URL to the images folder.
var imageUrl = typeof (determineBaseImagesUrl) == 'function' ? determineBaseImagesUrl() : ""; // from init.js
jQuery("").replaceAll('div.hpui-progress-indicator', context);
// Register event listeners to close any open progress indicators.
if (window.attachEvent) { // some browsers support this way:
// this event is for loading from server or browser cache
window.attachEvent("onload", hideAllProgressIndicators);
} else if (window.addEventListener) { // some browsers support this way:
// this event is for loading from server
window.addEventListener("load", hideAllProgressIndicators, false); // FF
// this event is for loading from browser cache
window.addEventListener("pageshow", hideAllProgressIndicators, false); // FF
}
}
/****** end HPE overlays JS (overlays.js) ******/
/****** begin HPE shopping cart JS (shopping-cart.js) ******/
/*** "Public" methods - start with prefix "hpui" - for use by feature developers ***/
// Add screenreader messages for the given locale into the shopping cart icons
// within the given context (may be a JQuery Object, a string HTML ID, or the whole
// page by default).
function hpuiAddShoppingCartResources(context) {
// Get the message resources.
if (typeof(hpuiAddMessageResources) == 'function') {
hpuiAddMessageResources();
}
// Determine the context (if not given).
if (!context || !context.length || (typeof context != 'object') || !(context instanceof jQuery)) {
if (context && typeof context == 'string') {
context = jQuery('#' + context);
} else {
context = document;
}
}
// For each shopping cart set, add the screenreader message and title as needed.
jQuery('a.hpui-shopping-cart-icon,' +
'span.hpui-shopping-cart-icon,' +
'div.hpui-shopping-cart-icon', context).each(function() {
var icon = jQuery(this);
setShoppingCartIconScreenreaderText(icon);
});
}
// Dynamically opens a tooltip without user action.
// Stays opened for the specified period and closes automatically. If the user performs
// mouse enter action on the content, then the close action will be removed.
// Usage - hpuiOpenShoppingCart(jQuery('#NonEmptyMiniShoppingCart .hpui-shopping-cart-icon'),jQuery('.ui-tooltip .hpui-mini-shopping-cart-table'), 3000);
function hpuiOpenShoppingCart(shoppingCartLink, shoppingCartContent, period) {
// Make sure we got passed JQuery objects; return short otherwise.
if (!shoppingCartLink || !shoppingCartLink.length ||
(typeof shoppingCartLink != 'object') ||
!(shoppingCartLink instanceof jQuery))
return;
if (!shoppingCartContent || !shoppingCartContent.length ||
(typeof shoppingCartContent != 'object') ||
!(shoppingCartContent instanceof jQuery))
return;
// Make sure the triggering link is not disabled; do nothing if disabled.
if (shoppingCartLink.attr('disabled'))
return;
// Default period to 3 seconds.
if (!period || isNaN(period) || (period <= 0))
period = 3000;
// Open the tooltip and auto-close at the end of the period.
shoppingCartLink.trigger('mouseenter');
var closeTooltip = setTimeout(function() {
shoppingCartLink.tooltip('close');
tweakIconTitle(shoppingCartLink);
}, period);
// Keep the tooltip open if the user mouses-into it until he mouses-out.
jQuery("div.ui-tooltip-content").off("mouseenter",shoppingCartContent);
jQuery("div.ui-tooltip-content").on("mouseenter",shoppingCartContent,function(){
clearTimeout(closeTooltip);
});
jQuery("div.ui-tooltip-content").off("mouseleave",shoppingCartContent);
jQuery("div.ui-tooltip-content").on("mouseleave",shoppingCartContent,function(){
shoppingCartLink.tooltip('close');
tweakIconTitle(shoppingCartLink);
});
}
/*** "Private" functions not for direct use by feature developers ***/
// Return just the counter from the shopping cart icon.
// This is the icon text minus any screenreader text, forced
// to a non-negative integer.
function getIconCounter(icon) {
var iconCounter = jQuery.trim(icon.text());
icon.find(".hpui-screenreader-text").each(function() {
var screenreaderText = jQuery(this).text();
iconCounter = jQuery.trim(iconCounter.replace(screenreaderText, ''));
});
iconCounter = parseInt(iconCounter, 10);
if (isNaN(iconCounter) || iconCounter < 0)
iconCounter = 0;
return iconCounter;
}
// Set the icon counter in the shopping cart icon.
// The counter must be a non-negative integer; if not, zero is assumed.
// When the counter is zero, the shopping cart icon is emptied.
function setIconCounter(icon, val) {
val = parseInt(val, 10);
if (isNaN(val) || val < 0)
val = 0;
if (val > 0) {
if (val < 100)
icon.html("" + val + " ");
else
icon.html("" + val + " ");
} else {
icon.empty();
}
}
// When icon is enabled, use single-space title instead of no title.
// When icon is disabled, use no title instead of single-space title.
function tweakIconTitle(icon) {
if (!icon.attr('disabled')) {
if (!jQuery.trim(icon.attr('title')))
icon.attr('title', ' ');
} else {
if (!jQuery.trim(icon.attr('title')))
icon.removeAttr('title');
}
}
// Initialize shopping carts in the given context
function initShoppingCart(context) {
// Initialize the mini shopping cart tooltip for each shopping cart icon.
jQuery('a.hpui-shopping-cart-icon,' +
'span.hpui-shopping-cart-icon,' +
'div.hpui-shopping-cart-icon', context).each(function(index) {
var icon = jQuery(this);
var iconCounter = getIconCounter(icon);
var iconState = icon.attr('disabled') ? 'disable' : 'enable';
// Initialize the appropriate counter span (normal or wide) based on the counter size.
// Don't initialize the screenreader text, that will come later.
setIconCounter(icon, iconCounter);
// Initialize the title attribute.
tweakIconTitle(icon);
// Insert into the normal tabflow. No need to do this if tab flow or an href
// is set.
if (!icon.attr('tabindex') && !icon.attr('href'))
icon.attr('tabindex', '0');
// Register keypress event handler to trigger click on 'enter', for accessibility.
// No need to do this if an href is not set because it happens by default.
if (!icon.attr('href')) {
icon.off('keypress.hpui-shopping-cart');
icon.on('keypress.hpui-shopping-cart', function(event) {
var icon = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
icon.trigger('click');
}
});
}
// Initialize the tooltip.
icon.tooltip({
content : generatingTitle,
tooltipClass: "hpui-mini-shopping-cart-table",
position : {
my : "right+18 top+8",
at: "right bottom",
collision: "flip",
using : function(position, feedback) {
jQuery(this).css(position);
if(feedback.vertical == 'bottom'){
jQuery("").addClass("hpui-mini-shopping-cart-arrow-bottom").appendTo(this);
} else if (feedback.vertical == 'top') {
jQuery("
").addClass("hpui-mini-shopping-cart-arrow-top").appendTo(this);
}
}
}
});
// Keep the tooltip visible if user mouseover the tooltip, otherwise
// close the tooltip in 1/2 second.
icon.bind("mouseleave", function(event) {
event.stopImmediatePropagation();
var fixed = setTimeout(function() {
icon.tooltip("close");
tweakIconTitle(icon);
}, 500);
jQuery(".ui-tooltip").hover(
function() {
clearTimeout(fixed);
},
function() {
icon.tooltip("close");
tweakIconTitle(icon);
});
}).tooltip();
icon.bind("focus", function() {
icon.tooltip("close");
icon.addClass("hpui-shopping-cart-icon-focus");
tweakIconTitle(icon);
//jQuery(this).css("background-position", "0px -170px");
});
icon.bind("blur", function() {
icon.removeClass("hpui-shopping-cart-icon-focus");
});
// Register the disable event on the shopping cart icon.
icon.off('hpui-disable.hpui-shopping-cart');
icon.on('hpui-disable.hpui-shopping-cart', function() {
return function() {
var icon = jQuery(this);
// Disable the shopping cart icon and link.
icon.attr('disabled', '');
// Update the screenreader text.
setShoppingCartIconScreenreaderText(icon);
// Unset single-space title when no title.
if (!jQuery.trim(icon.attr('title')))
icon.removeAttr('title');
}
}());
// Register the enable event on the shopping cart icon.
icon.off('hpui-enable.hpui-shopping-cart');
icon.on('hpui-enable.hpui-shopping-cart', function() {
return function() {
var icon = jQuery(this);
// Enable the shopping cart icon and link.
icon.removeAttr('disabled');
// Update the screenreader text.
setShoppingCartIconScreenreaderText(icon);
// Set single-space title when no title.
if (!jQuery.trim(icon.attr('title')))
icon.attr('title', ' ');
}
}());
// Register the custom value event on the shopping cart icon.
icon.off('hpui-value.hpui-shopping-cart');
icon.on('hpui-value.hpui-shopping-cart', function(event, val) {
var icon = jQuery(this);
// Set the counter value if new value is greater than zero,
// and empty the counter value otherwise.
setIconCounter(icon, val);
// Update the screenreader text.
setShoppingCartIconScreenreaderText(icon);
});
// Register the custom toggle event on the shopping cart icon.
// This increments or decrements the current counter by the integer
// amount (positive or negative) given.
icon.off('hpui-toggle.hpui-shopping-cart');
icon.on('hpui-toggle.hpui-shopping-cart', function(event, val) {
var icon = jQuery(this);
// Normalize the value.
val = parseInt(val);
if (isNaN(val)) val = 0;
// Calculate the new counter value.
var newVal = getIconCounter(icon) + val;
// Set the new counter value.
icon.trigger('hpui-value', newVal);
});
// Register the custom clear event on the shopping cart icon.
icon.off('hpui-clear.hpui-shopping-cart');
icon.on('hpui-clear.hpui-shopping-cart', function() {
return function() {
var icon = jQuery(this);
// Set a value of zero.
icon.trigger('hpui-value', 0);
}
}());
// Register the custom reset event on the shopping cart icon.
icon.off('hpui-reset.hpui-shopping-cart');
icon.on('hpui-reset.hpui-shopping-cart', function(initValue, initState) {
return function() {
var icon = jQuery(this);
// Reset the text input disabled/readonly/enabled state
icon.trigger('hpui-' + initState);
// Reset the counter value
icon.trigger('hpui-value', initValue);
}
}(iconCounter, iconState));
});
}
function setShoppingCartIconScreenreaderText(icon) {
var iconTitle = jQuery.trim(icon.attr('title'));
var iconText = jQuery.trim(icon.text());
var iconCounter = getIconCounter(icon);
var iconCounterSpan = icon.children("span.hpui-counter, span.hpui-wide-counter");
var disabled = icon.attr('disabled');
// If there is a counter then attach the messages for the non-empty case as needed.
// If no counter, then attach the message for the empty case as needed.
if (iconCounter > 0) {
if (disabled) {
if (typeof non_empty_shoppingcart_disabled_screenreader == 'string')
iconCounterSpan.html("
" + non_empty_shoppingcart_disabled_screenreader + " " +
iconCounter);
} else {
if (typeof non_empty_shoppingcart_screenreader == 'string')
iconCounterSpan.html("
" + non_empty_shoppingcart_screenreader + " " +
iconCounter);
}
if (typeof non_empty_shoppingcart_title == 'string')
// Remember, initial generated/default title is a single-space.
// Only set title to message if title and text not already set.
if (!iconTitle && !iconText && non_empty_shoppingcart_title)
icon.attr('title', non_empty_shoppingcart_title);
} else {
if (disabled) {
if (typeof empty_shoppingcart_disabled_screenreader == 'string')
icon.html("
" + empty_shoppingcart_disabled_screenreader + " ");
} else {
if (typeof empty_shoppingcart_screenreader == 'string')
icon.html("
" + empty_shoppingcart_screenreader + " ");
}
if (typeof empty_shoppingcart_title == 'string')
// Remember, initial generated/default title is a single-space.
// Only set title to message if title and text not already set.
if (!iconTitle && !iconText && empty_shoppingcart_title)
icon.attr('title', empty_shoppingcart_title);
}
}
/****** end HPE shopping cart JS (shopping-cart.js) ******/
/****** begin HPE tables JS (tables.js) ******/
/*** "Public" table methods - start with prefix "hpui" - for use by feature developers ***/
// This hash maps lowercase locales (format ll eg "fr" or ll-cc, eg "zh-tw") to
// Java locale tags (format ll eg "fr" or ll_CC, eg "zh_TW") of provided message
// bundles.
var HPUI_LOCALES_TO_TABLE_MESSAGES = {
'zh-hk':'zh_HK',
'zh-tw':'zh_TW',
'cs': 'cs',
'de': 'de',
'el': 'el',
'es': 'es',
'fr': 'fr',
'hu': 'hu',
'it': 'it',
'ja': 'ja',
'ko': 'ko',
'pl': 'pl',
'pt': 'pt',
'ru': 'ru',
'tr': 'tr',
'zh': 'zh'
};
// Return URL for best-fit localized resource file for the given locale.
function hpuiAddTableResources() {
// First determine the locale being requested: either the HPUI_LOCALE or the
// value of the HPUI_LOCALE_COOKIE or English by default. From init.js.
var requestedLocale = typeof (determineLocale) == 'function' ? determineLocale() : "en";
// From the locale being requested, determine the locale to actually use.
var localeToUse = "";
var requestedLanguage = requestedLocale;
if (requestedLocale.length > 2)
requestedLanguage = requestedLocale.substring(0, 2);
if (HPUI_LOCALES_TO_TABLE_MESSAGES[requestedLocale.toLowerCase()])
// We will use the full locale if it is supported
localeToUse = HPUI_LOCALES_TO_TABLE_MESSAGES[requestedLocale.toLowerCase()];
else if (HPUI_LOCALES_TO_TABLE_MESSAGES[requestedLanguage.toLowerCase()])
// Else we will use the language if it is supported
localeToUse = HPUI_LOCALES_TO_TABLE_MESSAGES[requestedLanguage.toLowerCase()];
else
// Else we will use English (base) if neither full locale nor language are supported
localeToUse = "en";
// Build and return the best-fit datatables JSON file URL for the locale to use.
// HPUI_URL and HPUI_JS_URL are alternative global variables for the root URL
// to the JS folder. From init.js.
var baseUrl = typeof (determineBaseJsUrl) == 'function' ? determineBaseJsUrl() : "";
var url = baseUrl + 'datatables/i18n/datatables' +
(localeToUse == 'en' ? '' : '_' + localeToUse) + '.json';
return url;
}
// Initialize pagination on the given table with the given options.
function hpuiPaginateTable(options) {
// Make sure we got table options.
if (!options || !options.tableID)
return;
var tableID = options.tableID;
var isViewButtonRequired = options.isViewButtonRequired;
var pageSize = options.pageSize;
var tableElement = jQuery("table.hpui-standard-table#" + tableID + "," +
"table.hpui-static-table#" + tableID);
// Sanity check - there should be one and only one such table
if (tableElement && tableElement.length == 1) {
var viewButtonID = "hpui-view-button_" + tableID;
var wrapper = tableElement.parent();
var oTable = tableElement.dataTable();
var oSettings = oTable.fnSettings();
var rowsToShow = oSettings.fnRecordsDisplay();
var viewAll = oSettings.oLanguage.oPaginate.sViewAll;
var viewLess = oSettings.oLanguage.oPaginate.sViewLess;
var paginationInfo = jQuery('.dataTables_info', wrapper);
// Sanity check - page size should be a positive number
if ((typeof pageSize != "number") || (pageSize < 1))
// Default page size to 25
pageSize = 25;
else if (!(oSettings._iDisplayLength == -1 || oSettings._iDisplayLength == pageSize)) {
oSettings._iDisplayLength = pageSize;
oTable.fnDraw();
}
// Insert pagination info into the normal tabflow.
if (!paginationInfo.attr('tabindex'))
paginationInfo.attr('tabindex', '0');
if (rowsToShow > pageSize) {
jQuery('.dataTables_paginate', wrapper).show();
paginationInfo.children('span.hpui-screenreader-text:last').show();
if (isViewButtonRequired) {
if (oSettings._iDisplayLength == pageSize)
jQuery('.dataTables_paginate', wrapper).append(
"
" + viewAll + " ");
else
jQuery('.dataTables_paginate', wrapper).append(
"
" + viewLess + " ");
var viewButton = jQuery("span#" + viewButtonID);
viewButton.off('click.hpui-view-button');
viewButton.on('click.hpui-view-button', function() {
if (jQuery(this).text() == viewAll) {
jQuery(this).text(viewLess);
oSettings._iDisplayLength = -1;
oTable.fnDraw();
} else {
jQuery(this).text(viewAll);
oSettings._iDisplayLength = pageSize;
oTable.fnDraw();
}
});
viewButton.off('keypress.hpui-view-button');
viewButton.on('keypress.hpui-view-button', function(event) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13'){
viewButton.trigger('click');
}
});
}
} else {
jQuery('.dataTables_paginate', wrapper).hide();
paginationInfo.children('span.hpui-screenreader-text:last').hide();
}
}
}
// Initialize nested tables inside the given table with the given options.
function hpuiNestTable(options){
// Make sure we got table options.
if (!options || !options.tableID)
return;
var tableID = options.tableID;
var multiExpand = options.multiExpand;
var ajaxPreloader = options.ajaxPreloader;
var ajaxProgressIndicator = options.ajaxProgressIndicator;
var ajaxError = options.ajaxError;
var ajaxDelay = options.ajaxDelay;
var ajaxTimeout = options.ajaxTimeout;
// Rationalize multiexpand argument
if (!multiExpand)
multiExpand = false;
// Rationalize preloader argument
if (!ajaxPreloader)
ajaxPreloader = false;
else if (typeof ajaxPreloader != 'string')
ajaxPreloader = '
';
// Rationalize progress indicator argument
if (!ajaxProgressIndicator || !ajaxProgressIndicator.length ||
typeof ajaxProgressIndicator != 'object' ||
!(ajaxProgressIndicator instanceof jQuery) ||
!(ajaxProgressIndicator.is(':data(dialog)')))
ajaxProgressIndicator = false;
// Rationalize error argument
if (!ajaxError || (typeof ajaxError != "string"))
ajaxError = false;
// Rationalize delay argument
if (!ajaxDelay)
ajaxDelay = false;
else if ((typeof ajaxDelay != "number") || (ajaxDelay < 1))
ajaxDelay == 500;
else
ajaxDelay = Math.round(ajaxDelay);
// Rationalize timeout argument
if (!ajaxTimeout || (typeof ajaxTimeout != "number") || (ajaxTimeout < 1))
ajaxTimeout = 0;
else
ajaxTimeout = Math.round(ajaxTimeout);
// Select the requested table
var containerTable = jQuery("table.hpui-standard-table#" + tableID + "," +
"table.hpui-static-table#" + tableID);
// Sanity check - there should be one and only one such table
if (containerTable && containerTable.length == 1) {
var containerTable = containerTable.dataTable();
var innerContentDivs = [];
var rowCount = 1;
var openRows = [];
// Setup the expand/collapse icons on the rows that need them.
jQuery('td:first-child', containerTable.fnGetNodes()).each(function() {
// For each row in the outer table:
//
var needIcon = false;
var firstCell = jQuery(this);
var thisRow = firstCell.parent("tr");
var ajaxUrl = firstCell.parent("tr").attr("data-source");
var rowID = tableID + rowCount;
thisRow.removeAttr("data-source");
// Ajax case: need icon when an Ajax URL has been defined for this row.
if (ajaxUrl)
needIcon = true;
// Non-Ajax case: need icon when div has been defined for this row.
else {
var innerContentDiv = jQuery("div#" + rowID);
needIcon = innerContentDiv && innerContentDiv.length;
// Save div reference for later show/hide.
innerContentDivs.push(innerContentDiv);
}
// Add the icon if needed. Remove it and go to next row if not needed.
var icon = firstCell.children('a.hpui-expand-icon,a.hpui-collapse-icon');
if (needIcon) {
if (!icon || !icon.length) {
icon = jQuery("
");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(icon);
firstCell.prepend(icon);
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(firstCell);
}
} else {
if (icon && icon.length)
icon.remove();
rowCount++;
return;
}
// Register click event on the icon.
icon.off('click.hpui-nested-table');
icon.on('click.hpui-nested-table', {ajaxUrl:ajaxUrl}, function (event) {
var icon = jQuery(this);
var rowObj = icon.parent("td").parent("tr");
var row = rowObj[0];
var i = jQuery.inArray(row, openRows);
var ajaxUrl = event.data.ajaxUrl;
// Stop the click propagation.
event.preventDefault();
event.stopPropagation();
if (i >= 0) {
// Handle click when inner content is already open:
//
// Convert the icon to an expand icon.
icon.removeClass("hpui-collapse-icon").addClass("hpui-expand-icon");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(icon.parent());
// Then close the inner content.
containerTable.fnClose(row);
// Lastly remove it from the list of open rows.
openRows.splice(i, 1);
} else {
// Handle click when inner content is not already open:
//
// First close other inner content (unless multi-expand is on).
if (openRows.length == 1 && !multiExpand) {
var otherIcon = jQuery(openRows[0]).find('a.hpui-collapse-icon');
otherIcon.removeClass("hpui-collapse-icon").addClass("hpui-expand-icon");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(otherIcon.parent());
containerTable.fnClose(openRows[0]);
openRows.splice(openRows[0], 1);
}
// Then convert the icon to a collapse icon.
icon.addClass("hpui-collapse-icon").removeClass("hpui-expand-icon");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(icon.parent());
// Then add the row to the list of open rows.
openRows.push(row);
// Then open the inner content - differs for Ajax and non-Ajax cases.
if (!ajaxUrl) {
// Non-Ajax case:
//
// Fetch the inner content div from saved references, and
// insert into the table.
var index = icon.attr('name').replace(tableID, '');
containerTable.fnOpen(row,
innerContentDivs[(index - 1)].show(),
'hpui-nested-table-container');
} else {
// Ajax case:
//
// If progress indicator, then open it.
if (ajaxProgressIndicator && (typeof(hpuiOpenProgressIndicator) == 'function'))
hpuiOpenProgressIndicator(ajaxProgressIndicator, window);
// Otherwise if preloader, then open it.
else if (ajaxPreloader) {
containerTable.fnOpen(row, ajaxPreloader);
// Make sure it is initialized.
var newRowObj = rowObj.next("tr");
if (typeof (hpuiInitialize) == 'function') hpuiInitialize(newRowObj);
}
// Make the Ajax call. To slow this down in a demo, so users
// can see the progress indicator or preloader for a while,
// we support a secret property, ajaxDelay. This is not
// public knowledge and we will never use this in
// production.
var ajaxCall = function() {
jQuery.ajax({
url: ajaxUrl,
dataType: 'html',
timeout: ajaxTimeout,
success: function(data) {
// Handle success callback from Ajax:
// First check whether row is still meant to be open -
// if not, abandon the AJAX response.
if (icon.hasClass('hpui-collapse-icon')) {
// Add the data into the table row (this
// automatically replaces a preloader if
// any).
containerTable.fnOpen(row,
data,
'hpui-nested-table-container');
// Initialize the data in the new table
// row, by calling hpuiInitialize() on it.
var newRowObj = rowObj.next("tr");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(newRowObj);
}
// Close the progress indicator if any.
if (ajaxProgressIndicator)
ajaxProgressIndicator.dialog('close');
},
error: function(data) {
// Handle error callback from Ajax:
// First check whether row is still meant to be open -
// if not, abandon the AJAX response.
if (icon.hasClass('hpui-collapse-icon')) {
// Add error content, if any, into the table
// row (this automatically replaces a
// preloader if any).
if (ajaxError) {
containerTable.fnOpen(row, ajaxError);
// Initialize the data in the new table
// row, by calling hpuiInitialize() on it.
var newRowObj = rowObj.next("tr");
if (typeof(hpuiInitialize) == 'function') hpuiInitialize(newRowObj);
}
}
// Close progress indicator or preloader row
// (unless we just inserted an error).
if (ajaxProgressIndicator)
ajaxProgressIndicator.dialog('close');
else if (!ajaxError)
containerTable.fnClose(row);
}
});
}
if (ajaxDelay) {
setTimeout (ajaxCall, ajaxDelay);
} else
ajaxCall();
}
}
}); // end of click handler
rowCount++;
return;
}); // end of row initializer
}
}
// Initialize inner tables inside the given table.
function hpuiInnerTable(id) {
// First find all inner tables in the given outer, and set the height of
// each one's outer table cell explicitly to its current computed height
// (which in turn is the current computed height of that whole outer row).
// Since the hpui-inner-table style is height 100%, this will cause each
// inner table to occupy the full height of its containing outer row.
//
// Update: Further testing in IE, FF and Chrome shows that this seems to
// be unnecessary, and in the case of Chrome it somehow causes unequal
// heights to be set on the outer cells in the last row. So comment
// this out. DSJ 2013/9/27
/*
jQuery('table.hpui-standard-table#' + id + ',' +
'table.hpui-static-table#' + id).each(function(i) {
jQuery(this).find('td.hpui-inner-table,th.hpui-inner-table').each(function(j) {
var outerCell = jQuery(this);
outerCell.css('height', outerCell.height() + 'px');
});
});
*/
// Then find all rows in the given outer, and for each such row, find all
// the contained inner table rows and set their heights. Each inner row's
// height is set to the maximum current computed height of all like-numbered
// rows in all the inner tables of this outer row. This way, the table
// row heights of inner tables in the same outer row will all align.
// Thanks to Oliver Wu for this algorithm.
jQuery('table.hpui-standard-table#' + id + '>tbody>tr,' +
'table.hpui-standard-table#' + id + '>thead>tr,' +
'table.hpui-standard-table#' + id + '>tr,' +
'table.hpui-static-table#' + id + '>tbody>tr,' +
'table.hpui-static-table#' + id + '>thead>tr,' +
'table.hpui-static-table#' + id + '>tr').each(function(i, outerRow) {
outerRow = jQuery(outerRow);
var nextOuterRow = outerRow.next("tr");
var borderHeight = 1;
if (!nextOuterRow || nextOuterRow.length == 0)
borderHeight = 0;
var innerRowHeights = [];
outerRow.find('>td.hpui-inner-table>table,>th.hpui-inner-table>table').each(function(j, innerTable) {
innerTable = jQuery(innerTable);
innerTable.find('>tbody>tr,>thead>tr,>tr').each(function (k, innerRow) {
innerRow = jQuery(innerRow);
if (innerRowHeights[k])
innerRowHeights[k] = Math.max(innerRowHeights[k], innerRow.height());
else
innerRowHeights[k] = innerRow.height();
});
});
outerRow.find('>td.hpui-inner-table>table,>th.hpui-inner-table>table').each(function(j, innerTable) {
innerTable = jQuery(innerTable);
innerTable.find('>tbody>tr,>thead>tr,>tr').each(function (k, innerRow) {
innerRow = jQuery(innerRow);
innerRow.css('height', innerRowHeights[k] + 'px');
});
// calculate any remaining space in the outer row and add to the last row of the inner table
// (disregard 1px for outer row bottom border in this calculation)
var extra = outerRow.height() - innerTable.height() - borderHeight;
if (extra > 0) {
innerTable.find('>tbody>tr:last-child,>thead>tr,>tr:last-child').each(function (k, lastInnerRow) {
lastInnerRow = jQuery(lastInnerRow);
var newHeight = lastInnerRow.height() + extra;
lastInnerRow.css('height', newHeight + 'px');
});
}
// fix outer row height so if table is proportional and is resized by the user
// the above settings will not get thrown out of whack
outerRow.css('height', outerRow.height());
});
});
// IE8 hack to remove the unnecessary borders on the inner table.
if ((typeof(getInternetExplorerVersion) == 'function') && (getInternetExplorerVersion() === 8)) {
jQuery('table.hpui-standard-table#'+id+' td.hpui-inner-table > table > tbody').each(function(event){
jQuery(this).children('tr').children('td').css('border-right','0px');
jQuery(this).children('tr:last-child').children('td').css('border-bottom','0px');
});
}
}
/*
* Function: hpuiGetTableDataAsDisplayed
* Purpose: Return an array with the data arrays used for displaying the table
* Returns: array node: data array elements
* Inputs: tableID
* Source: http://datatables.net/forums/discussion/798/export-current-state-of-datatable/p1
*/
function hpuiGetTableDataAsDisplayed(tableID) {
if (!tableID)
return;
var tableElement = jQuery("table.hpui-standard-table#" + tableID + "," +
"table.hpui-static-table#" + tableID);
if (tableElement && tableElement.length == 1) {
var oTable = tableElement.dataTable();
var oSettings = oTable.fnSettings();
var aaData = [];
for ( var j=0, jLen=oSettings.aiDisplay.length ; j
0) {
if (pipeCache) {
getPipelinedServerSideTable(sSource, aoData, fnCallback, oSettings, ajaxTimeout, ajaxError, destroyTableOnError, pipeCache, pipeSize);
} else {
handleServerSideError(ajaxError, destroyTableOnError, oSettings);
}
} else {
getServerSideTable(sSource, aoData, fnCallback, oSettings, ajaxTimeout, ajaxError, destroyTableOnError);
}
}
/*** "Private" functions not for direct use by feature developers ***/
// Pre-Initialize tables in the given context.
// This is hack for Large tables in IE9 have random empty TD showing up
// For more information visit - https://drupal.org/node/1535714
function preInitTables(context) {
if ((typeof(getInternetExplorerVersion) == 'function') && (getInternetExplorerVersion() === 9)) {
var tables = jQuery('table.hpui-standard-table,table.hpui-static-table', context);
var expr = new RegExp('>[\t\r\n\v\f]*<', 'g');
if (tables && tables.length)
for (var i = 0; i < tables.length; i++)
jQuery(tables[i]).html(jQuery(tables[i]).html().replace(expr, '><'));
}
}
// Post-initialize tables in the given context.
// This does the inner table sizing. Needs to happen after all other
// pre-, main and post-init, otherwise some of the table row sizings may be
// incorect.
function postInitTables(context) {
// Finally initialize the inner tables if any.
var tables = jQuery('table.hpui-standard-table,table.hpui-static-table', context);
if (tables && tables.length)
for (var i = 0; i < tables.length; i++)
hpuiInnerTable(jQuery(tables[i]).attr('id'));
}
// Initialize tables in the given context.
function initTables(context) {
// First, generate table alternating row styles when needed.
var tables = jQuery('table.hpui-standard-table.hpui-alternating-rows,' +
'table.hpui-static-table.hpui-alternating-rows', context);
if (tables && tables.length) {
for (var i = 0; i < tables.length; i++) {
var table = jQuery(tables[i]);
var bodies = table.children('tbody');
if (bodies && bodies.length) {
for (var j = 0; j < bodies.length; j++) {
var body = jQuery(bodies[j]);
body.children('tr:even').removeClass('hpui-normal-row hpui-alternate-row').addClass('hpui-normal-row');
body.children('tr:odd').removeClass('hpui-normal-row hpui-alternate-row').addClass('hpui-alternate-row');
}
}
}
}
// Finally: JQuery Datatables extensions for custom sorting.
if (typeof(jQuery.fn.dataTableExt) != 'undefined') {
// File Size - see http://www.datatables.net/plug-ins/sorting#file_size
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"file-size-pre": function ( a ) {
var x = a.substring(0,a.length - 2);
var x_unit = (a.substring(a.length - 2, a.length) == "MB" ?
1000 : (a.substring(a.length - 2, a.length) == "GB" ? 1000000 : 1));
return parseInt( x * x_unit, 10 );
},
"file-size-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"file-size-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
});
// Hidden title numbers - see http://www.datatables.net/plug-ins/sorting#hidden_title_numeric
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"title-numeric-pre": function ( a ) {
var x = a.match(/title="*(-?[0-9\.]+)/)[1];
return parseFloat( x );
},
"title-numeric-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"title-numeric-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
// Hidden title strings - see http://www.datatables.net/plug-ins/sorting#hidden_title_string
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"title-string-pre": function ( a ) {
return a.match(/title="(.*?)"/)[1].toLowerCase();
},
"title-string-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"title-string-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
// Localized string - wrote this one myself
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"i18n-string-asc" : function (s1, s2) {
return s1.localeCompare(s2);
},
"i18n-string-desc" : function (s1, s2) {
return s2.localeCompare(s1);
}
} );
}
// Initialize service summary views (both titles and content):
// Set tabindex and map enter key to click event.
jQuery('div[onclick].hpui-service-summary-title,' +
'table.hpui-service-summary-content tr[onclick]', context).each(function(index) {
var section = jQuery(this);
// Insert into the normal tabflow, unless tabflow already specified.
if (!section.attr('tabindex'))
section.attr('tabindex', '0');
// Register keypress event handler to trigger click on 'enter', for accessibility.
section.off('keypress.hpui-tables');
section.on('keypress.hpui-tables', function(event) {
var link = jQuery(this);
var keycode = (event.keyCode ? event.keyCode : event.which);
if (keycode == '13') {
link.trigger('click');
}
});
});
}
// Internal functions used in server side data tables feature
function fnSetKey(aoData, sKey, mValue) {
for (var i = 0, iLen = aoData.length; i < iLen; i++) {
if (aoData[i].name == sKey) {
aoData[i].value = mValue;
}
}
}
function fnGetKey(aoData, sKey) {
for (var i = 0, iLen = aoData.length; i < iLen; i++) {
if (aoData[i].name == sKey) {
return aoData[i].value;
}
}
return null;
}
function getServerSideTable(sSource, aoData, fnCallback, oSettings, ajaxTimeout, ajaxError, destroyTableOnError) {
jQuery.ajax({
"dataType": 'json',
"url": sSource,
"data": aoData,
"timeout": ajaxTimeout,
"success": fnCallback,
"error": function() {
handleServerSideError(ajaxError, destroyTableOnError, oSettings);
},
"complete": function() {
if (typeof(hideAllProgressIndicators) == 'function')
hideAllProgressIndicators();
}
});
}
function getPipelinedServerSideTable(sSource, aoData, fnCallback, oSettings, ajaxTimeout, ajaxError, destroyTableOnError, oCache, iPipe) {
var bNeedServer = false;
var sEcho = fnGetKey(aoData, "sEcho");
var iRequestStart = fnGetKey(aoData, "iDisplayStart");
var iRequestLength = fnGetKey(aoData, "iDisplayLength");
var iRequestEnd = iRequestStart + iRequestLength;
oCache.iDisplayStart = iRequestStart;
/* If requested page not in cache, remember to make server-side fetch. */
if (!("iCacheLower" in oCache))
oCache.iCacheLower = -1;
if (oCache.iCacheLower < 0 || iRequestStart < oCache.iCacheLower || iRequestEnd > oCache.iCacheUpper) {
bNeedServer = true;
}
/* If requested sort or similar criteria not in cache, remember to make server-side fetch. */
if (oCache.lastRequest && !bNeedServer) {
for (var i = 0, iLen = aoData.length; i < iLen; i++) {
if (aoData[i].name != "iDisplayStart" && aoData[i].name != "iDisplayLength" && aoData[i].name != "sEcho") {
if (aoData[i].value != oCache.lastRequest[i].value) {
bNeedServer = true;
break;
}
}
}
}
/* Store the request for checking next time around */
oCache.lastRequest = aoData.slice();
/* Make server-side fetch when not in cache. */
if (bNeedServer) {
if (iRequestStart < oCache.iCacheLower) {
iRequestStart = iRequestStart - (iRequestLength * (iPipe - 1));
if (iRequestStart < 0 || iRequestLength < 0) {
iRequestStart = 0;
}
}
oCache.iCacheLower = iRequestStart;
oCache.iCacheUpper = iRequestStart + (iRequestLength * iPipe);
oCache.iDisplayLength = fnGetKey(aoData, "iDisplayLength");
fnSetKey(aoData, "iDisplayStart", iRequestStart);
fnSetKey(aoData, "iDisplayLength", ((iRequestLength < 0) ? iRequestLength : (iRequestLength * iPipe)));
jQuery.ajax({
"dataType": 'json',
"url": sSource,
"data": aoData,
"timeout": ajaxTimeout,
"success": function(json) {
oCache.lastJson = jQuery.extend(true, {}, json);
if (oCache.iCacheLower != oCache.iDisplayStart) {
json.aaData.splice(0, oCache.iDisplayStart - oCache.iCacheLower);
}
if (oCache.iDisplayLength >= 0) {
json.aaData.splice(oCache.iDisplayLength, json.aaData.length);
}
fnCallback(json);
},
"error": function() {
handleServerSideError(ajaxError, destroyTableOnError, oSettings);
},
"complete": function() {
if (typeof(hideAllProgressIndicators) == 'function')
hideAllProgressIndicators();
}
});
}
/* Fetch from cache when server-side fetch not required. */
else {
json = jQuery.extend(true, {}, oCache.lastJson);
json.sEcho = sEcho; /* Update the echo for each response */
json.aaData.splice(0, iRequestStart - oCache.iCacheLower);
if (iRequestLength >= 0) {
json.aaData.splice(iRequestLength, json.aaData.length);
}
fnCallback(json);
return;
}
}
function handleServerSideError(ajaxError, destroyTableOnError, oSettings) {
// Hide the progress indicators
jQuery.fn.dataTableExt.oApi._fnProcessingDisplay(oSettings, false);
if (typeof(hideAllProgressIndicators) == 'function')
hideAllProgressIndicators();
// If a custom error message was provided, render it into the table -
// otherwise no updates to the table in its current state.
if (ajaxError) {
if (destroyTableOnError) {
jQuery(oSettings.nTableWrapper).html(ajaxError);
} else {
var nNewRow = document.createElement("tr");
var nNewCell = document.createElement("td");
nNewRow.appendChild( nNewCell );
nNewCell.colSpan = jQuery.fn.dataTableExt.oApi._fnVisbleColumns(oSettings);
if (typeof ajaxError === "string")
nNewCell.innerHTML = ajaxError;
else
jQuery(nNewCell).html(ajaxError);
jQuery(oSettings.nTBody).html(nNewRow);
}
}
}
/****** end HPE tables JS (tables.js) ******/
/****** begin HPE typography JS (typography.js) ******/
/*** "Public" functions - may be used by feature developers ***/
/*** "Private" functions not for direct use by feature developers ***/
/****** end HPE typography JS (typography.js) ******/