16

I have a problem with ng-model on a select element when passing an object from option elements. So, imagine we have an array of columns from a table called columns (the table's definition) and we'd like to creat some filters upon this definition

var columns = [
  {name: 'Account ID',    type: 'numeric'},
  {name: 'Full name',     type: 'text'},
  {name: 'Date of birth', type: 'date'},
  {name: 'Active',        type: 'boolean'}
  // and so on
];

var filters = [{}];

HTML:

<div class="form-field" ng-repeat="filter in filters">
  <select ng-model="filter">
    <option value="" disabled>Choose filter</option>
    <option ng-repeat="column in columns" ng-value="column">{{column.name}}</option>
  </select>
  <input type="text" ng-model="filter.value">
</div>

As you can see, I'd like that filter to get the value of column and to add specific data in it, so at a certain moment, my filter could be like:

[
  {name: 'Account ID', type: 'numeric', value: 123},
  {name: 'Active', type: 'boolean', value: 'Yes'}
]

Anyway, I'm not sure this is the way of doing this, but I'd like to know how can I achieve this behavior, withour writing to much js code in the controller.

I did some workaround to get this done using ng-change, passing the filter and the column.name, find the column in the columns array, get the type property, update the filter, but I really think that there is a simpler answer to this.

Michael B
  • 1,660
  • 3
  • 28
  • 59
Chris X
  • 901
  • 3
  • 9
  • 19

1 Answers1

21

You can use ng-options to bind the selected object to a model:

<div class="form-field" ng-repeat="filter in filters">
   <select ng-options="column.name for column in columns" ng-model="filter.value">
         <option value="" disabled>Choose filter</option>
   </select>

   <input type="text" ng-model="filter.value.name">
</div>

Plunker

Updated answer:

<div class="form-field" ng-repeat="filter in filters">
   <select ng-options="column.name for column in columns" ng-model="filters[$index]">
     <option value="" disabled>Choose filter</option>
   </select>

   <input type="text" ng-model="filters[$index].name">
</div>
noj
  • 6,740
  • 1
  • 25
  • 30
  • I've updated that plunker to use 1.1.5 and it still works fine. – noj Jul 29 '13 at 11:12
  • Hmmm, wierd... it works on plunker but not on my local machine. Anyway... why does it work when binded to `filter.value` but not directly on `filter`? Somehow I need the same structure as the table's definition :) – Chris X Jul 29 '13 at 11:19
  • It's due to how javascript behaves when setting values on child scopes. It's a bit much to explain in a comment, so see [this question](http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs). To get around this you can use the `$index` property of an ng-repeat loop to set the value. See the updated [plunker](http://plnkr.co/edit/C3ojySE0x6XbDwHkCD7u?p=preview). – noj Jul 29 '13 at 11:38
  • Great! This is what I wanted... Now it works, thanks a lot! I've tried something like this but since I was using ` – Chris X Jul 29 '13 at 11:52
  • Could you possibly assist with a similar issue I'm having https://stackoverflow.com/questions/63163118/can-we-use-a-ngmodel-directive-with-an-object-property – D.Hodges Jul 29 '20 at 22:10