Nikolay
Nikolay

Reputation: 123

selectivity applied for angularjs select

I try to use selectivity applied to select element, which renders his options via angularjs controller. The problem is that the selectivity applies before angular passes the options to the template. For the protocol - the selectivity styling works fine with static options, but they are not data-binded and static options are not a solution at all.

html

<select id="roleIds" name="roleIds[]" ng-options="role.name for role in roles track by role.id" ng-model="selected_roles" multiple></select>

angularjs

$http
({
    method: "GET",
    url: url,
    isArray: true
}).then
(
    function(response)
    {
        $scope.name = response.data.name;
        $scope.email = response.data.email;
        $scope.roles = response.data.roles;
        $scope.selected_roles = response.data.selected_roles;
        $scope.selected_accesses = response.data.selected_accesses;
        $scope.accesses = response.data.accesses;

        jQuery('#roleIds').selectivity({
          multiple: true,
          tokenSeparators: [' ']
         });
    }
);

How can i achieve this? Is it possible to have nice multiselect while handle the data with angularjs?

Upvotes: 1

Views: 327

Answers (1)

10100111001
10100111001

Reputation: 1832

You can create an Angular directive and apply selectivity in the directive's link function. You can then add the directive to the html template on the selected element. Since the roles are can be updated and retrieved at a later time, I added a watch to the roles object.

angular.module("app", []);
angular.module("app").controller("SelectivityCtrl", function($scope, $timeout) {

  var roles = [{
    id: 1,
    name: "test"
  }, {
    id: 2,
    name: "blah"
  }, {
    id: 3,
    name: "third"
  }];
  $timeout(function() {
    $scope.roles = roles;
    $scope.selected_roles = [];
  }, 1000);
});
angular.module("app").directive("jSelectivity", function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    scope: {
      jSelectivity: "<"
    },
    link: function(scope, elem, attr, modelCtrl) {
      scope.$watch("jSelectivity", function(newValue, oldValue) {
        if (newValue !== oldValue) {
          var test = jQuery(elem).selectivity({
            multiple: true,
            tokenSeparators: [' ']
          });
          $(test).on('change', function(e) {
            modelCtrl.$setViewValue($('#roleIds').selectivity('data'));
            modelCtrl.$render();
          });
        }

      });
    }
  }
});
<link href="https://arendjr.github.io/selectivity/stylesheets/selectivity-jquery.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://arendjr.github.io/selectivity/javascripts/selectivity-jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>

<body ng-app="app">
  <div ng-controller="SelectivityCtrl">
    <select id="roleIds" name="roleIds[]" ng-options="role.name for role in roles track by role.id" ng-model="selected_roles" multiple j-selectivity="roles"></select>
    <p>{{selected_roles|json}}</p>
  </div>

</body>

Update:

I added an onChange event handler on the new selectivity div which will allows us to properly update the model data. I would recommend writing a custom Angular directive that wraps around the functionality of selectivity. This will allow for much more user friendly design and code.

Upvotes: 1

Related Questions