0

I have the following input field

 <input type="text" class="form-control pull-right" ng-model="ceremony.CeremonyFee | number:2">

it is showing up correctly but has been disabled. The error I am receiving is "[ngModel:nonassign] Expression 'ceremony.CeremonyFee | number:2' is non-assignable". I understand why it is in error, but do not know how to get this to work on an input field. Thanks.

1
  • And what do you want to achieve? Commented Dec 8, 2015 at 13:59

4 Answers 4

2

input with ng-model is for inputting data, number filter is for displaying data. As filter values are not bindable, they are not compatible, as you can see. You have to decide what you want to do with that input.

Do you want it to be an input? User can input his own number and you only needs to validate? Use i.e. pattern attribute:

<input type="text" ng-model="ceremony.CeremonyFee" pattern="[0-9]+(.[0-9]{,2})?">

Do you want it to be an output? User does not need to input his own value? Do not use ng-model, use value instead:

<input type="text" value="{{ceremony.CeremonyFee | number:2}}" readonly>
Sign up to request clarification or add additional context in comments.

1 Comment

There is another option that mixes these two: create a directive that displays the second input (with formatted value) and when the user clicks on it it's changed to the first option for edition (using regex pattern). It's an idea that can work if the UI design requires it
0

UPDATE:

really I don't understand what you need, but, if you want just that users can insert only two digits you should use a simple html attributes, have a look on min, max, step...

Follows a pure js solution, but I don't suggest something like that!

angular.module('test', []).controller('TestCtrl', function($scope) {
  var vm = $scope;
  var testValue = 0;
  Object.defineProperty(vm, 'testValue', {
    get: function() { return testValue; },
    set: function(val) {
      val = Number(val);
      
      if(angular.isNumber(val) && (val < 100 && val > 0)) {
        console.log(val);
        testValue = val;
      }
    } 
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app="test">
  <div ng-controller="TestCtrl">
    <input style="display:block; width: 100%; padding: 1em .5em;" type="number" ng-model="testValue" />
  </div>
</section>


the ng-model directive requires a viewmodel assignable (or bindable) property, so, you cannot add a pipe...

angular.module('test', [])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="test" ng-init="testValue = 0">
  <label ng-bind="testValue | currency"></label>
  <input style="display:block;" ng-model="testValue" type="number"/>
</div>

1 Comment

I understand what you are doing, but the label is read only. We are wanting the filter applied to the input field. Possibly on blur, or like a 'mask' from my .net days. If there is a solution for it, I would love to hear it.
0

As an error states you have got an 'non-assignable' expression in your ng-model attribute.

You should use only ceremony.CeremonyFee.

| is used on ng-repeat to indicate what expression should be used as filter.

If you want to have that <input> populated with initial data in your controller/link you should give it an initial value ex.

$scope.ceremony = {
    CeremonyFee: 'My first ceremony'
}

And every time your <input> element data will be changed CeremonyFee will be updated as well.

1 Comment

Yeah, new to angular, understanding that. But how would I alter the input of that data? Or would I have to create a new function to work with these fields?
0

I found and used the solution found on this page.

http://jsfiddle.net/k7Lq0rns/1/

    'use strict';
    angular.module('induction').$inject = ['$scope'];
    angular.module('induction').directive('format',['$filter', function ($filter) {
      return {
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            ctrl.$formatters.unshift(function (a) {
                return $filter(attrs.format)(ctrl.$modelValue)
            });

            elem.bind('blur', function(event) {
                var plainNumber = elem.val().replace(/[^\d|\-+|\.+]/g, '');
                elem.val($filter(attrs.format)(plainNumber));
            });
        }
  };
}]);

relatively easy to apply it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.