use virtual-dom to implement functionality for invite form

This commit is contained in:
Riku Rouvila
2015-01-21 23:30:33 +02:00
parent a7bfb8e591
commit 92d7790b4a
5 changed files with 115 additions and 15 deletions

View File

@@ -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"
]

View File

@@ -17,6 +17,9 @@ html
<br />
Koodiklinikka on <a target="_blank" href="https://slack.com/">Slack</a>-yhteisö kaikille ohjelmoinnista ja ohjelmistoalasta kiinnostuneille harrastajille ja ammattilaisille.
#invite-form
h3 Liity mukaan
.footer
a(href='https://koodiklinikka.slack.com') koodiklinikka.slack.com

View File

@@ -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;

View File

@@ -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');
});
});

11
src/js/util/classList.js Normal file
View File

@@ -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(' ');
};