1

I have a select (bootstrap-select) in my web page which consist of some data that will update according to some filter. The data is bonded to the select via API.

     <select  appBootstrapSelect  data-live-search="true" [(ngModel)]="mCompany" >
          <option value=''>All</option>
          <option *ngFor="let motherCompany of motherCompanies " [ngValue]="motherCompany.id">                       
           {{motherCompany.name}}
         </option>
     </select>

Some initial data is filled in the select during ngOnInit and this works fine. But when I try to update the options of select via code by changing the model, it does not seem to reflect. One thing I noticed is that if I removed the attribute appBootstrapSelect the select will be having a default style and binding from code works which is the behavior I want.

appBootstrapSelect is a Directive and the code for it is as below

import { Directive, ElementRef, OnInit, OnDestroy } from '@angular/core';

declare var jQuery: any;

/**
 * Directive to wrap bootstrap-select
 */
@Directive({
  selector: '[appBootstrapSelect]'
})
export class BootstrapSelectDirective implements OnInit, OnDestroy {

  private el;

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

  ngOnInit() {
   // wrapping in setTimeout to delay init until after attribute binding
    setTimeout(() => {
      jQuery(this.el).selectpicker({
        iconBase: 'fa',
        tickIcon: 'fa-check'
      });
    },2000);

  }

  ngOnDestroy() {
    jQuery(this.el).selectpicker('destroy');
  }

  refresh() {
    jQuery(this.el).selectpicker('refresh');
  }

  /**
   * Manually dispatch a change event to let Angular know of a programmatic change to the select
   */
  triggerChangeEvent() {
    this.el.dispatchEvent(new Event('change', { 'bubbles': true }));
  }

  /**
   * Select an option in this select by id
   * @param id
   */
  selectOptionById(id) {
    jQuery(this.el).find('#'.concat(id)).prop('selected', true);
    this.triggerChangeEvent();
  }
}

I found a jQuery code I think that need to be called in order for the list to update but not sure how to do the same in angular. I do have a model reference for appBootstrapSelect

 @ViewChildren('appBootstrapSelect') motherCompanyDropdown: ElementRef;

Why might this be happening ? How can I solve this ?

PS: I have also tried ChangeDetectionStrategy but does not work.

1 Answer 1

1
+50

`Hello,

since you already have the refresh method in your directive, all you need to do is call it when updating the options data. To call it from the component you need to use ViewChild like below:

Your component.ts

@ViewChild(BootstrapSelectDirective) motherCompanyDropdown: BootstrapSelectDirective;
//...
update() {
  // new data
  this.motherCompanies = [...];
  // call refresh
  this.motherCompanyDropdown.refresh();
}

But since you use setTimeout it may not work without adding setTimeout too in your refresh method:

Your directive.ts

refresh() {
  setTimeout(() => {
    jQuery(this.el).selectpicker('refresh');
  })
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.