Marek123
Marek123

Reputation: 1211

AngularJS - Jquery Slider loading

I'm trying to use a jquery plugin within a partial in angularjs.

Directive:

app.directive('slideit',function() {
    return function(scope, elm, attrs) {
        elm.bxSlider({
          adaptiveHeight: true,
          mode: 'fade'
        });
    };
});

HTML:

<div id="sliderwrapper" >
    <ul class="slider" slideit>
        <li ng-repeat="image in dealer.images"><img ng-src="{{image}}" alt="" /></li> 
    </ul>
</div>  

The output shows me, that the bxSlider() is successfully running on the directive. But the list and/or the tags are not touched. Just with normal AngularJS code but not with the jQuery plugin.

What I'm doing wrong?

Upvotes: 2

Views: 4983

Answers (4)

Mohsen
Mohsen

Reputation: 1422

just maintain the dependency of file js file!

 <script src="/yii-application/frontend/web/js/libraries/angular/angular.min.js"></script>
 <script src="/yii-application/frontend/web/js/libraries/angular/angular-ui.js"></script>
 <script src="/yii-application/frontend/web/js/recordata/country.js"></script>
 <script src="/yii-application/frontend/web/js/libraries/jquery/jquery-1.11.3.min.js"></script>
  <script src="/yii-application/frontend/web/js/libraries/flex/jquery.bxslider.min.js"></script>
  <script src="/yii-application/frontend/web/assets/e3dc96ac/js/bootstrap.min.js"></script>
  <script src="/yii-application/frontend/web/js/libraries/jquery-ui/jquery-ui.min.js"></script>
  <script src="/yii-application/frontend/web/js/searchResult.js"></script>
  <script src="/yii-application/frontend/web/js/Flight.js"></script> 

like below!!!!

Upvotes: 0

asgoth
asgoth

Reputation: 35829

This works. It has an ng-repeat within the directive. The bxSlider gets started on ready() of the element.

app.directive('slideit',function() {
    return {
       restrict: 'A',
       replace: true,
       scope: {
         slideit: '=' 
       },
       template: '<ul class="bxslider">' +
                   '<li ng-repeat="slide in slides">' +
                     '<img ng-src="{{slide.src}}" alt="" />' +
                   '</li>' +
                  '</ul>',
       link: function(scope, elm, attrs) {
          elm.ready(function() {
            scope.$apply(function() {
                scope.slides = scope.slideit;
            });                    
            elm.bxSlider({
              adaptiveHeight: true,
              mode: 'fade'});   
            });
       }
    }; 
});

HTML:

<div slideit="images"></div>

Edit: Here is a plnkr.

Upvotes: 1

pavelgj
pavelgj

Reputation: 2701

I believe the issues is with the timing. "slideit" directive is invoked before your list is rendered, and afterwards it's totally redrawn again by ngRepeat and bxSlider doesn't even suspect that this is happening.

Just to validate this hypothesis (don't use this in production, as it's very ugly and might not even work if your model changes) try:

app.directive('slideit',function() {
    return function(scope, elm, attrs) {
        setTimeout(function() {
            elm.bxSlider({
              adaptiveHeight: true,
              mode: 'fade'
            });
        }, 100);
    };
});

There's a bigger issue here: you're trying to "compile" HTML with both Angular an JQuery and they are not necessarily compatible. To avoid the clashes, I'd recommend rendering the list by hand inside your directive and then calling bxSlider on that dynamically constructed DOM. It's not pretty, but it should be more stable. Ex:

<ul slideit="dealer.images"></ul>

directive:

app.directive('slideit',function() {
    return function(scope, elm, attrs) {
        scope.$watch(attrs.slideit, function(images) {
            var html = '';
            for (var i = 0; i < images.length; i++) {
                 html += '<li><img ng-src="' + images[i] + '" alt="" /></li>';
            }
            elm[0].innerHTML = html;
            elm.bxSlider({
              adaptiveHeight: true,
              mode: 'fade'
            });
        });
    };
});

(I haven't tested this, it's just an idea)

Upvotes: 2

Marek123
Marek123

Reputation: 1211

Figured it out:
Add the following directives:

app.directive("mySlider", function() {
    return {
        restrict: 'E',
        replace: true,
        scope: true,
        template: '<ul class="slider"><li check-last ng-repeat="image in dealer.images"><img ng-src="{{image}}" alt="" /></li></ul>'
    };
});
app.directive('checkLast', function () {
        return function (scope, element, attrs) {
            //console.log(scope.$position);
            if (scope.$last=== true) {
                element.ready(function () {
                    $('.slider').bxSlider({
                      mode: 'fade',
                      pager: false
                    });    
                })
            }
        }
    });

Upvotes: 0

Related Questions