Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aurelia + Select2 custom element not propagating selected changed

I have created a custom element in Aurelia.

import {bindable, inject, customElement, bindingMode} from 'aurelia-framework';
import 'select2';
import * as $ from 'jquery';
import {BindingSignaler} from "aurelia-templating-resources";

@customElement('select2')
@inject(Element, BindingSignaler)
export class Select2CustomMultiselect {
    @bindable name = null;    // name/id of custom select
    @bindable selected = null;  // default selected values
    @bindable ({defaultBindingMode: bindingMode.oneWay, attribute:"options"}) source:Array<{id:number, name:any}>= [];   // array of options with id/name properties
    @bindable placeholder = "";
    @bindable allow_clear = true;
    private $select2: $;

    constructor(private element, private signaler:BindingSignaler) {
    }

    attached() {
        let $select = $(this.element).find('select');
        this.$select2 = $select.select2({theme: 'bootstrap', placeholder: this.placeholder});

        // on any change, propagate it to underlying select to trigger two-way bind
        this.$select2.on('change', (event) => {
            if (event.originalEvent) { return; }

            const select2Value = this.$select2.val();
            if(select2Value == this.selected) { return; }

            // dispatch to raw select within the custom element
            var notice = new Event('change', {bubbles: true});
            event.target.dispatchEvent(notice);
        });

        this.$select2.val(this.selected);//.trigger('change');
    }

    selectedChanged(newValue,oldValue){
        console.log(newValue);
    }

    detached() {
        $(this.element).find('select').select2('destroy');
    }
}

And it's template:

<template>
    <select value.two-way="selected" name.one-way="name" id.one-way="name" class="form-control"  data-allow-clear.one-way="allow_clear" size="1">
        <option></option>
        <option repeat.for="src of source" model.bind="src.id">${src.name & t}</option>
    </select>
</template>

I use the control like this:

<select2 name="payingBy" selected.two-way="model.countryId & validate" options.bind="countries" placeholder="${'Select' & t}" allow_clear="true"></select2>

And model is:

countries:Array<{id:number, name:string}> = [{id:1, name:"USA"}, {id:2, name:Canada'}];
model.countryId: number;

Now, everything works fine if I change the select and on initial binding. But if i change the model.countryId from ie. 1 to 2, the change is not reflected in the select control, the control still displays "USA" as like 1 is selected. Because 'selected' property is bind two-way I would expect it to update the select when it change. But it does not. Why? What Am I doing wrong?

Please help

like image 347
Luka Avatar asked Mar 03 '17 10:03

Luka


2 Answers

Ok, I implemented it like in this post:Custom Select2 Aurelia component

And it works perfectly.

like image 68
Luka Avatar answered Oct 04 '22 02:10

Luka


That is because you are using the data version which expects an object, but you have set your select to work with the id value only. So you should use the val to pass the id.

selectedChanged(newValue, oldValue) {
    console.log(newValue);
    if (this.select2) {
      this.select2.select2({
        val: newValue, // << changed this from data: newValue
        theme: 'bootstrap',
        placeholder: this.placeholder
      });
    }
like image 25
Gabriele Petrioli Avatar answered Oct 04 '22 01:10

Gabriele Petrioli