Skip to content

Instantly share code, notes, and snippets.

@StephanHoyer
Created December 8, 2015 11:15
Show Gist options
  • Save StephanHoyer/097e10bad077398358e1 to your computer and use it in GitHub Desktop.
Save StephanHoyer/097e10bad077398358e1 to your computer and use it in GitHub Desktop.
Simple multiselect with mithril.js
'use strict';
var m = require('mithril');
var icons = require('client/utils/icons');
function checkbox(label, options) {
options = options || {};
var onclick = function(event) {
event.stopImmediatePropagation();
options.onchange && options.onchange({
target: {
checked: !options.value
}
});
m.redraw();
};
var labelAttrs = options.disabled ? {
disabled: true
} : {};
return m('label.form-label' + (options.property ? '.field-' + options.property : ''), labelAttrs, [
icons.button(options.value ? 'checkboxChecked' : 'checkboxUnchecked', {
onclick: onclick,
className: 'form-checkbox'
}), m('.form-checkbox-label', label)
]);
}
module.exports = checkbox;
'use strict';
var m = require('mithril');
var checkboxField = require('./checkbox');
var pull = require('lodash/array/pull');
var withTooltip = require('./tooltip').withTooltip;
var icons = require('client/utils/icons');
function noop() {}
function byLabel(optionA, optionB) {
return optionA.label > optionB.label;
}
function optionView(scope, selectedOptions) {
return function(selectOption) {
return m('li', {
key: selectOption.value
}, checkboxField(selectOption.label, {
disabled: !scope.isOpen || selectOption.disabled,
value: selectedOptions.indexOf(selectOption.value) >= 0,
onchange: function(event) {
if (event.target.checked) {
selectedOptions.push(selectOption.value);
} else {
pull(selectedOptions, selectOption.value);
}
scope.onChange(selectedOptions);
}
}));
};
}
module.exports = {
controller: function(options) {
var selectedOptions = options.selectedOptions || [];
var scope = {
selector: options.selector,
getSelectOptions: options.getSelectOptions || function() {
return options.selectOptions || [];
},
getSelectedOptions: options.getSelectedOptions || function() {
return selectedOptions;
},
onChange: options.onChange || noop,
get title() {
return (options.getTitle || noop)(scope.getSelectedOptions());
},
get label() {
return (options.getLabel || noop)(scope.getSelectedOptions());
},
isOpen: false,
toggle: function(event) {
event.stopPropagation();
scope.isOpen = !scope.isOpen;
}
};
return scope;
},
view: function(scope) {
var selectOptions = scope.getSelectOptions();
var selectedOptions = scope.getSelectedOptions();
var button = m(scope.selector || '.multi-select.button', {
className: selectOptions.length === 0 ? 'disabled' : '',
onclick: scope.isOpen ? null : scope.toggle
}, [
scope.label,
icons('arrow'),
scope.isOpen ? m('.dropdown-overlay', {
onclick: scope.toggle
}): null,
m('ul.options.' + (scope.isOpen ? 'open' : 'close'),
selectOptions.sort(byLabel).map(optionView(scope, selectedOptions))
)
]);
return withTooltip(button, scope.title, {
dark: true,
position: 'top'
});
}
};
return m.component(multiSelect, {
key: key,
selector: 'li.multi-select.aggregation-' + key,
getSelectedOptions: function() {
return [] // selected options as array of keys;
},
getSelectOptions: function() {
return [] // possible options as array of {key: 'foo', label: 'bar'}
},
getTitle: function(selectedOptions) {
return 'click here'
},
onChange: function(selectedValues) {
// triggered on change
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment