Created
December 8, 2015 11:15
-
-
Save StephanHoyer/097e10bad077398358e1 to your computer and use it in GitHub Desktop.
Simple multiselect with mithril.js
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 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; |
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 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' | |
}); | |
} | |
}; |
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
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