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
Related
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
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" }
In web app I have a list of Expenses, which that if you press above it takes you to a new page to edit the selected Expense. When the user click on an element of list, I save the Object (the selected Expense) in a Global Object common in whole application and I retrieve it when I am in the Editing controller:
$scope.companySelected = GlobalApplicationData.selectedExpenseList;
The GlobalApplicationData.selectedExpenseList is an Object:
$$hashKey: "object:39"
_id: "33aa5549-7802-40d9-bc89-8780705b8c9b"
_rev: "3-eb940cb990524112723f711618e0cf51"
ad_table_id: 1000596
company_name: "Company 1"
data: Object
recordid: 1000005
__proto__: Object
In one expense there is only one company.
So, in this page of editing I have some field (input type text, date, etc). And I also have a selection with the list of the Companies of the logged user. To retrieve that list, I made this function:
$scope.getCompanyList = function() {
EditExpenseListSrv.getCompanyListDetail(user).then(function (companyListDetail) {
$scope.companyList = companyListDetail;
$scope.$apply();
}).catch(function (err) {
console.log(err);
});
};
CompanyListDetail is an array of Obejct:
companyListDetail: Array[5]
0: Object
1: Object
2: Object
3: Object
4: Object
And this is one example of those object:
_id: "44e620dc-e715-453f-882b-3f21aeef48fe"
_rev: "1-c09c9f3350e853e588f3358aaafc0374"
ad_table_id: 1000146
data: {
description: "text"
id_company: 513424
name: "Company 2"
}
recordid: 1000002
So the company of the selected Expense ($scope.companySelected) will definitely part of the list obtained by the query ($scope.companyList). But I want to give the user the possibility to change it.
So I would like to make a selection containing the list ($scope.companyList) and default already selected the Company corresponding to $scope.companySelected.
I've writter this, but it doesnt work:
<select class="selection" ng-model="companySelected"
ng-init="companySelected = globalApplicationData.selectedExpenseList"
ng-options="company
as company.data.name for company in companyList">
But it doesn't work. I can see in the selection all the Companies, but don't select the default value
When you are assigning a default value to the select, you need to assign the object, so it won't work, when assigned with the same data of some other object:
Note:
a) data is the array which is getting looped in the select list
b) selectedcountry is the model which is bind on select list.
Option 1:
Using ng-init:
<select ng-model="selectedcountry" ng-init="selectedcountry = data[0]" ng-options="item.name for item in data">
<option value="">Select</option>
</select>
Demo 1.
Option 2:
Assigning the default from the controller
$scope.selectedcountry = $scope.data[0];
Demo 2
You can try to do the initialisation in the controller:
$scope.companySelected = "the value that you want to set here"
Or you can try to put the ng-init inside the parent of the select. Once I had a problem like this and I solved it putting the ng-init in the parent tag. Example:
<div id="parent" ng-init="companySelected = globalApplicationData.selectedExpenseList">
<select ...>
</div>
Another idea would be to put companySelected inside an object. I have had some problems (I am not sure why) with the forms if I was using $scope.value inside the ng-value instead of using $scope.formData.value
Sup guys! I am trying to build a dynamic form, but I got stuck in a ngModel problem.
The idea is:
I got 2 arrays: one for temporary show to user selected info, and another that is which actually is saved on post (I have different types of data, so I have to do this way).
1- The user uses a <select> to choose a option. The selected option is a object inside a list. User hits the add link, and the selected option pop for him.
2- The selected option, has a custom property, that must be set before hit the add button. For that, a ´input´ pop when an option is selected. the ngModel for this is dynamically set, based on a object's property.
3- I need to get the input data, and save it inside a property of the object selected on the list.
4- Push the object to the array-to-be-posted (newData).
What I have that work: the list, the dynamic ngModel.
What I need: to get the data from this ngModel ad use it inside my directive.
here go the codes:
html:
<select id="newPrereq" class="form-control" name="newPrereq" ng-model="newPrereq" ng-options="prereq.name group by prereq.cat for prereq in prereqs | orderBy:prereq.name">
<option value="" hidden>-- Select --</option>
</select>
<input type="{{newPrereq.type}}" ng-show="newPrereq.array" ng-model="newPrereq[ngModel]">
<a ng-click="addItem(newPrereq, selectedPrereqs, 'prereqs')" ng-show="newPrereq !== undefined || ''">add</a>
<ul class="list-inline">
<li ng-repeat="prereq in selectedPrereqs"><span>{{prereq.name}} </span> <a ng-click="removeItem($index, selectedPrereqs, 'prereqs')">[X]</a></li>
</ul>
directive (scope:false) relevant functions:
scope.prereqs = Lists.prereqs;
scope.addItem = function(obj, array, group){
array.push(obj); // Add item to array-to-be-posted
if(obj.array){
scope.newData.prereqs.proficiencies.push({'name': obj.name, 'cat': obj.cat, 'details': [something here to get the ng-model from DOM]})
};
scope[group] = scope[group].filter(function(list){ // Remove added item from the <select>
return list !== obj;
});
scope.newPrereq = undefined;
};
part of the list (come from a Lists.js service)
'prereqs': [
{'name':'option 1', 'cat':'category 1', 'type':'text', 'ngModel':'smDetails', 'array':true},
{'name':'option 2', 'cat':'category 2', 'type':'text', 'ngModel':'srDetails', 'array':true},
]
I have a dropdown generated using ng-options
<select class="form-control" ng-options="item.value as item.label for item in filterFields track by item.value" ng-model="selectedFilterField">
</select>
The problem is that when I select an option from this dropwon, the selected item appears as empty and an extra blank element is added to the dropdown. What am I doing wrong?
Edit: added controller code:
$scope.columns = accountColumns;
$scope.filterFields = [];
$scope.filterFields.push(defaultSelectOption);
$scope.filterFieldValues.push(defaultSelectOption);
var idx = 1;
for(i=0; i < accountColumns.length; i++) {
var option = {label: accountColumns[i], value: accountColumns[i]};
$scope.filterFields.push(option);
}
$scope.selectedFilterField = $scope.filterFields[0];
Let's say your filterFields array has objects that look like this:
{
name: "",
value: 0
}
In your ng-options you tell angular that the possible values for the select is an array of these objects. But you also tell angular that when you select an option then the real value is the object.value; So now angular sees that this value is not present in the array of options and tries to add it or something.
Initially the dropdown works because you set the ng-model to a complete object present in the filterFields array.
Try it with this:
ng-options="item for item in filterFields track by item.value"