From 34611beb0d131573b2c8eebaac25f4c07a719612 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Fri, 16 Jun 2017 11:43:12 -0700 Subject: [PATCH] Add error API Provide a container for displaying error messages with an API for controlling the messages inside that container Implements: https://www.pivotaltracker.com/story/show/147353401 --- error-el.js | 51 +++++++++++++++++++++++++++++++++++++++++++++ form-elements.js | 1 + test/errors.spec.js | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 error-el.js create mode 100644 test/errors.spec.js diff --git a/error-el.js b/error-el.js new file mode 100644 index 0000000..3d7a005 --- /dev/null +++ b/error-el.js @@ -0,0 +1,51 @@ +const html = require('bel') +const helpers = require('./element-helper') + +function errorContainer (opts) { + const classes = helpers.classes(['center', 'w-100', 'tc', 'red', 'f4', 'mt3', 'mb3'], opts) + const style = helpers.style('', opts) + const el = helpers.opts(html`
`, opts) + return el +} + +function errorMessage (key, txt) { + return html`
${txt}
` +} + +function error (opts) { + opts = opts || {} + const messages = new Map() + const container = errorContainer(opts) + + return { + render: () => container, + displayError, + removeError, + clear + } + + function displayError (key, txt) { + if (messages.has(key)) { + const msgEl = getMsgDiv(key) + msgEl.innerText = txt + } else { + container.appendChild(errorMessage(key, txt)) + } + messages.set(key, txt) + } + + function removeError (key) { + messages.delete(key) + container.removeChild(getMsgDiv(key)) + } + + function clear () { + messages.forEach((_, key) => removeError(key)) + } + + function getMsgDiv (key) { + return container.querySelector(`div[data-for="${key}"]`) + } +} + +module.exports = error diff --git a/form-elements.js b/form-elements.js index f8cbd99..eacd777 100644 --- a/form-elements.js +++ b/form-elements.js @@ -2,3 +2,4 @@ exports.input = require('./input-el') exports.button = require('./button-el') exports.label = require('./label-el') exports.labeledInput = require('./labeled-input-el') +exports.error = require('./error-el') diff --git a/test/errors.spec.js b/test/errors.spec.js new file mode 100644 index 0000000..f54f8ee --- /dev/null +++ b/test/errors.spec.js @@ -0,0 +1,41 @@ +const test = require('tape') + +const error = require('../error-el.js') + +test('errors', (t) => { + const errA = error() + const $elA = errA.render() + const errB = error() + const $elB = errB.render() + + t.equal($elA.children.length, 0, 'elA has no kids') + t.equal($elB.children.length, 0, 'elB has no kids') + + errA.displayError('bar', 'beep') + + t.equal($elA.children.length, 1, 'elA has a kid') + t.equal($elB.children.length, 0, 'elB has no kids') + t.equal($elA.children[0].innerText, 'beep', 'beeping') + + errA.displayError('bar', 'moog') + + t.equal($elA.children.length, 1, 'elA has a kid') + t.equal($elA.children[0].innerText, 'moog', 'mooging') + + errA.removeError('bar') + + t.equal($elA.children.length, 0, 'elA has no kids') + t.equal($elB.children.length, 0, 'elB has no kids') + + errA.displayError('foo', 'boop') + errA.displayError('baz', 'shoop') + + t.equal($elA.children.length, 2, 'elA has 2 kids') + t.equal($elA.children[0].innerText, 'boop', 'first we boop') + t.equal($elA.children[1].innerText, 'shoop', 'then we shoop') + + errA.clear() + + t.equal($elA.children.length, 0, 'elA has no kids') + t.end() +})