0

I have a dropdown with a backing JSON like this:

$scope.tradestyles = [
    {"id":"1","source":"Source One","name":"Name One"},
    {"id":"2","source":"Source Two","name":"Name Two"}
]

This is the dropdown, using select2, the model is the ID of the selected tradestyle:

<select id="tradestyle" ui-select2 ng-model="currentTradestyle" >
    <option ng-repeat="tradestyle in tradestyles" value="{{tradestyle.id}}">
        {{tradestyle.name}}
    </option>
</select>

Next to it, I want to place a text field where the selected tradestyle's name is shown and can be edited.

<input type="text" ng-model="currentTradestyle" />

How do I change the model of the latter to point to the selected tradestyle's name rather than the ID? In other words, how do I traverse the scope object to point to the sibling name value of the selected ID value?

Jeroen Kransen
  • 1,379
  • 3
  • 19
  • 45

3 Answers3

2

If i have understood your question correctly, you need to use ng-options for binding to a object rather than a field. So it becomes

 <select id="tradestyle" ui-select2 ng-model="currentTradestyle" ng-options="style.name for style in tradestyles">

        </select>
 <input type="text" ng-model="currentTradestyle.id" />
 <input type="text" ng-model="currentTradestyle.name" />

See my fiddle here http://jsfiddle.net/cmyworld/UsfF6/

Chandermani
  • 42,589
  • 12
  • 85
  • 88
  • Thanks, but ui-select2 is incompatible with ng-options. I hope to get an answer that is compatible with ui-select2. – Jeroen Kransen Feb 28 '14 at 14:00
  • Hmmm, maybe you can try `ng-click` over the `option` `ng-repeat` and manually select the item in controller. – Chandermani Feb 28 '14 at 14:04
  • If you put a ng-click in an ng-repeat you are going to create as many event handlers as elements you've got in that repeat, I don't think it's a valid solution. – Wawy Feb 28 '14 at 16:25
  • Something like this `ng-click="currentTradestyle=tradestyle"` – Chandermani Feb 28 '14 at 16:38
2
<div ng-app="myApp">
    <div ng-controller='Ctrl'>
        <select id="tradestyle" ng-model="currentTradestyle" update-model="tradestyles">
            <option ng-repeat="style in tradestyles" value="{{style.id}}">{{style.name}}</option>
        </select>
        <input type="text" ng-model="currentTradestyle.name" />
    </div>
</div>

JavaScript:

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

app.controller('Ctrl', ['$scope', '$rootScope', function ($scope, $rootScope) {
    $scope.tradestyles = [{
        "id": "1",
        "source": "Source One",
        "name": "Name One"
    }, {
        "id": "2",
        "source": "Source Two",
        "name": "Name Two"
    }];
}]);


app.directive('updateModel', function() {
    return {
       require: '?ngModel',
       restrict: 'A',
       link: function(scope, element, attrs, modelCtrl) {
           function parser(value) {
               if(value) {
                   return _.findWhere(scope[attrs.updateModel], {id: value});
               }
           }
           modelCtrl.$parsers.push(parser);
       },
    }
});

This might satisfy the issues you raised in your comment. It uses tradestyle.id rather than $index in the <option>s which means the selected item works in cases where a filter is applied to the collection. The additional of a $parser ensures the tradestyle.id actually becomes the selected tradestyle item before being applied to the currentTradestyle model property.

Theres a dependency on Underscore but you can remove that with a more long hand alternative to the findWhere() method.

http://jsfiddle.net/asperry1/Zfecq/6/

asperry
  • 21
  • 2
1

I believe what you are looking for is something like this:

<div ng-app="myApp">
    <div ng-controller='Ctrl'>
        <select id="tradestyle" ui-select2 ng-model="currentTsIndex">
            <option ng-repeat="tradestyle in tradestyles" value="{{$index}}">{{tradestyle.name}}</option>
        </select>
        <input type="text" ng-model="tradestyles[currentTsIndex].name" />
    </div>
</div>

Working fiddle:

Wawy
  • 6,259
  • 2
  • 23
  • 23
  • Thanks, that should work in my situation. I would find it more elegant to use the IDs as dropdown values, and `currentTradestyle.name` looks nicer than `tradestyles[currentTsIndex].name`, but I don't want to be religious about that. – Jeroen Kransen Feb 28 '14 at 15:21
  • Another problem that I'm having is that Angular can't keep track of the changes I make in the edit fields, and updates the dropdown later instead of synchronous with my typing. – Jeroen Kransen Feb 28 '14 at 16:18
  • must be a ui-select2 issue – Jeroen Kransen Feb 28 '14 at 17:04