I am trying to get bootstrap-multiselect to work with Aurelia. have got it working more or less but not sure it is the best solution or if I might run into trouble.
Bootstrap-multiselect is a jquery plugin that turns a normal select (multi) into a drop down with checkboxes (http://davidstutz.github.io/bootstrap-multiselect/)
My first problem is to get it working with dynamically created options. I solved that by using the plugins "rebuild" feature when my array of options (created as a bindable property) changes. However the options of the original select hhas then not yet been created so I use setTimeout to delay rebuilding so Aurelia have rebuilt the select. Feels like a "dirty" solution and I know to little about the Aurelia lifecyle to be sure it will always work.
Second problem is that value for component will not be updated, however the change method will fire. I solved this by firing off a change event (found an example for some other plugin that do the same). Works fine, value wiill be updated but the change method will fire twice. Not a big problem but might be a problem if a change does some time consuming work (like getting data from a database etc).
Any suggestions to improve code ?
<template>
<select value.bind="value" multiple="multiple">
<option repeat.for="option of options"Value.bind="option.value">${option.label}</option>
</select>
</template>
import {customElement, bindable, inject} from 'aurelia-framework';
import 'jquery';
import 'bootstrap';
import 'davidstutz/bootstrap-multiselect';
@inject(Element)
export class MultiSelect {
@bindable value: any;
@bindable options: {};
@bindable config: {};
constructor(private element) {
this.element = element;
}
optionsChanged(newVal: any, oldVal: any) {
setTimeout(this.rebuild, 0);
}
attached() {
var selElement = $(this.element).find('select');
selElement.multiselect(
{
includeSelectAllOption: true,
selectAllText: "(All)",
selectAllNumber: false,
numberDisplayed: 1,
buttonWidth: "100%"
})
.on('change', (event) => {
if (event.originalEvent) { return; }
var notice = new Event('change', { bubbles: true });
selElement[0].dispatchEvent(notice);
});
}
detached() {
$(this.element).find('select').multiselect('destroy');
}
rebuild = () => {
$(this.element).find('select').multiselect('rebuild');
}
}