Created
October 3, 2017 08:34
-
-
Save Tharos/8afe8bb950f3e845ec4d0d869b238e42 to your computer and use it in GitHub Desktop.
First Mithril app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var constants = require('./constants'); | |
var Applicant = function (type) { | |
this.type = type; | |
this.laboratoryId = null; | |
this.institution = null; | |
this.name = null; | |
this.email = null; | |
this.setInstitution = function (institution) { | |
if (this.type === constants.APPLICANT_TYPE_NONIMG) { | |
this.institution = institution; | |
} else { | |
throw 'InvalidMethodCall'; | |
} | |
}; | |
this.setLaboratoryId = function (laboratoryId) { | |
if (this.type === constants.APPLICANT_TYPE_IMG) { | |
this.laboratoryId = laboratoryId; | |
} else { | |
throw 'InvalidMethodCall'; | |
} | |
}; | |
this.setName = function (name) { | |
this.name = name; | |
}; | |
this.setEmail = function (email) { | |
this.email = email; | |
}; | |
this.isImg = function () { | |
return this.type === constants.APPLICANT_TYPE_IMG; | |
}; | |
}; | |
module.exports = Applicant; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var Applicant = require('./Applicant'); | |
var Applicants = function (applicants) { | |
applicants = applicants || {}; | |
this.push = function (applicant) { | |
var keys = Object.keys(applicants); | |
var id = keys.length > 0 ? Math.max.apply(null, Object.keys(applicants)) + 1 : 1; | |
applicants[id] = applicant; | |
}; | |
this.remove = function (id) { | |
delete applicants[id]; | |
}; | |
this.getAll = function () { | |
return applicants; | |
}; | |
this.isRemovable = function (id) { | |
var keys = Object.keys(applicants); | |
if (keys.length > 0 && keys[0] === id) { | |
return false; // main applicant | |
} | |
for (var index in applicants) { | |
if (applicants.hasOwnProperty(index) && index !== id && applicants[index].isImg()) { | |
return true; // there is some other IMG applicant | |
} | |
} | |
return false; | |
}; | |
}; | |
module.exports = Applicants; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var m = require('mithril'); | |
var constants = require('./constants'); | |
var Applicant = require('./Applicant'); | |
var applicantsFormInit = require('./applicantsFormInit'); | |
module.exports = { | |
oninit: applicantsFormInit, | |
onupdate: function (vnode) { | |
vnode.state.stateField.value = JSON.stringify(vnode.state.applicants.getAll()); | |
}, | |
view: function (vnode) { | |
return [ | |
m('div.applicants', (function () { | |
var children = []; | |
var buildLaboratoryInput = function (applicant) { | |
return m('.form-group.required', [ | |
m('.control-label.col-xs-3', m('label.required[for=applicant' + index + '_laboratory]', 'Laboratory')), | |
m('.col-xs-9', | |
m('select[required].form-control.sizeM#applicant' + index + '_laboratory]', { | |
oninput: m.withAttr('value', (function (applicant) { | |
return function (value) { | |
applicant.setLaboratoryId( | |
vnode.state.helpers.formatIntegerValue(value) | |
); | |
} | |
})(applicant)), | |
value: applicant.laboratoryId !== null ? applicant.laboratoryId : '', | |
'data-nette-rules': '[{"op":":filled","msg":"Please complete mandatory field Laboratory."}]' | |
}, (function () { | |
var options = [m('option', {value: ''}, '-- Please choose --')]; | |
for (var index in vnode.state.laboratories) { | |
if (vnode.state.laboratories.hasOwnProperty(index)) { | |
options.push(m('option', {value: index}, vnode.state.laboratories[index])); | |
} | |
} | |
return options; | |
})() | |
) | |
) | |
]) | |
}; | |
var buildInstitutionInput = function (applicant) { | |
return m('.form-group.required', [ | |
m('.control-label.col-xs-3', m('label.required[for=applicant' + index + '_institution]', 'Name of institution')), | |
m('.col-xs-9', m('input[type=text][required].form-control.sizeL#applicant' + index + '_institution]', { | |
oninput: m.withAttr('value', applicant.setInstitution.bind(applicant)), | |
value: applicant.institution, | |
'data-nette-rules': '[{"op":":filled","msg":"Please complete mandatory field Name of institution."}]' | |
})) | |
]) | |
}; | |
var list = vnode.state.applicants.getAll(); | |
var mainApplicantIndex = Object.keys(list)[0]; | |
for (var index in list) { | |
if (!list.hasOwnProperty(index)) { | |
continue; | |
} | |
var applicant = list[index]; | |
var inputs = [ | |
m('.row', m('.applicant-type.col-xs-9.col-xs-offset-3', [ | |
(function () { | |
var children = [m( | |
'strong', | |
(index === mainApplicantIndex ? 'Main applicant (' : 'Joint applicant (') + (applicant.isImg() ? 'IMG' : 'Non-IMG ') + ')' | |
)]; | |
if (vnode.state.applicants.isRemovable(index)) { | |
children.push(' '); | |
children.push(m('a[href=#].btn.btn-danger.btn-sm', { | |
onclick: (function (index) { | |
return function (e) { | |
e.preventDefault(); | |
vnode.state.applicants.remove(index); | |
} | |
})(index) | |
}, 'Remove')); | |
} | |
return children; | |
})() | |
])), | |
// laboratory or institution input | |
applicant.isImg() ? buildLaboratoryInput(applicant) : buildInstitutionInput(applicant), | |
// name input | |
m('.form-group.required', [ | |
m('.control-label.col-xs-3', m('label.required[for=applicant' + index + '_name]', "Applicant's name")), | |
m('.col-xs-9', m('input[type=text][required].form-control.sizeL#applicant' + index + '_name]', { | |
oninput: m.withAttr('value', applicant.setName.bind(applicant)), | |
value: applicant.name, | |
'data-nette-rules': '[{"op":":filled","msg":"Please complete mandatory field Name."}]' | |
})) | |
]), | |
// e-mail input | |
m('.form-group.required', [ | |
m('.control-label.col-xs-3', m('label.required[for=applicant' + index + '_email]', "Applicant's e-mail")), | |
m('.col-xs-9', m('input[type=text][required].form-control.sizeL#applicant' + index + '_email]', { | |
oninput: m.withAttr('value', applicant.setEmail.bind(applicant)), | |
value: applicant.email, | |
'data-nette-rules': '[{"op":":email","msg":"Please enter a valid email address."}]' | |
})) | |
]) | |
]; | |
children.push(m('.applicant', inputs)); | |
} | |
return children; | |
})()), | |
m('.form-group', m('.applicants-controls.col-xs-9.col-xs-offset-3', [ | |
m('a[href=#].btn.btn-default', { | |
onclick: function (e) { | |
e.preventDefault(); | |
vnode.state.applicants.push(new Applicant(constants.APPLICANT_TYPE_IMG)); | |
} | |
}, 'Add IMG applicant'), | |
' ', | |
m('a[href=#].btn.btn-default', { | |
onclick: function (e) { | |
e.preventDefault(); | |
vnode.state.applicants.push(new Applicant(constants.APPLICANT_TYPE_NONIMG)); | |
} | |
}, 'Add Non-IMG applicant') | |
])) | |
]; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var constants = require('./constants'); | |
var helpers = require('./helpers'); | |
var Applicant = require('./Applicant'); | |
var Applicants = require('./Applicants'); | |
var stateField = document.getElementById('applicants'); | |
var laboratories = JSON.parse( | |
document.getElementById('applicantsApp').dataset.laboratories | |
); | |
var applicants = new Applicants((function () { | |
var applicants = {}; | |
try { | |
var list = JSON.parse(stateField.value); | |
for (var index in list) { | |
if (list.hasOwnProperty(index)) { | |
var data = list[index]; | |
var applicant = new Applicant(data.type); | |
if (data.type === constants.APPLICANT_TYPE_IMG) { | |
applicant.setLaboratoryId(data.laboratoryId); | |
} else { | |
applicant.setInstitution(data.institution); | |
} | |
applicant.setName(data.name); | |
applicant.setEmail(data.email); | |
applicants[index] = applicant; | |
} | |
} | |
} catch (e) { | |
// never mind, just missing initial state… | |
} | |
return applicants; | |
})()); | |
module.exports = function (vnode) { | |
vnode.state.stateField = stateField; | |
vnode.state.applicants = applicants; | |
vnode.state.helpers = helpers; | |
vnode.state.laboratories = laboratories; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
module.exports = Object.freeze({ | |
APPLICANT_TYPE_IMG: 'img', | |
APPLICANT_TYPE_NONIMG: 'nonImg' | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
module.exports = { | |
formatIntegerValue: function (value) { | |
return (value === null || value === '') ? null : parseInt(value); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var m = require('mithril'); | |
var applicantsForm = require('./applicantsForm'); | |
var applicantsApp = document.getElementById('applicantsApp'); | |
if (applicantsApp !== null) { | |
m.mount(applicantsApp, applicantsForm); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment