Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two-way binding with range and number input in AngularJS

Tags:

angularjs

I'm just starting to play around with AngularJS and trying to understand the binding technique. For starters, I tried to make a simple conversion calculator (dozens to pieces, pieces to dozens). That worked well, but when I tried to bind both a range input and a number input to the same model property the number input does not update when the range value is adjusted. I have a jsfiddle showing the behavior:

common javascript for broken and working fiddles:

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

myApp.controller('CalcCtrl', function ($scope) {
    var num = 0.0;
    $scope.qty = new Quantity(12);
    $scope.num = num;
});

function Quantity(numOfPcs) {
    var qty = numOfPcs;
    var dozens = numOfPcs / 12;

    this.__defineGetter__("qty", function () {
        return qty;
    });

    this.__defineSetter__("qty", function (val) {
        qty = val;
        dozens = val / 12;
    });

    this.__defineGetter__("dozens", function () {
        return dozens;
    });

    this.__defineSetter__("dozens", function (val) {
        dozens = val;
        qty = val * 12;
    });
}

BROKEN FIDDLE

html:

<div ng-controller="CalcCtrl">
    <form>
        <label for="pcs">Pieces:</label>
        <input type="number" min="0" ng-model="qty.qty" size="20" id="pcs"
        />
        <input type="range" min="0" max="100" ng-model="qty.qty" />
        <br/>
        <label for="numOfDozens">Dozens</label>
        <input type="number" min="0" ng-model="qty.dozens" size="20"
        id="numOfDozens" />
    </form>
</div>

However, binding two number inputs to the same model property seems to work fine as shown in this fiddle:

WORKING FIDDLE

html:

<div ng-controller="CalcCtrl">
    <form>
        <label for="pcs">Pieces:</label>
        <input type="number" min="0" ng-model="qty.qty" size="20" id="pcs"
        />
        <input type="number" min="0" max="100" ng-model="qty.qty" />
        <br/>
        <label for="numOfDozens">Dozens</label>
        <input type="number" min="0" ng-model="qty.dozens" size="20"
        id="numOfDozens" />
    </form>
</div>

Any ideas how to get a range and number input bound to a single model property in AngularJS? Thanks.

like image 696
gbc Avatar asked Feb 27 '13 15:02

gbc


People also ask

How do you do two way binding in AngularJS?

Two-way Binding Data binding in AngularJS is the synchronization between the model and the view. When data in the model changes, the view reflects the change, and when data in the view changes, the model is updated as well.

Does AngularJS support two way binding?

AngularJS creates a two way data-binding between the select element and the $ctrl.

Which object is used for two way data binding in AngularJS?

Without $scope object performs two-way binding in AngularJS.

Is NgModel necessary for two way binding?

Because no built-in HTML element follows the x value and xChange event pattern, two-way binding with form elements requires NgModel . For more information on how to use two-way binding in forms, see Angular NgModel.


1 Answers

The problem here is that the input type="range" works with Strings and not with Numbers (while input type="number" only works with Numbers).

http://www.w3.org/wiki/HTML/Elements/input/range

The range state represents a control for setting the element's value to a string representing a number.

If you add val = parseInt(val) as your first instruction on the qty setter it should work:

this.__defineSetter__("qty", function (val) {        
    val = parseInt(val);
    qty = val;
    dozens = val / 12;
});

jsfiddle: http://jsfiddle.net/bmleite/2Pk3M/2/

like image 114
bmleite Avatar answered Oct 03 '22 16:10

bmleite