diff --git a/app/assets/javascripts/collapsibleCheckboxes.js b/app/assets/javascripts/collapsibleCheckboxes.js
index f6bb41fab..6f378c074 100644
--- a/app/assets/javascripts/collapsibleCheckboxes.js
+++ b/app/assets/javascripts/collapsibleCheckboxes.js
@@ -1,150 +1,164 @@
(function (Modules) {
"use strict";
- Modules.CollapsibleCheckboxes = function() {
- const _focusTextElement = ($el) => {
- $el
- .attr('tabindex', '-1')
- .focus();
- };
+ function Summary (module) {
+ this.module = module;
+ this.$el = module.$formGroup.find('.selection-summary');
+ this.fieldLabel = module.fieldLabel;
+ this.total = module.total;
+ this.addContent();
+ this.update(module.getSelection());
+ }
+ Summary.prototype.templates = {
+ all: (selection, total, field) => `All ${field}s`,
+ some: (selection, total, field) => `${selection} of ${total} ${field}s`,
+ none: (selection, total, field) => ({
+ "folder": "No folders (only templates outside a folder)",
+ "team member": "No team members (only you)"
+ }[field] || `No ${field}s`)
+ };
+ Summary.prototype.addContent = function() {
+ this.$text = $(`
`);
- this.start = function(component) {
- this.$formGroup = $(component);
- this.$fieldset = this.$formGroup.find('fieldset');
- this.$checkboxes = this.$fieldset.find('input[type=checkbox]');
- this.fieldLabel = this.$formGroup.data('fieldLabel');
- this.total = this.$checkboxes.length;
- this.legendText = this.$fieldset.find('legend').text().trim();
- this.expanded = false;
+ if (this.fieldLabel === 'folder') { this.$text.addClass('selection-summary__text--folders'); }
- this.addHeadingHideLegend();
+ this.$el.append(this.$text);
+ };
+ Summary.prototype.update = function(selection) {
+ let template;
- // generate summary and footer
- this.summary.$el = this.$formGroup.find('.selection-summary');
- this.footer.$el = this.footer.getEl(this);
- this.footer.update(this);
+ if (selection === this.total) {
+ template = 'all';
+ } else if (selection > 0) {
+ template = 'some';
+ } else {
+ template = 'none';
+ }
- // create summary from component pieces and match text to current selection
- this.summary.addContent(this.legendText, this.fieldLabel);
- this.summary.update(this.getSelection(), this.total, this.fieldLabel);
- this.$fieldset.before(this.summary.$el);
-
- // add custom classes
- this.$formGroup.addClass('selection-wrapper');
- this.$fieldset.addClass('selection-content');
-
- // hide checkboxes
- this.$fieldset.hide();
-
- this.bindEvents();
- };
- this.getSelection = function() { return this.$checkboxes.filter(':checked').length; };
- this.addHeadingHideLegend = function() {
- const headingLevel = this.$formGroup.data('heading-level') || '2';
-
- this.$heading = $(`${this.legendText}`);
- this.$fieldset.before(this.$heading);
-
- this.$fieldset.find('legend').addClass('visuallyhidden');
- };
- this.summary = {
- templates: {
- all: (selection, total, field) => `All ${field}s`,
- some: (selection, total, field) => `${selection} of ${total} ${field}s`,
- none: (selection, total, field) => ({
- "folder": "No folders (only templates outside a folder)",
- "team member": "No team members (only you)"
- }[field] || `No ${field}s`)
- },
- addContent: function(legendText, fieldLabel) {
- this.$text = $(``);
-
- if (fieldLabel === 'folder') { this.$text.addClass('selection-summary__text--folders'); }
-
- this.$el.append(this.$text);
- },
- update: function(selection, total, field) {
- let template;
-
- if (selection === total) {
- template = 'all';
- } else if (selection > 0) {
- template = 'some';
- } else {
- template = 'none';
- }
-
- this.$text.html(this.templates[template](selection, total, field));
- }
- };
- this.footer = {
- buttonContent: {
- change: (fieldLabel) => `Choose ${fieldLabel}s`,
- done: (fieldLabel) => `Done choosing ${fieldLabel}s`
- },
- getEl: function (module) {
- const buttonState = module.expanded ? 'done' : 'change';
- const buttonContent = this.buttonContent[buttonState](module.fieldLabel);
-
- return $(``);
- },
- update: function (module) {
- this.$el.remove();
- this.$el = this.getEl(module);
-
- module.$formGroup.append(this.$el);
- }
- };
- this.expand = function(e) {
- if (e !== undefined) { e.preventDefault(); }
-
- if (!this.expanded) {
- this.$fieldset.show();
- this.expanded = true;
- this.footer.update(this);
- }
-
- // shift focus whether expanded or not
- _focusTextElement(this.$fieldset);
- };
- this.collapse = function(e) {
- if (e !== undefined) { e.preventDefault(); }
-
- if (this.expanded) {
- this.$fieldset.hide();
- this.expanded = false;
- this.footer.update(this);
- }
-
- // shift focus whether expanded or not
- _focusTextElement(this.summary.$text);
- };
- this.handleClick = function(e) {
- if (this.expanded) {
- this.collapse(e);
- } else {
- this.expand(e);
- }
- };
- this.handleSelection = function(e) {
- this.summary.update(this.getSelection(), this.total, this.fieldLabel);
- };
- this.bindEvents = function() {
- const self = this;
-
- this.$formGroup.on('click', '.button', this.handleClick.bind(this));
- this.$checkboxes.on('click', this.handleSelection.bind(this));
-
- // take summary out of tab order when focus moves
- this.summary.$el.on('blur', (e) => $(this).attr('tabindex', '-1'));
- };
+ this.$text.html(this.templates[template](selection, this.total, this.fieldLabel));
+ };
+ Summary.prototype.bindEvents = function () {
+ // take summary out of tab order when focus moves
+ this.$el.on('blur', (e) => $(this).attr('tabindex', '-1'));
};
+ function Footer (module) {
+ this.module = module;
+ this.fieldLabel = module.fieldLabel;
+ this.fieldsetId = module.$fieldset.attr('id');
+ this.$el = this.getEl(this.module.expanded);
+ this.module.$formGroup.append(this.$el);
+ }
+ Footer.prototype.buttonContent = {
+ change: (fieldLabel) => `Choose ${fieldLabel}s`,
+ done: (fieldLabel) => `Done choosing ${fieldLabel}s`
+ };
+ Footer.prototype.getEl = function (expanded) {
+ const buttonState = expanded ? 'done' : 'change';
+ const buttonContent = this.buttonContent[buttonState](this.fieldLabel);
+
+ return $(``);
+ };
+ Footer.prototype.update = function (expanded) {
+ this.$el.remove();
+ this.$el = this.getEl(expanded);
+
+ this.module.$formGroup.append(this.$el);
+ };
+
+ function CollapsibleCheckboxes () {}
+ CollapsibleCheckboxes.prototype._focusTextElement = ($el) => {
+ $el
+ .attr('tabindex', '-1')
+ .focus();
+ };
+ CollapsibleCheckboxes.prototype.start = function(component) {
+ this.$formGroup = $(component);
+ this.$fieldset = this.$formGroup.find('fieldset');
+ this.$checkboxes = this.$fieldset.find('input[type=checkbox]');
+ this.fieldLabel = this.$formGroup.data('fieldLabel');
+ this.total = this.$checkboxes.length;
+ this.legendText = this.$fieldset.find('legend').text().trim();
+ this.expanded = false;
+
+ this.addHeadingHideLegend();
+
+ // generate summary and footer
+ this.footer = new Footer(this);
+ this.summary = new Summary(this);
+
+ this.$fieldset.before(this.summary.$el);
+
+ // add custom classes
+ this.$formGroup.addClass('selection-wrapper');
+ this.$fieldset.addClass('selection-content');
+
+ // hide checkboxes
+ this.$fieldset.hide();
+
+ this.bindEvents();
+ };
+ CollapsibleCheckboxes.prototype.getSelection = function() { return this.$checkboxes.filter(':checked').length; };
+ CollapsibleCheckboxes.prototype.addHeadingHideLegend = function() {
+ const headingLevel = this.$formGroup.data('heading-level') || '2';
+
+ this.$heading = $(`${this.legendText}`);
+ this.$fieldset.before(this.$heading);
+
+ this.$fieldset.find('legend').addClass('visuallyhidden');
+ };
+ CollapsibleCheckboxes.prototype.expand = function(e) {
+ if (e !== undefined) { e.preventDefault(); }
+
+ if (!this.expanded) {
+ this.$fieldset.show();
+ this.expanded = true;
+ this.summary.update(this.getSelection());
+ this.footer.update(this.expanded);
+ }
+
+ // shift focus whether expanded or not
+ this._focusTextElement(this.$fieldset);
+ };
+ CollapsibleCheckboxes.prototype.collapse = function(e) {
+ if (e !== undefined) { e.preventDefault(); }
+
+ if (this.expanded) {
+ this.$fieldset.hide();
+ this.expanded = false;
+ this.summary.update(this.getSelection());
+ this.footer.update(this.expanded);
+ }
+
+ // shift focus whether expanded or not
+ this._focusTextElement(this.summary.$text);
+ };
+ CollapsibleCheckboxes.prototype.handleClick = function(e) {
+ if (this.expanded) {
+ this.collapse(e);
+ } else {
+ this.expand(e);
+ }
+ };
+ CollapsibleCheckboxes.prototype.handleSelection = function(e) {
+ this.summary.update(this.getSelection(), this.total, this.fieldLabel);
+ };
+ CollapsibleCheckboxes.prototype.bindEvents = function() {
+ const self = this;
+
+ this.$formGroup.on('click', '.button', this.handleClick.bind(this));
+ this.$checkboxes.on('click', this.handleSelection.bind(this));
+
+ this.summary.bindEvents(this);
+ };
+
+ Modules.CollapsibleCheckboxes = CollapsibleCheckboxes;
+
}(window.GOVUK.Modules));