2

I want to create an Angular directive to use the bootstrap-select plugin and specifically the option to use a data-subtext attribute on the <option> tag as shown here which would require something like this :

html markup

<select>
    <option data-subtext="Mustard's yellow" >Mustard</option>
    <option data-subtext="Ketchup's red">Ketchup</option>
    <option data-subtext="I don't know about Relish">Relish</option>
</select>

javascript

$('select').selectpicker({showSubtext:true});

I think ng-options is out of the question since I have to add the data-subtext to each <option> tag (correct me if I'm wrong).

What I have so far is this :

index.html

<select ng-model="idCourse" class="form-control input-sm" data-live-search="true" select-picker>
    <option ng-repeat="c in cources" value="{{c.id}}" data-subtext="{{c.name}}">{{c.code}}</option>
</select>

module.js

angular.module('myApp', [])

  .controller('ctrl',['$scope', function($scope){
    $scope.courses = [
      {id:1, code:'CS1607', name:'computer science beginner'},
      {id:2, code:'PH006', name:'Quantum physics'},
      {id:3, code:'CSB-9', name:'Machine Learning'}
      ];
  }])
  
  .directive('selectPicker', function(){
    return {
      restrict: 'A',
      link:function(scope, elem){
        elem.selectpicker({showSubtext:true});
      }
    };
});

The problem I'm having is that the select plugin is called before angular could fill it with the data, I've created a plunker for the code. Thanks for the help.

EDIT

As mer10z_tech suggested, using $timeout solved the problem :

//omitted...
.directive('selectPicker', ['$timeout', function($timeout){
    return {
      restrict: 'A',
      link:function(scope, elem){
        $timeout(function() {
          elem.selectpicker({showSubtext:true});
        }, 0);
      }
    };
}]);
Community
  • 1
  • 1
snajahi
  • 900
  • 2
  • 14
  • 26
  • you need to transclude child elements in your directive. Check transclude docs. – Quad May 27 '14 at 13:15
  • I added the `transclude:true`to my directive, still no luck. – snajahi May 27 '14 at 13:19
  • simply adding transclude:true will of course not work, you have to handle the transcluded elements, as i said check transclude docs/tutorials. – Quad May 27 '14 at 13:20
  • 2
    in your directive you can wrap the elem.selectpicker call in a timeout function: `$timeout(function() {elem.selectpicker({showSubtext:true});}, 0);` http://plnkr.co/edit/y60KQd – mer10z_tech May 27 '14 at 13:26
  • @mer10z_tech the code worked as expected with hardcoded cource list but when I started fetching the data from the server the select is empty again. Is there a way to listen for the promise's success event or something? – snajahi May 27 '14 at 14:17
  • @snajahi, R u calling elem.selectpicker.refresh() to update the option list..? I have just implemented a ajax call using this question and http://stackoverflow.com/questions/14284263/refresh-bootstrap-scrollspy-after-angular-model-changes . I should warn you that mutliple select is getting hanged if the option list is huge – saiki4116 Sep 30 '14 at 12:28
  • @saiki4116 care to share a plunker or maybe update http://plnkr.co/edit/vSfh9HwIIxvN4RGXhuvK?p=info cuz I don't see how I would access the `elem` inside the controller where I perform the AJAX call. thanks in advance. – snajahi Sep 30 '14 at 14:05
  • 1
    @snajahi, The code snippet you have shared is working, may be you should increase time out. I have edited yours for the ajax call, it is available at http://plnkr.co/edit/gk8N3MCzBxusvPwAPbyi?p=preview hope it would be useful for you :) – saiki4116 Oct 01 '14 at 13:18

2 Answers2

0

I would bind your selectPicker plugin after angular compiles the view. Her is how to do that

function MyCtrl($scope) {
    angular.element(document).ready(function () {
        $('select').selectpicker({showSubtext:true});
    });
}

It is equivalent of $(document).ready()

0

I know the post was made long time ago but I hope this solution will be helpful for others.

I got another solution to the issue related.

What I did was first load my data from back-end using angularjs and inside the .success after my validation I wrote the following code:

angular.element(document).ready(function () {
    $('select').selectpicker("destroy"); 
    $('select').selectpicker("render"); 
});

I tried to do it without angular.element(document).ready(function (){}) but nothing happend. I suppose the plugin's methods only works inside that function.