How to use a dynamic ng-repeat depending on user input - javascript

I need to use two ng-repeat: one shows car brands and the other shows car models. This last one should only present the models of the selected car brands, but I have no ideia how to do it.
My two JSON files have this structure:
{
"brands" : [
{
"id": 0,
"name": "Alfa Romeo",
"short_url": "alfa-romeo"
},
{ "models" : [
{
"id": 0,
"brand_id": 0,
"name": "MiTo"
}, ...
And my HTML is looking like this:
<label>Brand
<input list="brands" name ="brand" type="text" placeholder="Select your brand...">
<datalist id="brands">
<option ng-repeat="b in brands">{{b.name}}</option>
</datalist>
</label>
<label>Model
<input list="models" name ="models" type="text" placeholder="Select your model...">
<datalist id="models">
<option ng-repeat="m in models">{{m.name}}</option>
</datalist>
</label>
I need to compare the models' brand_id with the selected brand's id. I heard about ng-if so i tryied this (didn't work):
<div ng-if="models.brand_id === b.id">
Any help is appreciated :)

You don't need an input when making a selection. You can use the select element.
To get this to work you need to first communicate to your app that something has changed. Try changing your first input to a select element and putting an onchange handler in it. When a brand is selected we will save the models of that brand to the $scope and render them in the Models section. We can use ng-if to display the Models selection, only if a brand selection has been made.
Going forward you can then use a similar pattern for when making a model selection
We can set the value of the select options by using the "as" keyword.
b.id as b.name means that we will display the name, but store the value of the id.
<label>Brand
<select onchange="handleChange" ng-options="b.id as b.name for b in brand"/>
</label>
<label>Model
<select ng-if="modelsOfSelectedBrand" ng-options="m.id as m.name for m in models"/>
</label>
Then in your directive
$scope.handleChange((e) => {
// filter out models that are not from the selected brand
$scope.modelsOfSelectedBrand = $scope.models.filter(model => model.brand_id === e.target.value)
})
EDIT: correctly use ng-options

Related

AngularJS Select index of selected property

I have a request that returns an array of objects based on a Provider selected. Like this:
data:[
0:
Producto:"Chiken",
Unidad: "box",
PrecioUnitario:"34334",
etc..
1:
Producto:"Chiken",
Unidad: "box",
PrecioUnitario:"200",
etc..
]
I'm displaying the data properly in a <select> tag
What I want is that if the user selects let's say "Carne Asada" all of the other properties of that selected child object are auto-selected on the rest of the fields, i.e:
Unidad text input should be "box" automatically, "precioUnitario" field should be 200.
Or visually:
Another thing is that it should display the value that the object has but it can be edited by the user.
Controller:
$scope.columns = [{colId: 'col1', producto:[], catidad:'', unidades:[], preunit:''}];
$scope.fact = {};
$scope.get_proveedor_prod = function(fact){
var data = {ProveedorID: fact.ProvID};
$http.post(URL + "/api/get_prod_by_provider.php",data).then(function(callback) {
$scope.products = callback.data;
});
}
View:
<md-input-container>
<select ng-model="fact.producto"
ng-options="item.ProductID as item.NombreProducto for item in products"
class="form-control selectformcc" required>
<option value="" disabled selected>Producto</option>
</select>
</md-input-container>
(I'm assuming your data notation is incorrect and that you meant to use an array of objects.)
Bind the select to the whole item instead of to a property of the item:
ng-options="item as item.NombreProducto for item in products" //not ="item.ProductID...
Now fact.producto (select model) is an object and will contain the whole item. In your Unidad text box you can use:
<input type="text" ng-model="fact.producto.Unidad" />
Here is an example with easy to understand data: Working Fiddle

Using ng-options for a select field inside an ng-repeat how do I filter out previously selected values?

I am creating a select dropdown that can dynamically be added by the user. Clicking a button will execute the following line: "$scope.expenses.push({});" adding a new select dropdown to the page for them to choose from.
This piece is working perfectly fine. But I am running into the issue of the user being able to select the same item in both fields. I have not been able to successfully filter out any other selected values from the dropdown fields. Any pointers would be lovely!
I'm thinking either a custom filter to hide the other selected values or an ng-change function to update the array I am looping over..
Here is my current code:
<div ng-repeat="expense in expenses track by $index">
<label for="itemDescr_{{$index + 1}}">${item_descr}</label>
<select id="itemDescr_{{$index + 1}}" name="itemDescr_{{$index + 1}}" ng-model="expenses[$index].ItemCode" ng-class="{submitted:submitted}" required ng-options="benefit.Code as benefit.Description for benefit in purchDescOptions | removeUsedItemsFilter | orderBy:'Description'">
<option value="">Please select</option>
</select>
</div>
Here is the array ($scope.purchDescOptions) I am looping over:
[
{
Code:"HOU",
Description:"Housewares"
},
{
Code:"ATO",
Description:"Auto Parts, Equipmnt"
},
{
Code:"APP",
Description:"Appliances"
},
{
Code:"CLO",
Description:"Clothing"
}
]

Angular 1.5 "track by" ruines binding in ng-options

I need to select option in combobox from ajax loaded data. That data comes as list of objects. The problem is that ng-option compares objects by reference and thus setting model to objects element results in appearing new empty option in combobox instead of selecting correct option.
The known workaround is to use track by expression.
And here is example code:
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.roles =[
{ key:"administrator", value:"ROLE_ADMIN" },
{ key:"operator", value:"ROLE_OPERATOR" },
];
// this emulates data from server
// won't work without 'track by'
$scope.role={ key:"administrator", value:"ROLE_ADMIN" };
});
Template:
<body ng-app="myApp" ng-controller="myCtrl">
0: <input ng-model="roles[0].key" />
<br>
1: <input ng-model="roles[1].key" />
<br>
select role: <select ng-model="role" ng-options="r.key for r in roles track by r.value">
</select>
<pre>selected role={{role|json}}</pre>
</body>
Here another problem arises. When one selects role in combobox and then
changes it's "key" property in textbox, then selected role stays unchanged. So it looks like binding is suddenly gets broken.
https://jsfiddle.net/xLqackxw/8/
from Angular documentation https://docs.angularjs.org/api/ng/directive/ngOptions
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
So:
<select ng-model="role" ng-options="r as r.key for r in roles track by r.value"></select>
'$scope.role' value will be object like { key:"administrator", value:"ROLE_ADMIN" } or { key:"operator", value:"ROLE_OPERATOR" }

angular best practice for select show options when other select changes

i'm trying to build a select box that trigger show on options of other select in angular way.
the json that i use build select boxs is
[
{"item_id":1,"item":"rubber","type":"x","facility":"school a"},
{"item_id":2,"item":"pen","type":"x","facility":"school b"},
{"item_id":3,"item":"book","type":"y","facility":"school b"},
]
what i need is 3 select boxes, first one shows all unique type. in above json that would be 'x,y'.
when user select one of them, then it should show all unqiue facility values in other selectbox that has same type as selected.
--if user selected x, then it would show school a and school b
when user select facility, a 3rd selectbox show all uiqiue item as label, and item_id as value where facility = selected facility
<select ng-model="selected.type">
<!-- need to show unique types here -->
</select>
<select ng-model="selected.facility">
<option ng-repeat="s in json" ng-if='selected.type == s.type'>{{s.item}}</option>
</select>
<select ng-model="selected.item">
<option ng-repeat="s in json" ng-if='selected.facility == s.facility'>{{s.item}}</option>
</select>
Current solution
currently what i'm doing is that i wrote a filter
.filter('unique', function() {
return function (arr, field) {
var r = [],final=[];
for(i in arr){
if(r.indexOf(arr[i][field]) == -1){
r.push(arr[i][field]);
final.push(arr[i]);
}
}
return final;
};
})
and doing
<select class="form-control" ng-model="nrequest.facility">
<option ng-repeat="s in facility_services |unique:'facility'" value="{{s.facility}}">{{s.facility}}</option>
</select>
<select class="form-control" ng-model="nrequest.item">
<option ng-repeat="s in facility_services" ng-if='s.facility == nrequest.facility'>{{s.item}}</option>
</select>
it works yet i'm not sure if this is correct way to do it angular way, since i'm still learning this new toy i was hoping for some directions on how to achieve this using ngoptions, or other angularjs best practice

How to get value at the ng-model for the options under ng-repeat

Let my HTML is as follows:
<div ng-repeat="option in options">
<select ng-model="myselect">
<option value="">{{option.attribute_text}}:</option>
<option value="">{{option.attr_value}}-${{option.cost}}</option>
</select>
</div>
I want to get the values of the option selected in the ng-model. Is there any methods to get the values in the ng-model under a ng-repeat?
You have multiple selects and you are giving same model to all of them.
you can't give them same myselect to all of them.
give each option(the ones you are repeating) a name, and use an object's keys for their model.
<div ng-repeat="option in options">
<select ng-model="selections[option.name]">
<option value="">{{option.attribute_text}}:</option>
<option value="">{{option.attr_value}}-${{option.cost}}</option>
</select>
</div>
then you can access them like $scope.selections["some option name you gave earlier"]
if you want to use select you can use ng-select
if you specify ng-model for ng-select it bind the select option to ng-model
you can see it in this jsbin
Have a look at: https://docs.angularjs.org/api/ng/directive/select
Here's an example that should be about right:
Options stored as list of hashes in your controller:
$scope.options = [ { "attribute_text" : "whatever", "data" : { "value" : 9, "cost" : 8 }, { ... } ]
// Selected value
$scope.optionSelected = {};
HTML:
<div>
<select ng-select="option.attribute_text for option in options" ng-model="optionSelected">
</div>

Categories

Resources