From 92d7790b4ab0b65263d4f8e57279d5faf4e52be1 Mon Sep 17 00:00:00 2001 From: Riku Rouvila Date: Wed, 21 Jan 2015 23:30:33 +0200 Subject: [PATCH] use virtual-dom to implement functionality for invite form --- package.json | 7 +++- src/jade/index.jade | 3 ++ src/js/components/inviteForm.js | 40 +++++++++++++++++++ src/js/main.js | 69 ++++++++++++++++++++++++++------- src/js/util/classList.js | 11 ++++++ 5 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 src/js/components/inviteForm.js create mode 100644 src/js/util/classList.js diff --git a/package.json b/package.json index ddf6b45..5f4bc04 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,15 @@ ], "dependencies": { "axios": "^0.4.2", - "virtual-dom": "^1.1.0" + "lodash": "^2.4.1", + "virtual-dom": "^1.2.0" }, "devDependencies": { - "coffee-script": "~1.8.0", + "6to5ify": "^3.1.2", "bower": "~1.3.5", "browserify": "~6.1.0", "chalk": "~0.5.1", + "coffee-script": "~1.8.0", "deamdify": "^0.1.1", "debowerify": "~0.9.1", "ecstatic": "~0.5.3", @@ -47,6 +49,7 @@ }, "browserify": { "transform": [ + "6to5ify", "debowerify", "deamdify" ] diff --git a/src/jade/index.jade b/src/jade/index.jade index c4fa83d..19fc407 100644 --- a/src/jade/index.jade +++ b/src/jade/index.jade @@ -17,6 +17,9 @@ html
Koodiklinikka on Slack-yhteisö kaikille ohjelmoinnista ja ohjelmistoalasta kiinnostuneille harrastajille ja ammattilaisille. + #invite-form + h3 Liity mukaan + .footer a(href='https://koodiklinikka.slack.com') koodiklinikka.slack.com diff --git a/src/js/components/inviteForm.js b/src/js/components/inviteForm.js new file mode 100644 index 0000000..f0d6901 --- /dev/null +++ b/src/js/components/inviteForm.js @@ -0,0 +1,40 @@ +'use strict'; + +var {h} = require('virtual-dom'); +var classList = require('../util/classList'); + +function render(props, state) { + var emailInput = h('input', { + className: classList({ + 'input': true, + 'has-success': state.submitted, + 'has-error': state.error + }), + type: 'text', + name: 'email', + placeholder: 'Email', + value: state.email, + onkeydown: props.onChange + }); + + var submitButton = h('button', { + className: 'btn btn__submit', + type: 'submit', + title: 'Lähetä', + disabled: state.error || state.submitted + }, '⏎'); + + return h('form', { + className: classList({ + 'invite-form': true, + 'has-success': state.submitted, + 'has-error': state.error + }), + onsubmit: props.onSubmit + }, [ + emailInput, + submitButton + ]); +} + +module.exports = render; diff --git a/src/js/main.js b/src/js/main.js index 96af354..b243195 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,19 +1,62 @@ 'use strict'; require('./ga'); + +var _ = require('lodash'); var request = require('axios'); -var form = document.getElementById('invite'); -form.addEventListener('submit', function(event) { - event.preventDefault(); - form.classList.remove('has-success', 'has-error'); - var email = event.target.elements.email.value; +var inviteForm = require('./components/inviteForm'); +var {diff, patch, create} = require('virtual-dom'); + +var state = { + email: '', + submitted: false, + error: false +}; + +function setState(newState) { + state = _.extend({}, state, newState); + rerender(state); +} + +var props = { + onSubmit: function(e) { + e.preventDefault(); + + setState({ + submitted: false, + error: false + }); + + request.post('/api/invites', { + email: state.email.email + }).then(function() { + setState({submitted: true}); + }).catch(function() { + setState({error: true}); + }); + }, + onChange: function(e) { + setState({ + email: e.target.value, + error: false, + submitted: false + }); + }, +}; + +var tree = inviteForm(props, state); +var rootNode = create(tree); + +document + .getElementById('invite-form') + .appendChild(rootNode); + +function rerender() { + var newTree = inviteForm(props, state); + var patches = diff(tree, newTree); + rootNode = patch(rootNode, patches); + tree = newTree; +} + - request.post('/api/invites', { - email: email - }).then(function() { - form.classList.add('has-success'); - }).catch(function() { - form.classList.add('has-error'); - }); -}); diff --git a/src/js/util/classList.js b/src/js/util/classList.js new file mode 100644 index 0000000..9a85b16 --- /dev/null +++ b/src/js/util/classList.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function classList(classesObj) { + var classes = []; + for(var key in classesObj) { + if(!!classesObj[key]) { + classes.push(key); + } + } + return classes.join(' '); +};