-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor toolkit JS to pass local linting
The toolkit JS was refactored to pass StandardJS linting rules: alphagov/govuk_frontend_toolkit#334 We haven't moved to them yet and still lint according to JSHint + our own config (see .jshintrc). This refactors the toolkit JS to pass our rules. Note: we will move to StandardJS rules in the future but doing so requires changing all our JS and tests so cannot be included in this story.
- Loading branch information
Showing
2 changed files
with
86 additions
and
86 deletions.
There are no files selected for viewing
120 changes: 60 additions & 60 deletions
120
app/assets/javascripts/govuk-frontend-toolkit/show-hide-content.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,166 +1,166 @@ | ||
;(function (global) { | ||
'use strict' | ||
(function (global) { | ||
'use strict'; | ||
|
||
var $ = global.jQuery | ||
var GOVUK = global.GOVUK || {} | ||
var $ = global.jQuery; | ||
var GOVUK = global.GOVUK || {}; | ||
|
||
function ShowHideContent () { | ||
var self = this | ||
var self = this; | ||
|
||
// Radio and Checkbox selectors | ||
var selectors = { | ||
namespace: 'ShowHideContent', | ||
radio: '[data-target] > input[type="radio"]', | ||
checkbox: '[data-target] > input[type="checkbox"]' | ||
} | ||
}; | ||
|
||
// Adds ARIA attributes to control + associated content | ||
function initToggledContent () { | ||
var $control = $(this) | ||
var $content = getToggledContent($control) | ||
var initToggledContent = function () { | ||
var $control = $(this); | ||
var $content = getToggledContent($control); | ||
|
||
// Set aria-controls and defaults | ||
if ($content.length) { | ||
$control.attr('aria-controls', $content.attr('id')) | ||
$control.attr('aria-expanded', 'false') | ||
$content.attr('aria-hidden', 'true') | ||
$control.attr('aria-controls', $content.attr('id')); | ||
$control.attr('aria-expanded', 'false'); | ||
$content.attr('aria-hidden', 'true'); | ||
} | ||
} | ||
}; | ||
|
||
// Return toggled content for control | ||
function getToggledContent ($control) { | ||
var id = $control.attr('aria-controls') | ||
var id = $control.attr('aria-controls'); | ||
|
||
// ARIA attributes aren't set before init | ||
if (!id) { | ||
id = $control.closest('[data-target]').data('target') | ||
id = $control.closest('[data-target]').data('target'); | ||
} | ||
|
||
// Find show/hide content by id | ||
return $('#' + id) | ||
return $('#' + id); | ||
} | ||
|
||
// Show toggled content for control | ||
function showToggledContent ($control, $content) { | ||
// Show content | ||
if ($content.hasClass('js-hidden')) { | ||
$content.removeClass('js-hidden') | ||
$content.attr('aria-hidden', 'false') | ||
$content.removeClass('js-hidden'); | ||
$content.attr('aria-hidden', 'false'); | ||
|
||
// If the controlling input, update aria-expanded | ||
if ($control.attr('aria-controls')) { | ||
$control.attr('aria-expanded', 'true') | ||
$control.attr('aria-expanded', 'true'); | ||
} | ||
} | ||
} | ||
|
||
// Hide toggled content for control | ||
function hideToggledContent ($control, $content) { | ||
$content = $content || getToggledContent($control) | ||
$content = $content || getToggledContent($control); | ||
|
||
// Hide content | ||
if (!$content.hasClass('js-hidden')) { | ||
$content.addClass('js-hidden') | ||
$content.attr('aria-hidden', 'true') | ||
$content.addClass('js-hidden'); | ||
$content.attr('aria-hidden', 'true'); | ||
|
||
// If the controlling input, update aria-expanded | ||
if ($control.attr('aria-controls')) { | ||
$control.attr('aria-expanded', 'false') | ||
$control.attr('aria-expanded', 'false'); | ||
} | ||
} | ||
} | ||
|
||
// Handle radio show/hide | ||
function handleRadioContent ($control, $content) { | ||
// All radios in this group which control content | ||
var selector = selectors.radio + '[name="' + $control.attr('name') + '"][aria-controls]' | ||
var $form = $control.closest('form') | ||
var $radios = $form.length ? $form.find(selector) : $(selector) | ||
var selector = selectors.radio + '[name="' + $control.attr('name') + '"][aria-controls]'; | ||
var $form = $control.closest('form'); | ||
var $radios = $form.length ? $form.find(selector) : $(selector); | ||
|
||
// Hide content for radios in group | ||
$radios.each(function () { | ||
hideToggledContent($(this)) | ||
}) | ||
hideToggledContent($(this)); | ||
}); | ||
|
||
// Select content for this control | ||
if ($control.is('[aria-controls]')) { | ||
showToggledContent($control, $content) | ||
showToggledContent($control, $content); | ||
} | ||
} | ||
|
||
// Handle checkbox show/hide | ||
function handleCheckboxContent ($control, $content) { | ||
// Show checkbox content | ||
if ($control.is(':checked')) { | ||
showToggledContent($control, $content) | ||
showToggledContent($control, $content); | ||
} else { // Hide checkbox content | ||
hideToggledContent($control, $content) | ||
hideToggledContent($control, $content); | ||
} | ||
} | ||
|
||
// Set up event handlers etc | ||
function init ($container, elementSelector, eventSelectors, handler) { | ||
$container = $container || $(document.body) | ||
$container = $container || $(document.body); | ||
|
||
// Handle control clicks | ||
function deferred () { | ||
var $control = $(this) | ||
handler($control, getToggledContent($control)) | ||
} | ||
var deferred = function () { | ||
var $control = $(this); | ||
handler($control, getToggledContent($control)); | ||
}; | ||
|
||
// Prepare ARIA attributes | ||
var $controls = $(elementSelector) | ||
$controls.each(initToggledContent) | ||
var $controls = $(elementSelector); | ||
$controls.each(initToggledContent); | ||
|
||
// Handle events | ||
$.each(eventSelectors, function (idx, eventSelector) { | ||
$container.on('click.' + selectors.namespace, eventSelector, deferred) | ||
}) | ||
$container.on('click.' + selectors.namespace, eventSelector, deferred); | ||
}); | ||
|
||
// Any already :checked on init? | ||
if ($controls.is(':checked')) { | ||
$controls.filter(':checked').each(deferred) | ||
$controls.filter(':checked').each(deferred); | ||
} | ||
} | ||
|
||
// Get event selectors for all radio groups | ||
function getEventSelectorsForRadioGroups () { | ||
var radioGroups = [] | ||
var radioGroups = []; | ||
|
||
// Build an array of radio group selectors | ||
return $(selectors.radio).map(function () { | ||
var groupName = $(this).attr('name') | ||
var groupName = $(this).attr('name'); | ||
|
||
if ($.inArray(groupName, radioGroups) === -1) { | ||
radioGroups.push(groupName) | ||
return 'input[type="radio"][name="' + $(this).attr('name') + '"]' | ||
radioGroups.push(groupName); | ||
return 'input[type="radio"][name="' + $(this).attr('name') + '"]'; | ||
} | ||
return null | ||
}) | ||
return null; | ||
}); | ||
} | ||
|
||
// Set up radio show/hide content for container | ||
self.showHideRadioToggledContent = function ($container) { | ||
init($container, selectors.radio, getEventSelectorsForRadioGroups(), handleRadioContent) | ||
} | ||
init($container, selectors.radio, getEventSelectorsForRadioGroups(), handleRadioContent); | ||
}; | ||
|
||
// Set up checkbox show/hide content for container | ||
self.showHideCheckboxToggledContent = function ($container) { | ||
init($container, selectors.checkbox, [selectors.checkbox], handleCheckboxContent) | ||
} | ||
init($container, selectors.checkbox, [selectors.checkbox], handleCheckboxContent); | ||
}; | ||
|
||
// Remove event handlers | ||
self.destroy = function ($container) { | ||
$container = $container || $(document.body) | ||
$container.off('.' + selectors.namespace) | ||
} | ||
$container = $container || $(document.body); | ||
$container.off('.' + selectors.namespace); | ||
}; | ||
} | ||
|
||
ShowHideContent.prototype.init = function ($container) { | ||
this.showHideRadioToggledContent($container) | ||
this.showHideCheckboxToggledContent($container) | ||
} | ||
this.showHideRadioToggledContent($container); | ||
this.showHideCheckboxToggledContent($container); | ||
}; | ||
|
||
GOVUK.ShowHideContent = ShowHideContent | ||
global.GOVUK = GOVUK | ||
})(window) | ||
GOVUK.ShowHideContent = ShowHideContent; | ||
global.GOVUK = GOVUK; | ||
})(window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,61 @@ | ||
;(function (global) { | ||
'use strict' | ||
(function (global) { | ||
'use strict'; | ||
|
||
var $ = global.jQuery | ||
var GOVUK = global.GOVUK || {} | ||
GOVUK.Modules = GOVUK.Modules || {} | ||
var $ = global.jQuery; | ||
var GOVUK = global.GOVUK || {}; | ||
GOVUK.Modules = GOVUK.Modules || {}; | ||
|
||
GOVUK.modules = { | ||
find: function (container) { | ||
container = container || $('body') | ||
container = container || $('body'); | ||
|
||
var modules | ||
var moduleSelector = '[data-module]' | ||
var modules; | ||
var moduleSelector = '[data-module]'; | ||
|
||
modules = container.find(moduleSelector) | ||
modules = container.find(moduleSelector); | ||
|
||
// Container could be a module too | ||
if (container.is(moduleSelector)) { | ||
modules = modules.add(container) | ||
modules = modules.add(container); | ||
} | ||
|
||
return modules | ||
return modules; | ||
}, | ||
|
||
start: function (container) { | ||
var modules = this.find(container) | ||
var modules = this.find(container); | ||
|
||
for (var i = 0, l = modules.length; i < l; i++) { | ||
var module | ||
var element = $(modules[i]) | ||
var type = camelCaseAndCapitalise(element.data('module')) | ||
var started = element.data('module-started') | ||
var module; | ||
var element = $(modules[i]); | ||
var type = camelCaseAndCapitalise(element.data('module')); | ||
var started = element.data('module-started'); | ||
|
||
if (typeof GOVUK.Modules[type] === 'function' && !started) { | ||
module = new GOVUK.Modules[type]() | ||
module.start(element) | ||
element.data('module-started', true) | ||
module = new GOVUK.Modules[type](); | ||
module.start(element); | ||
element.data('module-started', true); | ||
} | ||
} | ||
|
||
// eg selectable-table to SelectableTable | ||
function camelCaseAndCapitalise (string) { | ||
return capitaliseFirstLetter(camelCase(string)) | ||
return capitaliseFirstLetter(camelCase(string)); | ||
} | ||
|
||
// http://stackoverflow.com/questions/6660977/convert-hyphens-to-camel-case-camelcase | ||
function camelCase (string) { | ||
return string.replace(/-([a-z])/g, function (g) { | ||
return g.charAt(1).toUpperCase() | ||
}) | ||
return g.charAt(1).toUpperCase(); | ||
}); | ||
} | ||
|
||
// http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript | ||
function capitaliseFirstLetter (string) { | ||
return string.charAt(0).toUpperCase() + string.slice(1) | ||
return string.charAt(0).toUpperCase() + string.slice(1); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
global.GOVUK = GOVUK | ||
})(window) | ||
global.GOVUK = GOVUK; | ||
})(window); |