Macilquham
Macilquham

Reputation: 282

Angular2 Custom Directive two way binding

I am trying to write a custom directive that if the user selects the "All" option on a drop down it automatically selects all the options I have been able to get my custom directive selecting all the options but this does not update the model on the consuming component.

Custom Directive

@Directive({ selector: '[selectAll]' })
export class SelectAllDirective {
    private selectElement: any;
    private selectedItemsd:number[];

constructor(private el: ElementRef) {
    this.selectElement = el.nativeElement;
}

@HostListener('change')
onChange() {

    if (this.selectElement.options[0].selected) {
        for (let i = 0; i < this.selectElement.options.length; i++) {
            this.selectElement.options[i].selected = true;
        }
    }
}
}

And the template

  <select selectAll multiple
                                ngControl="shoreLocation"
                                #shoreLocation="ngModel"
                                id="shoreLocation"
                                [(ngModel)]="customTask.shoreLocations"
                                name="shoreLocation"
                                class="form-control multi-select"
                                required
                                style="height:150px">

I have tried creating an @Input and using the banana in a box syntax to try and update the model, I wasn't succesful with that.

I was able to use @Output and emit an event that the consuming component could handle similar to https://toddmotto.com/component-events-event-emitter-output-angular-2 but I would prefer if I could simply update the model automatically.

I am wondering if its possible? Or if creating a custom component similar to http://plnkr.co/edit/ORBXA59mNeaidQCLa5x2?p=preview is the better option.

Thanks in advance

Upvotes: 0

Views: 780

Answers (1)

Steven Luke
Steven Luke

Reputation: 522

Setting the selected state in Javascript doesn't send the "changed" event on the select component (probably because it is direct access to the child option, but not sure). Try triggering the changed event yourself by doing this:

if (this.selectElement.options[0].selected) {
    for (let i = 0; i < this.selectElement.options.length; i++) {
        this.selectElement.options[i].selected = true;
    }
    //These are the two new lines
    let changeEvent = new Event("change", {"bubbles":true, "cancelable": false});
    this.selectElement.dispatchEvent(changeEvent);
}

And see if that triggers the ngModel to get updated.

Upvotes: 1

Related Questions