Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Added support for numerical ngTrueValue and ngFalseValue attributes #3251

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ var inputType = {
*
* @param {string} ngModel Assignable angular expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} ngTrueValue The value to which the expression should be set when selected.
* @param {string=} ngFalseValue The value to which the expression should be set when not selected.
* @param {string=} ngTrueValue The string or number value to which the expression should be set when selected.
* @param {string=} ngFalseValue The string or number value to which the expression should be set when not selected.
* @param {string=} ngChange Angular expression to be executed when input changes due to user
* interaction with the input element.
*
Expand Down Expand Up @@ -641,11 +641,8 @@ function radioInputType(scope, element, attr, ctrl) {
}

function checkboxInputType(scope, element, attr, ctrl) {
var trueValue = attr.ngTrueValue,
falseValue = attr.ngFalseValue;

if (!isString(trueValue)) trueValue = true;
if (!isString(falseValue)) falseValue = false;
var trueValue = typedValue(attr.ngTrueValue, true),
falseValue = typedValue(attr.ngFalseValue, false);

element.on('click', function() {
scope.$apply(function() {
Expand All @@ -666,6 +663,14 @@ function checkboxInputType(scope, element, attr, ctrl) {
});
}

function typedValue(value, defaultValue) {
if(isString(value)) {
var number = parseFloat(value);
return !isNaN(number) && isFinite(number) ? number : value;
} else {
return defaultValue;
}
}

/**
* @ngdoc directive
Expand Down
167 changes: 150 additions & 17 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -876,32 +876,165 @@ describe('input', function() {
});


it('should allow custom enumeration', function() {
compileInput('<input type="checkbox" ng-model="name" ng-true-value="y" ' +
'ng-false-value="n">');
describe('should allow custom string enumeration', function() {
it('with non empty strings', function() {
compileInput('<input type="checkbox" ng-model="name" ng-true-value="y" ' +
'ng-false-value="n">');

scope.$apply(function() {
scope.name = 'y';
scope.$apply(function() {
scope.name = 'y';
});
expect(inputElm[0].checked).toBe(true);

scope.$apply(function() {
scope.name = 'n';
});
expect(inputElm[0].checked).toBe(false);

scope.$apply(function() {
scope.name = 'something else';
});
expect(inputElm[0].checked).toBe(false);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual('y');

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual('n');
});
expect(inputElm[0].checked).toBe(true);

scope.$apply(function() {
scope.name = 'n';
it('with empty strings', function() {
compileInput('<input type="checkbox" ng-model="name" ng-true-value="something" ' +
'ng-false-value="">');

scope.$apply(function() {
scope.name = 'something';
});
expect(inputElm[0].checked).toBe(true);

scope.$apply(function() {
scope.name = '';
});
expect(inputElm[0].checked).toBe(false);

scope.$apply(function() {
scope.name = 'something else';
});
expect(inputElm[0].checked).toBe(false);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual('something');

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual('');
});
});

describe('should allow custom numerical enumeration', function() {
it('with positive numbers', function() {
compileInput('<input type="checkbox" ng-model="name" ng-true-value="1" ' +
'ng-false-value="0">');

scope.$apply(function() {
scope.name = 1;
});
expect(inputElm[0].checked).toBe(true);

scope.$apply(function() {
scope.name = 0;
});
expect(inputElm[0].checked).toBe(false);

scope.$apply(function() {
scope.name = 'something else';
});
expect(inputElm[0].checked).toBe(false);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(1);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(0);
});
expect(inputElm[0].checked).toBe(false);

scope.$apply(function() {
scope.name = 'something else';
it('with negative numbers', function() {
compileInput('<input type="checkbox" ng-model="name" ng-true-value="-1" ' +
'ng-false-value="-0">');

scope.$apply(function() {
scope.name = -1;
});
expect(inputElm[0].checked).toBe(true);

scope.$apply(function() {
scope.name = 0;
});
expect(inputElm[0].checked).toBe(false);

scope.$apply(function() {
scope.name = 'something else';
});
expect(inputElm[0].checked).toBe(false);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(-1);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(0);
});
expect(inputElm[0].checked).toBe(false);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual('y');
it('with floating point numbers', function() {
compileInput('<input type="checkbox" ng-model="name" ng-true-value="1.3" ' +
'ng-false-value="-1.3">');

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual('n');
});
scope.$apply(function() {
scope.name = 1.3;
});
expect(inputElm[0].checked).toBe(true);

scope.$apply(function() {
scope.name = -1.3;
});
expect(inputElm[0].checked).toBe(false);

scope.$apply(function() {
scope.name = 'something else';
});
expect(inputElm[0].checked).toBe(false);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(1.3);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(-1.3);
});

it('with exponential numbers', function() {
compileInput('<input type="checkbox" ng-model="name" ng-true-value="1e3" ' +
'ng-false-value="1e-3">');

scope.$apply(function() {
scope.name = 1e3;
});
expect(inputElm[0].checked).toBe(true);

scope.$apply(function() {
scope.name = 1e-3;
});
expect(inputElm[0].checked).toBe(false);

scope.$apply(function() {
scope.name = 'something else';
});
expect(inputElm[0].checked).toBe(false);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(1e3);

browserTrigger(inputElm, 'click');
expect(scope.name).toEqual(1e-3);
});
});

it('should be required if false', function() {
compileInput('<input type="checkbox" ng:model="value" required />');
Expand Down