Skip to content

Instantly share code, notes, and snippets.

@Tharos
Created October 3, 2017 08:34
Show Gist options
  • Save Tharos/8afe8bb950f3e845ec4d0d869b238e42 to your computer and use it in GitHub Desktop.
Save Tharos/8afe8bb950f3e845ec4d0d869b238e42 to your computer and use it in GitHub Desktop.
First Mithril app
'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;
'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;
'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')
]))
];
}
};
'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;
};
'use strict';
module.exports = Object.freeze({
APPLICANT_TYPE_IMG: 'img',
APPLICANT_TYPE_NONIMG: 'nonImg'
});
'use strict';
module.exports = {
formatIntegerValue: function (value) {
return (value === null || value === '') ? null : parseInt(value);
}
};
'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