AnglerJS orderby does not work when editing orderby-property

I have a list of objects in my scope and you want to iterate over them, show some of their properties in the order ordered by properties and change them.

ng-repeat is used to display text fields attached to each object of my list, and an ordering filter that takes a "position" as a parameter.

Once again, the position is also editable!

Now we change the position of a certain object once (angular reorders the list as expected), and then we change it twice. Angular does not reorder the list.

Can someone explain how to correct this situation only after registration and what are the reasons for this behavior?

Here is the fiddle: JSFiddle

HTML

<div ng-controller="MyCtrl"> <p>List of activities:</p> <div ng-repeat="activity in model.activities | orderBy: 'position'"> <textarea type="text" ng-model="activity.name"> </textarea> {{activity.name}} <input type="text" ng-model="activity.position"> </div> </div> 

Js

 var myApp = angular.module('myApp',[]); function MyCtrl($scope) { $scope.model = { activities: [ {name: "activity 1", position: 1}, {name: "activity 2", position: 2}, {name: "activity 3", position: 3}, {name: "activity 4", position: 4}, {name: "activity 5", position: 5} ] }; } 
+7
javascript angularjs angularjs-orderby angularjs-model
source share
2 answers

Here it is.

Why does the code behave like this?

position bound to the input text . This makes the text whole at first, and then translates to Strings as soon as you start typing. Then ordering becomes odd and why it fails.

How to fix it?

You have two options. The first option is to change type="text" to type="number" , then it will work. If this is not an option, you can create a simple directive (Angular 1.2 onwards)

 myApp.directive('integer', function() { return { require: 'ngModel', link: function(scope, el, attr, ctrl){ ctrl.$parsers.unshift(function(viewValue){ return parseInt(viewValue, 10); }); } }; }); 

What this code does is to parse each value into an integer, making it work.

+6
source share

This happened because your position property is bound to a text value. This means that your position value becomes a string after editing through the input.

You need to create a custom sort.

For example:

 <div ng-repeat="activity in getOrderedData()"> {{activity.name}} <input type="text" ng-model="activity.position"> </div> $scope.getOrderedData = function(){ return $scope.model.activities.sort(compare); }; var compare = function(a,b){ if (parseInt(a.position) < parseInt(b.position)) return -1; if (parseInt(a.position) > parseInt(b.position)) return 1; return 0; }; 

This will work with every version of AngularJS.

Please take a look at JSFiddle for a full working example.

Hope this helps!

+2
source share

All Articles