57

I am trying to use simple jQuery UI. I've included everything and I have this simple script:

<script>
  $(function() {
    $( "#slider" ).slider();
  });
</script>

and

<div id="slider"></div>

My includes:

<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.4.custom.min.js"></script>
<script type="text/javascript" src="js/jquery.easing.1.3.js"></script>
<script type="text/javascript" src="js/ayaSlider.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="js/angular-route.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>

But when I am opening the page there is no slider. According to documentation of angular:

If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery.

However, I don't really understand how can I use angular.element and there is no example.

Update: I managed to have the slider on the screen but it does not work, I cannot change values or do something with it.

enter image description here

11
  • 2
    if you included jQuery, you can just use it normally. Are you getting any errors in your console? Commented Mar 26, 2014 at 15:49
  • execute .slider() when the dom is ready Commented Mar 26, 2014 at 15:50
  • 1
    @Dreamwalker, the questioner already does so. Commented Mar 26, 2014 at 15:51
  • @user, also keep in mind that jQuery UI requires a CSS file to be included in order to work properly. Double-check you have included that file in your page. Commented Mar 26, 2014 at 15:51
  • @Nick No I am not getting any error. I updated the post with my includes list. Commented Mar 26, 2014 at 15:52

4 Answers 4

45

Ideally you would put that in a directive, but you can also just put it in the controller. http://jsfiddle.net/tnq86/15/

  angular.module('App', [])
    .controller('AppCtrl', function ($scope) {

      $scope.model = 0;

      $scope.initSlider = function () {
          $(function () {
            // wait till load event fires so all resources are available
              $scope.$slider = $('#slider').slider({
                  slide: $scope.onSlide
              });
          });

          $scope.onSlide = function (e, ui) {
             $scope.model = ui.value;
             $scope.$digest();
          };
      };

      $scope.initSlider();
  });

The directive approach:

HTML

<div slider></div>

JS

  angular.module('App', [])
    .directive('slider', function (DataModel) {
      return {
         restrict: 'A',
         scope: true,
         controller: function ($scope, $element, $attrs) {
            $scope.onSlide = function (e, ui) {
              $scope.model = ui.value;
              // or set it on the model
              // DataModel.model = ui.value;
              // add to angular digest cycle
              $scope.$digest();
            };
         },
         link: function (scope, el, attrs) {

            var options = {
              slide: scope.onSlide  
            };

            // set up slider on load
            angular.element(document).ready(function () {
              scope.$slider = $(el).slider(options);
            });
         }
      }
  });

I would also recommend checking out Angular Bootstrap's source code: https://github.com/angular-ui/bootstrap/blob/master/src/tooltip/tooltip.js

You can also use a factory to create the directive. This gives you ultimate flexibility to integrate services around it and whatever dependencies you need.

Sign up to request clarification or add additional context in comments.

3 Comments

Using jQuery doesn't necessarily mean things will get messy, it's usually due to poor structure of the code. Ideally you'd want to build out an api within a service using whatever you need and then call those methods within your directive.
angular.element(document).ready(function () { scope.$slider = $(el).slider(options); }); did the trick for me. thanks
How this will be in angular4?
8

This should be working. Please have a look at this fiddle.

$(function() {
   $( "#slider" ).slider();
});//Links to jsfiddle must be accompanied by code

Make sure you're loading the libraries in this order: jQuery, jQuery UI CSS, jQuery UI, AngularJS.

4 Comments

You're not loading the libraries in that order. I supposed you'd need/want to load angular and dependencies before jQuery
@user23236245242 as far as I can tell the fiddle shows exactly what you want. Plus here I added AngularJS to External Resources and it works fine. Take a look at the source-code here.
I meant "The code you posted should be working", provided that you load the libraries in the right order.
This is simple and fine...why not to use this technique instead of the complicated accepted one ?
2

You have to do binding in a directive. Look at this:

angular.module('ng', []).
directive('sliderRange', function($parse, $timeout){
    return {
        restrict: 'A',
        replace: true,
        transclude: false,
        compile: function(element, attrs) {            
            var html = '<div class="slider-range"></div>';
            var slider = $(html);
            element.replaceWith(slider);
            var getterLeft = $parse(attrs.ngModelLeft), setterLeft = getterLeft.assign;
            var getterRight = $parse(attrs.ngModelRight), setterRight = getterRight.assign;

            return function (scope, slider, attrs, controller) {
                var vsLeft = getterLeft(scope), vsRight = getterRight(scope), f = vsLeft || 0, t = vsRight || 10;                        

                var processChange = function() {
                    var vs = slider.slider("values"), f = vs[0], t = vs[1];                                        
                    setterLeft(scope, f);
                    setterRight(scope, t);                    
                }                 
                slider.slider({
                    range: true,
                    min: 0,
                    max: 10,
                    step: 1,
                    change: function() { setTimeout(function () { scope.$apply(processChange); }, 1) }
                }).slider("values", [f, t]);                    
            };            
        }
    };
});

This shows you an example of a slider range, done with jQuery UI. Example usage:

<div slider-range ng-model-left="question.properties.range_from" ng-model-right="question.properties.range_to"></div>

Comments

1

The best option is create a directive and wrap the slider features there. The secret is use $timeout, the jquery code will be called only when DOM is ready.

angular.module('app')
.directive('my-slider', 
    ['$timeout', function($timeout) {
        return {
            restrict:'E',
            scope: true,
            template: '<div id="{{ id }}"></div>',
            link: function($scope) {
                $scope.id = String(Math.random()).substr(2, 8);

                $timeout(function() {
                    angular.element('#'+$scope.id).slider();                    
                });
            }
        };
    }]
);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.