2

I am using Jquery Selectric on my page to render a select box in my angularJS app, so I decided to create a directive to render the element, below is the directive and how I use it.

The Directive:

angular.module('shoeRevamp.directives')
  .directive('selectric', function () {
    return {
      restrict: 'A',
      scope: {countries: '='},
      controller: function ($scope, $element, $attrs) {
        console.log($scope.countries);
      },
      link: function (scope, el, attrs) {
        if( $("select").length) {
          $(el).selectric();
        }
      }
    };
  });

How I use it (Jade/Pug):

select(selectric ng-model='country' countries='countries' ng-options='country.name for country in countries track by country.symbol')

The Problem

When I load the page and try to open the select box it complains with the error below without displaying any of the countries:

Error Message

jquery.selectric.min.js:1 Uncaught TypeError: Cannot read property 'offsetTop' of undefined

Another Problem

When I add priority: -1000, It displays the countries, but it looses its Selectric styles and behaviour.

I need help.

George
  • 3,757
  • 9
  • 51
  • 86

1 Answers1

1

So technically the problem you have is that when selectric is being initialized on the DOM you your ng-options hasn't populated the DOM yet so selectric has an empty list.

To fix this you need to load the data using the selectric ajax format to build the options and then inject them into the selectric dropdown.

Javascript

.directive('selectric', function ($timeout) {
    return {
      restrict: 'A',
      scope: {countries: '='},
      link: function (scope, el, attrs) {
          var myList = "";
          //Loop through the list of countries and build the options
          for(i = 0; i < scope.countries.length; i++) {
            myList = myList + "<option value='" + scope.countries[i].symbol + "'>" + scope.countries[i].name + "</option>";
          }
          //Start selectric and append option list
          el.append(myList).selectric();
      }
    };
  })
;

HTML

<select ng-model='country' selectric countries='countries'></select>

Couple things that are worth mentioning:

  • You cannot use ng-options natively with selectric, I had tried a hacky solution to put a timeout on using selectric but that created it's own issues
  • Because you cannot use ng-options that also means you can't work with objects as the option value which is going to impose some limitations on your development.
Malkus
  • 3,686
  • 2
  • 24
  • 39
  • I have some issue with this approach, I am not able to access the model unil I change a selected item, accessing it without changin selected item throws error `angular.js:13920 TypeError: Cannot read property 'country' of undefined` – George Sep 06 '16 at 14:57
  • Are you sure there's not a Vanilla JS for doing what you'd like to achieve? JQuery plugins and Angular often spells $timeout() – Christian Bonato Sep 08 '16 at 16:47