0

I want to implement a dynamic sort into a list of items, by allowing the user to define any number of sort properties based on an available list of property names. The code:

JavaScript (controller)

$scope.data.sortInfo = {};
$scope.data.sortInfo.availableProperties = [
    { PropertyName: "ProjectName", PropertyDisplayName: "Name" },
    { PropertyName: "LastUpdateOnAnsiStr", PropertyDisplayName: "Updated" },
    { PropertyName: "LocationsStr", PropertyDisplayName: "Locations" }
];

// array of selected properties to sort by {Name: {property name}, Direction: {0 = ASC / 1 = DESC}, Priority: {index of sort field (auto filled)} }
$scope.data.sortInfo.selectedProperties = [
    { Name: "ProjectName", Direction: 0, Priority: 0 }
];

HTML

<td ng-repeat="currentSelectedProperty in data.sortInfo.selectedProperties track by $index">
     <!-- debug info -->
     {{currentSelectedProperty.Name}} - {{currentSelectedProperty.Direction}} - {{currentSelectedProperty.Priority}}

      <select ng-model="currentSelectedProperty.Name"
              ng-options="item as item.PropertyDisplayName for item in data.sortInfo.availableProperties track by item.PropertyName">
</td>

Doing this, select is correctly displayed and populated, but I have no option selected. I expect to have ProjectName displayed in the drop-down.

Also, changing the value in the select will correctly change displayed information in the debug fields (Name, Direction and Priority), so ng-model seems to work properly.

I have managed to find a workaround by not using ng-options and explictly ng-repeat the options:

<option ng-selected="{{item.PropertyName == currentSelectedProperty.Name}}" 
        ng-repeat="item in data.sortInfo.availableProperties"
        value="{{item.PropertyName}}">
   {{item.PropertyDisplayName}}
</option>

Question: what is wrong with my ng-options approach?

Angular version is 1.4.3.

Thanks!

Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164

4 Answers4

1

Try below, it should work:

<select ng-model="currentSelectedProperty.Name" ng-init="currentSelectedProperty.Name=data.sortInfo.availableProperties[0]" ng-options="item as item.PropertyDisplayName for item in data.sortInfo.availableProperties track by item.PropertyName">
Suneet Bansal
  • 2,664
  • 1
  • 14
  • 18
  • It worked. Thank you! However, it seems a little weird, since `currentSelectedProperty.Name` is a string and `data.sortInfo.availableProperties[0]` is a `{ PropertyName , PropertyDisplayName }` object. – Alexei - check Codidact Jun 28 '16 at 19:21
  • Yes and the reason is: based on your no-options parameters it is clear that item(which is an object) will be the model and item.PropertyDisplayName will be the display value. Now if you have to change the drop down selection then you will have to assign model to the variable which is binded with ng-model. And also in javascript you can reassign any value to any variable. So initially currentSelectedProperty.Name will be string but when you assign it with model then it became an object. – Suneet Bansal Jun 29 '16 at 04:47
0

Use ng-init or set the default in your controller.

See this previously asked/answered question how to use ng-option to set default value of select element

Community
  • 1
  • 1
n daniel
  • 148
  • 1
  • 10
0

Try this,

$scope.data.sortInfo.selectedProperties =   $scope.data.sortInfo.availableProperties[0]

The problem in your code is that you are having different objects for available properties and selectedproperties.

Alberto
  • 129
  • 1
  • 12
0

You can simply do:

<select ng-model="currentSelectedProperty"
              ng-options="item as item.PropertyDisplayName for item in data.sortInfo.availableProperties track by item.PropertyName">

Reason: currentSelectedProperty is an object which can be mapped to item which is also an object. Since object is contained in an array you need to track it by $index.

Rahul Arora
  • 4,503
  • 1
  • 16
  • 24