skip to Main Content

I’m trying to update the value of an Ion.RangeSlider when its bound ng-model scope variable changes. The model updates when the Ion.RangeSlider is used, but not vice-versa. Other inputs with the same ng-model update when the model value changes, so this must be some special case.

1

Edit: Woo! Here’s a snippet @lin 🙂 Also jsfiddle.

var app = angular.module('ngModelIonRangeSliderDemo', []);

app.controller('MainCtrl', function ($scope, $rootScope, $timeout) {
    
    $scope.someNumber = 10;
    
}).directive('ionRangeSlider', function ionRangeSlider() {
   return {
      restrict: 'A',
      scope: {
         rangeOptions: '=',
         model: '=ngModel'
      },
      link: function (scope, elem, attrs) {
         scope.$watch('model',function () {
            elem.ionRangeSlider(scope.rangeOptions);
         });
      }
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/js/ion.rangeSlider.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.skinFlat.min.css" />

<div ng-app="ngModelIonRangeSliderDemo">
    <div ng-controller="MainCtrl" class="wrapper">
       <h3>Text input updates slider, but not vice-versa.</h3>
       <input ion-range-slider ng-model="someNumber" range-options="{min: -100, max: 100, step: .001}">
       <br/>
       <input type="text" ng-model="someNumber" class="form-control">
    </div>
</div>

I have tried all kinds of suggestions in over ten somewhat-related stack overflow posts (which is how I have set up the current scope.$watch scheme on the ngModel), but none have worked. There aren’t any errors in my console. What’s wrong? Also, why doesn’t it work without any mention of the model in my directive? Please let me know if there’s anything important I have failed to include in this post.

2

Answers


  1. Just use slider.update() inside your directive and you will be fine:

    var app = angular.module('myApp', []);
    
    app.controller('MainCtrl', function ($scope, $rootScope, $timeout) {
    
        $scope.someNumber = 15;
        $scope.apply = false;
    
    }).directive('ionRangeSlider', function ionRangeSlider() {
       return {
          restrict: 'A',
          scope: {
             rangeOptions: '=',
             model: '=ngModel',
             apply: '=apply'
          },
          link: function (scope, elem, attrs) {
             elem.ionRangeSlider(scope.rangeOptions);
             scope.$watch('apply',function () {
              if (scope.apply) {
                scope.apply = false;
                var slider = elem.data("ionRangeSlider");            
                slider.update({
                   from: scope.model
                });
              }
             });
          }
       }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/js/ion.rangeSlider.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.1.6/css/ion.rangeSlider.skinFlat.min.css" />
    
    <div ng-app="myApp" ng-controller="MainCtrl" class="wrapper">
      <h3>Text input updates slider and vice-versa.</h3>
      <input ion-range-slider ng-model="someNumber" apply="apply" range-options="{min: -100, max: 100, step: .001}">
      <br/>
      <input type="text" ng-model="someNumber" class="form-control" ng-change="apply = true">
    </div>
    Login or Signup to reply.
  2. Extra demo, how binding ion.rangeSlider to input works:

    http://jsfiddle.net/IonDen/r5aox84v/

    var $range = $(".js-range-slider"),
        $inputFrom = $(".js-input-from"),
        $inputTo = $(".js-input-to"),
        instance,
        min = 0,
        max = 1000,
        from = 0,
        to = 0;
    
    $range.ionRangeSlider({
        type: "double",
        min: min,
        max: max,
        from: 200,
        to: 800,
        onStart: updateInputs,
        onChange: updateInputs
    });
    instance = $range.data("ionRangeSlider");
    
    function updateInputs (data) {
        from = data.from;
        to = data.to;
    
        $inputFrom.prop("value", from);
        $inputTo.prop("value", to); 
    }
    
    $inputFrom.on("input", function () {
        var val = $(this).prop("value");
    
        // validate
        if (val < min) {
            val = min;
        } else if (val > to) {
            val = to;
        }
    
        instance.update({
            from: val
        });
    });
    
    $inputTo.on("input", function () {
        var val = $(this).prop("value");
    
        // validate
        if (val < from) {
            val = from;
        } else if (val > max) {
            val = max;
        }
    
        instance.update({
            to: val
        });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search