/**
* @file
* Toggle object.
*/
/**
* @namespace toggle
* @memberof UCASUtilities
* @param {object} _u - UCASUtilities object.
*/
(function (_u) {
var toggles = []
// Wrapper with a fallback to document.
// Wrapper is needed for the click event on iOS.
var wrapper = document.querySelector('.page-wrapper') || document
/**
* A toggle object is returned from UCASUtilities.toggle.create().
* @class
* @memberof! UCASUtilities.toggle
* @public
* @example
* toggleRef = UCASUtilities.toggle.create('my-id', function(){console.log('show')}, function(){console.log('hide')}, true)
* toggleRef.show()
* toggleRef.hide()
*/
var Toggle = {
init: function (id, showCallback, hideCallback, hideOnClickAway) {
this.id = id
this.showCallback = showCallback
this.hideCallback = hideCallback
this.$element = document.getElementById(id)
this.show = function show () {
if (typeof this.showCallback === 'function') {
// If the callback returns false, exit early.
if (this.showCallback() === false) {
return
}
}
if (hideOnClickAway) {
wrapper.addEventListener('click', this, false)
}
this.$element.setAttribute('data-toggle-state', 'open')
}.bind(this)
this.hide = function hide () {
if (typeof this.hideCallback === 'function') {
// If the callback returns false, exit early.
if (this.hideCallback() === false) {
return
}
}
wrapper.removeEventListener('click', this, false)
this.$element.setAttribute('data-toggle-state', 'closed')
}.bind(this)
this.handleEvent = function (event) {
event.stopPropagation()
if (this.$element === event.target || this.$element.contains(event.target)) {
event.preventDefault() // Prevent default on the actual toggle and its children only.
}
switch (event.type) {
case 'click':
this.$element.getAttribute('data-toggle-state') === 'open' ? this.hide() : this.show()
break
}
}.bind(this)
addEventListeners(this)
},
destroy: function () {
removeEventListeners(this)
delete toggles[this.id]
}
}
/**
* @param {Toggle} toggle - Toggle instance
*/
function addEventListeners (toggle) {
removeEventListeners(toggle)
toggle.$element.addEventListener('click', toggle, true)
}
/**
* @param {Toggle} toggle - Toggle instance
*/
function removeEventListeners (toggle) {
toggle.$element.removeEventListener('click', toggle, true)
document.removeEventListener('click', toggle, false)
}
/**
* @function hideOthers
* @memberof! UCASUtilities.toggle
* @param {string} id - the unique ID of the toggle element
* @param {node} [context=document] - the ancestor node containing the toggle
* @example
* UCASUtilities.toggle.hideOthers('my-id')
*/
function hideOthers (id, context) {
context = context || document
var open = context.querySelectorAll('[data-toggle-state="open"]')
_u.forEach(open, function (i, el) {
if (el.id && el.id !== id) {
toggles[el.id].hide()
}
})
}
/**
* Creates and registers a toggle, which is used to show or hide elements.
* A toggle requires two callbacks: one for the show event and one for the hide event.
* @function create
* @memberof! UCASUtilities.toggle
* @param {string} id - the unique ID of the toggle element
* @param {function} show - a callback on show
* @param {function} hide - a callback on hide
* @param {boolean} hideOnClickAway - trigger hide when clicking away from the toggle
* @return {Toggle} - a reference to the Toggle
* @example
* UCASUtilities.toggle.create('my-id', function(){console.log('show')}, function(){console.log('hide')}, true)
*/
function create (id, show, hide, hideOnClickAway) {
if (document.getElementById(id)) {
toggles[id] = Object.create(Toggle)
toggles[id].init(id, show, hide, hideOnClickAway)
return toggles[id]
} else {
_u.log.log('No toggle with id ' + id)
}
}
/**
* @function destroy
* @memberof! UCASUtilities.toggle
* @param {string} id - the unique ID of the toggle element
* @example
* UCASUtilities.toggle.destroy('my-id')
*/
function destroy (id) {
if (toggles[id]) {
toggles[id].destroy()
} else {
_u.log.log('No toggle with id ' + id)
}
}
/**
* @function hide
* @memberof! UCASUtilities.toggle
* @param {string} id - the unique ID of the toggle element
* @example
* UCASUtilities.toggle.hide('my-id')
*/
function hideToggle (id) {
if (toggles[id]) {
toggles[id].hide()
} else {
_u.log.log('No toggle with id ' + id)
}
}
/**
* @function show
* @memberof! UCASUtilities.toggle
* @param {string} id - the unique ID of the toggle element
* @example
* UCASUtilities.toggle.show('my-id')
*/
function showToggle (id) {
if (toggles[id]) {
toggles[id].show()
} else {
_u.log.log('No toggle with id ' + id)
}
}
_u.toggle = {
create: create,
destroy: destroy,
hideOthers: hideOthers,
hide: hideToggle,
show: showToggle
}
}(UCASUtilities))