0

I have an angular app in which I want to wait until data is bound to a selection drop down until before I apply a jquery method to the selection drop down.

In my previous related question I was able to populate the drop down successfully using the following code.

 <select name="shippingState" id="shippingState" ng-model="accountAddresses.shippingState"  ng-options ="state.abbreviation for state in states track by state.abbreviation" class="state form-control" size="1">
                       </select>

AngularJS (1.5.8) - How do I populate a select option list directly from within controller that gets a json object?

Now I want to apply the jquery method (a custom selectbox dropdown styling library).

When data loads, I am able to apply the method manually in the browser console. The problem is I can only do the action in the browser console manually.

When the drop down data is fetching I can not run the same method in angular.

Question: How do I can trigger an action when data binding finishes in Angular?

EDIT - I created a directive and modified my html to trigger the directive.

Still I do not get a custom styled element.

Directive Chained to the Root Controller

  directive('onDataBind', function (id) {
                        alert(id);
                          function link(elem, id) {
                            elem.ready(function(id){
                              $scope.CreateDropDown(id);
                              });
                            }
                          })

HTML Modified

           <select name="billingState" id="billingState" ng-model="accountAddresses.billingState"  ng-options ="state.abbreviation for state in states track by state.abbreviation" on-data-bind="CreateDropDown('billingState')" class="state form-control" size="1">
           </select>

Create Drop Down at the Scope Level

   $scope.CreateDropDown = function(id){
      $("#"+id).selectbox();
      //selectbox is the following library - https://github.com/olivM/jQuery-Selectbox
    }
Community
  • 1
  • 1
Vahe
  • 1,699
  • 3
  • 25
  • 76
  • Use a directive and `$timeout()`. – Lex Sep 13 '16 at 23:52
  • @Lex, you beat me to it. Thanks for the help. Please see edits. – Vahe Sep 13 '16 at 23:54
  • I have no action working on this directive yet. Do I need scope to be injected into the function link? – Vahe Sep 13 '16 at 23:54
  • What is `CreateDropDown()`? That's a method on your scope? I thought you wanted to call some jQuery function? Also, that's not how you create a directive. – Lex Sep 13 '16 at 23:55
  • directive constructor is all wrong , a directive should return an object with properties like `link` .. `template` etc – charlietfl Sep 13 '16 at 23:56
  • My CreateDropDown is a function that calls a jquery libarary to style my drop down. Let me post code on this method. – Vahe Sep 13 '16 at 23:57
  • @charlietfl, I had it that way before, I just followed another section of the code I have, I am just getting familiar. – Vahe Sep 14 '16 at 00:00
  • Don't put DOM manipulation code in your controller - that should all go in the directive. – Lex Sep 14 '16 at 00:03
  • I got a solution but is there any way without timeout? – Vahe Sep 14 '16 at 00:26

1 Answers1

0

The following directive code helped resolve the issue. I used a directive and timeout as suggested.

directive('onDataBind', function () {
                  function link(scope, elem) {
                    var id = elem.attr("id");
                    elem.ready(function(){
                     setTimeout(function () {
                       $("#"+id).selectbox();
                     }, 1000);
                      //$('#'+id + ' .sbHolder > .sbOptions').wrap("<div class='optionsDiv'></div>");
                      //$("#"+id + " .sbHolder > a.sbToggle, "+id+" + .sbHolder a.sbSelector").wrapAll("<div class='selectDiv'></div>");
                    })(id);
                    }
                    return {
                      link: link,
                      restrict: 'A',
                    };
                  })
Vahe
  • 1,699
  • 3
  • 25
  • 76
  • Aside from timeout, is there a way to get "id" to be seen within elem.ready rather than the way I do right below the two commetned lines? – Vahe Sep 14 '16 at 00:31