diff --git a/app/views/examples/options-data-api/index.njk b/app/views/examples/options-data-api/index.njk new file mode 100644 index 0000000000..04b6a693fa --- /dev/null +++ b/app/views/examples/options-data-api/index.njk @@ -0,0 +1,156 @@ +{% extends "template.njk" %} + +{% from "character-count/macro.njk" import govukCharacterCount %} +{% from "error-summary/macro.njk" import govukErrorSummary %} + +{% block head %} + + + + + +{% endblock %} + +{% block content %} +

+ Options Data Api +

+ +

Character count

+

Data API

+
+ {{ govukCharacterCount({ + name: "with-hint", + id: "with-hint", + maxlength: 200, + label: { + text: "Can you provide more detail?" + }, + hint: { + text: "Do not include personal or financial information like your National Insurance number or credit card details." + } + }) }} +
+

Programmatic API

+
+ {{ govukCharacterCount({ + name: "programmatic-api", + id: "programmatic-api", + label: { + text: "Can you provide more detail?" + }, + hint: { + text: "Do not include personal or financial information like your National Insurance number or credit card details." + } + }) }} +
+

Overriden Data API

+
+ {{ govukCharacterCount({ + name: "overriden-api", + id: "overriden-api", + maxlength: 200, + label: { + text: "Can you provide more detail?" + }, + hint: { + text: "Do not include personal or financial information like your National Insurance number or credit card details." + } + }) }} +
+ +

Error summary

+

Data API

+
+ {{ govukErrorSummary({ + autofocus: false, + titleText: "There is a problem", + errorList: [ + { + text: "The date your passport was issued must be in the past", + href: "#passport-issued-error" + }, + { + text: "Enter a postcode, like AA1 1AA", + href: "#postcode-error" + } + ] + }) }} +
+

Programmatic API

+
+ {{ govukErrorSummary({ + titleText: "There is a problem", + errorList: [ + { + text: "The date your passport was issued must be in the past", + href: "#passport-issued-error" + }, + { + text: "Enter a postcode, like AA1 1AA", + href: "#postcode-error" + } + ] + }) }} +
+

Overriden Data API

+
+ {{ govukErrorSummary({ + titleText: "There is a problem", + errorList: [ + { + text: "The date your passport was issued must be in the past", + href: "#passport-issued-error" + }, + { + text: "Enter a postcode, like AA1 1AA", + href: "#postcode-error" + } + ] + }) }} +
+{% endblock %} + +{% block bodyEnd %} + + + +{% endblock %} \ No newline at end of file diff --git a/src/common.js b/src/common.js index 7d2835ebea..88b8eec43a 100644 --- a/src/common.js +++ b/src/common.js @@ -26,3 +26,32 @@ export function generateUniqueID () { return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16) }) } + +export function extractDatasetOptions ($element) { + var dataset = {} + var attributes = $element.attributes + if (!attributes) { + return dataset + } + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i] + var match = attribute.name.match(/^data-(.+)/) + if (!match) { + continue + } + + var value = attribute.value + var key = match[1] + + if (!isNaN(value)) { + dataset[key] = parseInt(value, 10) + } else if(value === 'true') { + dataset[key] = true + } else if(value === 'false') { + dataset[key] = false + } else { + dataset[key] = value + } + } + return dataset +} \ No newline at end of file diff --git a/src/components/character-count/character-count.js b/src/components/character-count/character-count.js index 93ec55e620..bda3445c9b 100644 --- a/src/components/character-count/character-count.js +++ b/src/components/character-count/character-count.js @@ -2,9 +2,14 @@ import '../../vendor/polyfills/Function/prototype/bind' import '../../vendor/polyfills/Event' // addEventListener and event.target normaliziation import '../../vendor/polyfills/Element/prototype/classList' -function CharacterCount ($module) { +import { extractDatasetOptions } from '../../common.js' + +function CharacterCount ($module, options) { this.$module = $module this.$textarea = $module.querySelector('.js-character-count') + + // If there are no options default to an empty object + this.options = typeof options !== 'undefined' ? options : {} } CharacterCount.prototype.defaults = { @@ -22,19 +27,10 @@ CharacterCount.prototype.init = function () { } // Read options set using dataset ('data-' values) - this.options = this.getDataset($module) - - // Determine the limit attribute (characters or words) - var countAttribute = this.defaults.characterCountAttribute - if (this.options.maxwords) { - countAttribute = this.defaults.wordCountAttribute - } - - // Save the element limit - this.maxLength = $module.getAttribute(countAttribute) + this.options = Object.assign({}, extractDatasetOptions($module), this.options) // Check for limit - if (!this.maxLength) { + if (!this.options.maxlength && !this.options.maxwords) { return } @@ -57,22 +53,6 @@ CharacterCount.prototype.init = function () { } } -// Read data attributes -CharacterCount.prototype.getDataset = function (element) { - var dataset = {} - var attributes = element.attributes - if (attributes) { - for (var i = 0; i < attributes.length; i++) { - var attribute = attributes[i] - var match = attribute.name.match(/^data-(.+)/) - if (match) { - dataset[match[1]] = attribute.value - } - } - } - return dataset -} - // Counts characters or words in text CharacterCount.prototype.count = function (text) { var length @@ -136,7 +116,7 @@ CharacterCount.prototype.updateCountMessage = function () { // Determine the remaining number of characters/words var currentLength = this.count(countElement.value) - var maxLength = this.maxLength + var maxLength = options.maxlength || options.maxwords var remainingNumber = maxLength - currentLength // Set threshold if presented in options diff --git a/src/components/character-count/template.njk b/src/components/character-count/template.njk index ee9004bb3b..bd2b96880b 100644 --- a/src/components/character-count/template.njk +++ b/src/components/character-count/template.njk @@ -23,7 +23,9 @@ errorMessage: params.errorMessage, attributes: params.attributes }) }} + {% if params.maxlength or params.maxwords %} You can enter up to {{ params.maxlength or params.maxwords }} {{'words' if params.maxwords else 'characters' }} + {% endif %} diff --git a/src/components/error-summary/error-summary.js b/src/components/error-summary/error-summary.js index 7d93ee9d04..138a6b1f9b 100644 --- a/src/components/error-summary/error-summary.js +++ b/src/components/error-summary/error-summary.js @@ -2,8 +2,13 @@ import '../../vendor/polyfills/Function/prototype/bind' import '../../vendor/polyfills/Event' // addEventListener import '../../vendor/polyfills/Element/prototype/closest' -function ErrorSummary ($module) { +import { extractDatasetOptions } from '../../common.js' + +function ErrorSummary ($module, options) { this.$module = $module + + // If there are no options default to an empty object + this.options = typeof options !== 'undefined' ? options : {} } ErrorSummary.prototype.init = function () { @@ -11,13 +16,25 @@ ErrorSummary.prototype.init = function () { if (!$module) { return } - window.addEventListener('load', function () { - $module.focus() - }) + + // Read options set using dataset ('data-' values) + this.options = Object.assign({}, extractDatasetOptions($module), this.options) + + var autofocus = typeof this.options.autofocus === 'boolean' ? this.options.autofocus : true + + if (autofocus) { + window.addEventListener('load', function () { + this.focus() + }.bind(this)) + } $module.addEventListener('click', this.handleClick.bind(this)) } +ErrorSummary.prototype.focus = function () { + this.$module.focus() +} + /** * Click event handler * diff --git a/src/components/error-summary/template.njk b/src/components/error-summary/template.njk index 49b34b4595..787a64b6ff 100644 --- a/src/components/error-summary/template.njk +++ b/src/components/error-summary/template.njk @@ -1,5 +1,6 @@