Bootstrap-select,angularjs dropdown not working
Asked Answered
L

2

5

I have this issue and hope to get some advice on how to fix it.

I've moved part of my html page into a partial view and loading it through ng-view the problem now is that the dropdown-select doens't work anymore,I managed to get the style back but when I click on it, it doesn't open. When it wasn't in the partial view, I didn't even need to make a javascript call which seems to be required now.

Here's my code

index.html
 <link href="resources/css/bootstrap.min.css" rel="stylesheet">
    <link href="resources/css/bootstrap-select.css" rel="stylesheet">
    <!-- Bootstrap Core CSS -->

    <script src="resources/js/jquery-2.1.1.min.js"></script>
    <script src="resources/js/jquery-1.11.0.js"></script>

    <script src="resources/js/bootstrap-select.js"></script>

    <script src="resources/library/angular.js"></script>
    <script src="resources/library/angular-route.js"></script>
    <script src="resources/js/MainController.js"></script>
    <script src="resources/js/main-app.js"></script>

    partialview.html
    -------------------
     <select class="selectpicker" multiple ng-model="selE">
                    <option ng-repeat="e in ee">{{e}}</option>
                </select>

    <script>
    $(document).ready(function () {

        $('select').selectpicker({
            style: 'btn-default',
            size: false
        });

    });

</script>   

Thank you in advance.

Lepido answered 22/9, 2014 at 10:1 Comment(0)
C
8

Mixing Angular + jQuery is not a good practice. If you want to use any jQuery plugin, you can wrap it into a custom angular directive (official docs).

See a working example of selectpicker directive in this jsFiddle.

html :

<select class="selectpicker"
        multiple
        title='Choose one of the following...'>
  <option>Mustard</option>
  <option>Ketchup</option>
  <option>Relish</option>
</select>

js :

angular.module('demo')
  .directive('selectpicker', function () {
    return {
      restrict: 'C',
      link: function (scope, element) {
        $(element).selectpicker({
          style: 'btn-default',
          size: false
        });
      }
    };
  });

Link to controller

Using require: 'ngModel' in your directive will give you ngModelController as 4th parameter to link function (see doc here).

So you can easyly bind your controller values with directive scope.

See other jsFiddle here.

Directive :

angular.module('demo')
  .directive('selectpicker', function () {
    return {
      restrict: 'C',
      require: 'ngModel',
      link: function (scope, element, attrs, ngModel) {
        var $el = $(element);
        $el.selectpicker({
          style: 'btn-default',
          size: false
        });
        $el.on('change', function (ee, aa) {
          ngModel.$setViewValue($el.val());
          scope.$apply();
        });
      }
    };
  });

Controller :

angular.module('demo')
  .controller('MainCtrl', function ($scope) {
    $scope.selected = [];
  });

HTML :

You have selected : {{ selected | json }}
<select ng-model="selected"
        class="selectpicker"
        multiple
        title='Choose one of the following...'>
  <option>Mustard</option>
  <option>Ketchup</option>
  <option>Relish</option>
</select>

Passing options in parameter

See 3rd jsFiddle.

To pass options dynamically, simply update your directive :

angular.module('demo')
  .directive('selectpicker', function ($timeout) {
    return {
      restrict: 'C',
      require: 'ngModel',
      replace: true,
        template: '<select multiple><option ng-repeat="opt in options">{{ opt }}</option></select>',
      scope: {
        options: '='
      },
      link: function (scope, element, attrs, ngModel) {
        var $el = $(element);
        $timeout(function () {
          $el.selectpicker({
            style: 'btn-default',
            size: false
          });
        });
        $el.on('change', function (ee, aa) {
          ngModel.$setViewValue($el.val());
          scope.$apply();
        });
      }
    };
  });

Then in your html :

<div ng-model="selected"
        class="selectpicker"
        options="issues"
        title='Choose one of the following...'>
</div>
Clactonian answered 22/9, 2014 at 11:7 Comment(9)
Do you think it's more acceptable to use jquery in directives or not use them at all? The issue that I am having is that my code works well but it doesn't work when I put my code in a partial view. I am using ng-view and a partial html file that has the multiselct dropdown. it looks exactly the same but when I press on the dropdown,nothing happens, it doesn't open. I tried to change the order of libraries as well but didn't help. I believe my issue is to do with the fact that I am using something in a partial view, although all the bootstrap,angular libraries are being loaded.Lepido
Yes, it's acceptable to use jQuery in directives. What you want to avoid is selecting element with jQuery. Directive makes it for you (see the example). See my edit answer for binding to controllerClactonian
The problem is that the dropdown does only work when you have static values. I have changed your example so it uses ng-options. Now you will notice that it doesn't work jsfiddle.net/7hree57z/3Lepido
There is no refs to ngOptions in your initial question. Maybe update it or create a new one ?Clactonian
the jsfiddle that I have posted in my previous comment is how my code is set now; I have tried both ng-repeat(initially) and ng-options. both are giving the same issue. if you check the following example, you will notice that you can't open the dropdown jsfiddle.net/7hree57z/3Lepido
Thank you so much, your last example worked perfectly; the only problem is that it seems like there's no straight way to do this, it requires to create a directive; do you know why the conventional ng-options and/or ng-repeat doesn't work in this case? How do I set your last comment as the solution?Lepido
because ngRepeat and ngOptions are directives too, and they dont communicate with your custom directive template. I'have updated my initial answer with the last example, so you can accept it.Clactonian
I'm trying to get my head around how to work with jqueries inside directives. There's one method that I'd like to implement but not sure how to do it. I want to be able to deselect all the selected item in the dropdown by making a call from the controller. Now there's a method for bootstrap-select called $('.selectpicker').selectpicker('deselectAll'); But it doesn't work in the controller and I've tried putting the following code in the directive: $el.on('deselectAll', function (ee, aa) { ngModel.$setViewValue(null); scope.$apply(); }); How do I implement it?ThanksLepido
sorry but it's not the place for discussion here. make a new question if neededClactonian
P
2

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 happened. I suppose the plugin's methods only works inside that function.

Polybius answered 19/11, 2017 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.