ng-options not working as expected - angularjs

I'm having an issue trying to loop through an array of objects using ng-options.
html
<select class="select-width" ng-options="type as type.name for type in types">
js
$scope.types = [{name: "Advanced Yield Analysis"},
{name: "Yield by Hybrid"},
{name: "Yield by planting data"},
{name: "Yield by soil type"},
{name: "Yield by management zone"},
{name: "Yield by population/seeding rate"},
{name: "Yield by Treatment"},
{name: "Total Yield by Grower / Location / MC"}];
Here is a JS-fiddle.

You only need to pass the ng-model. Ng-options will not work when you're not assigning a model.
By default, ngModel watches the model by reference, not value. This is
important when binding any input directive to a model that is an
object or a collection.
try
<select class="select-width" ng-model="demo" ng-options="type as type.name for type in types"></select>
Fiddle

Related

array in object in ng-options

I am having problems in getting an array inside of an object into an ng-options.
I have following array of objects with inside another array:
$scope.array = [{name: "jan", ar=["car", "bus", "bike"]}, {name: "tom", ar=["milk", "water", "bike", "walking"]}, {name: "kim", ar=["star", "car"]}]
I would like to make a select with the options jan, tom and kim. But that isn't a problem:
<select ng-options="o.name for o in array" ng-model="choosen.nOption">
however when they choose an option a new select should start with as options the array ar from that name:
<select ng-if="choosen.nOption!=undefined" ng-options="o.ar for o in array.ar | filter: {name: choosen.nOption}">
Can anyone help how I could get the values of the inside array?
You can find a fiddler at https://jsfiddle.net/brokenhip/phxyap8a/
Solution:
https://jsfiddle.net/brokenhip/phxyap8a/2/
<select ng-options="o.name for o in arrayA" ng-model="choosen.nOption"></select>
<select ng-if="choosen.nOption!=undefined" ng-options="o for o in choosen.nOption.ar" ng-model="choosen.nOption2"> </select>
So i found an easy way is to use $watch to see when the first select change.
In your controller add this :
$scope.$watch('choosen.nOption',function(newVal){
$scope.choosenOption = newVal['ar'];
console.log($scope.choosenOption); // check in your console
});
And in your HTML, you don't need a filter:
<select ng-if="choosen.nOption!=undefined" ng-options="opt for opt in choosenOption" ng-model="choosen.nOption2"> </select>

"Contains" search for a sub-element of an object array

Here's my data:
[
{profile: {name: "Test123"}}
]
I have a text input, like so:
<input ng-model="searchText">
I'm trying to do a search on profile.name using the textbox input.
I've tried making a custom filter, like so:
$scope.searchFilter = function(value){
return value.profile.name.indexOf($scope.searchText) != -1;
};
Then filtering like so:
<tr ng-repeat="profile in profiles | filter: searchFilter"></tr>
It seems unfortunately that this works fine on the initial search, but when entering text into the textbox the filter is not re-evaluated.
How can I force Angular to re-check the filter when I enter text into the search box, or is there a better way to do this?
You don't need to create a function to search. Just change your html into this:
<input ng-model="searchText.profile.name" />
...
<tr ng-repeat="data in profiles | filter: searchText">{{data.profile.name}}</tr>
In your controller:
$scope.searchText = { profile: {name:""}}; //should be the same data struct with your search target.
$scope.profiles = [
{profile: {name: "Someone"}},
{profile: {name: "Luky"}},
{profile: {name: "John"}},
{profile: {name: "Mary"}},
{profile: {name: "Howard"}},
{profile: {name: "Sheldon"}}
]
Then it works. Here is jsfiddle. : )
And here is filter document.

AngularJs dropdown values clearing out model value

My dropdown html looks like this:
<select name="originType" class="form-control"
ng-model="myLocationType"
ng-options="type.Key as type.Value for type in allLocationTypes"
required></select>
This works fine to populate the dropdown. However, when I'm loading the page and populating it with model data, the value that should be selected never is. The dropdown is always on the default (blank) value. I have no problem with dropdowns that are not key/value pairs. For example:
<select name="shipId" class="form-control"
ng-model="WageAgreement.ShipId"
ng-options="shipId for shipId in manufacturers"
required></select>
Populating the model value should work if the model value matches up with the supplied value in the array. See http://jsfiddle.net/5qp54/2/ where 2 is selected when set as the model value for WageAgreement.ShipId
var mod = angular.module("myApp", []);
mod.controller("MainController", function ($scope) {
$scope.allLocationTypes = [
{Key: 1, Value: "Shipyard 1"},
{Key: 2, Value: "Shipyard 2"},
{Key: 3, Value: "Shipyard 3"}
];
$scope.WageAgreement = {};
//Populate value here
$scope.WageAgreement.ShipId = 2;
});
Does your model value match the Key in your object array? I suspect something isn't matching up if it is not selecting the value on the dropdown.
If this doesn't answer your question, can you update your post with a jsfiddle or sample of how you populate manufacturers/allLocations and WageAgreement?

Binding ng-repeat and ng-model in controller

This is my first post on here so bear with me, I'm fairly new to AngularJS as well. I'm trying to build a form with ng-repeat and having trouble wrapping my head around the angular stuff.
JS in controller:
$scope.myCurrentAssets = {
cash_equiv: {name: 'Cash & Equivalents', value: 0, tbi: 41},
invest: {name: 'Short Term Investments', value: 0, tbi: 42},
notes_rec: {name: 'Notes Receivable', value: 0, tbi: 43},
account_rec: {name: 'Accounts Receivable', value: 0, tbi: 44},
inventory: {name: 'Inventory', value: 0, tbi: 45},
prepaid: {name: 'Prepaid Expenses', value: 0, tbi: 46},
other: {name: 'Other Current Assets', value: 0, tbi: 47}
};
HTML:
<div class="row" ng-repeat="(keyAssets, valueAssets) in myCurrentAssets">
<span>{{valueAssets.name}}</span>
<input data-name="myCurrentAssets.{{keyAssets}}"
data-ng-model=""
data-placeholder="{{valueAssets.value}}"
data-ng-change="compute()"
/>
</div>
The problems I'm having are:
trying to get the 'data-ng-model' set to something unique in each instance of the ng-repeat
how do I access the value of the input field from the compute() function?
trying to get the 'data-ng-model' set to something unique in each instance of the ng-repeat
You can use list[key][value] that will be different per item in ng-repeat
how do I access the value of the input field from the compute() function?
Generally you can use ng-model that automatically fetches input data.
<div class="row" ng-repeat="(keyAssets, valueAssets) in myCurrentAssets">
<span>{{valueAssets.name}}</span>
<input data-name="myCurrentAssets[keyAssets]['name']"
data-ng-model="myCurrentAssets[keyAssets]['value']"
data-placeholder="myCurrentAssets[keyAssets]['value']"
data-ng-change="compute(myCurrentAssets[keyAssets]['value'])"
/>
</div>
Demo Fiddle

declaring two object literals in (one?) data-ng-init and binding them to different views

I'm trying to create two different object literals and bind them to different views (<table>s). However, I'm not sure how to go about doing this. I've tried the below method where I declare both object literals in one data-ng-init of a parent container (the div). I've also tried having two different data-ng-init directives for that div and having one object literal in each of the directives. However both methods did not work and I get errors (will post if anyone would like to see them).
Example of what I've tried:
<div id="recipes" data-ng-init="
dessertsdrinks = [
{name: 'Apple Pie Popcorn', url: 'pdfs/recipes/desserts_and_drinks/Apple Pie Popcorn.pdf'},
{name: 'Zucchini Muffins', url: 'pdfs/recipes/Zucchini Muffins.pdf'}
];
maineats = [
{name: 'Autumn Enchilada Casserole', url: 'pdfs/recipes/Autumn Enchilada Casserole.pdf'},
{name: 'Build your own Taco', url: 'pdfs/recipes/Build your own Taco.pdf'},]
">
<table id="dessertsdrinks">
<th>Desserts and Drinks</th>
<tr data-ng-repeat="recipe in dessertsdrinks | filter:recipesearch | orderBy:'name'">
<td> {{ recipe.name }} </td>
</tr>
</table>
<table id="maineats">
<th>Main Eats</th>
<tr data-ng-repeat="recipe in maineats | filter:recipesearch | orderBy:'name'">
<td> {{ recipe.name }} </td>
</tr>
</table>
</div>
When I only have one object literal and one data-ng-init it works perfectly.
But how could I do this with two different lists? Is there a better way?
For example, could I have a controller which binds object literals to $scope based on the view's (table's) id tag or something? Like so :
psuedocode
function recipeController(){
if $scope id == "desertsdrinks" {
$scope.recipes = [{.. dessert and drink recipe obj literal ..}];
} else if $scope id == "maineats" {
$scope.recipes =[{.. main eats recipe obj literal..}];
}
}
Simply moving the objects inside the controller should work:
$scope.dessertsdrinks = [
{name: 'Apple Pie Popcorn', url: 'pdfs/recipes/desserts_and_drinks/Apple Pie Popcorn.pdf'},
{name: 'Zucchini Muffins', url: 'pdfs/recipes/Zucchini Muffins.pdf'}
];
$scope.maineats = [
{name: 'Autumn Enchilada Casserole', url: 'pdfs/recipes/Autumn Enchilada Casserole.pdf'},
{name: 'Build your own Taco', url: 'pdfs/recipes/Build your own Taco.pdf'}
]
No need to change the way you access them inside the html.
You can also pass an object literal directly into the ng-init directive. Each property (name is up to you) value will be evaluated and main avaialble on the scope.
ng-init="{a: dessertDrinks = [...], b: maineats = [...]}"

Resources