Nested ng-option inside angular ng-repeat - javascript

Im currently trying to nest a <select> inside a div with a ng-repeat
something like this:
<li ng-repeat="item in items >
<div class="row">
<div class="col-xs-7">
<span ng-bind="item.Name"></span>
</div>
<div class="col-xs-4 modal-body--ul--li__dropdown_container">
<select ng-model="typemodel" >
<option ng-repeat="usertype in item.userGroups"></option>
</select>
</div>
<div class="col-xs-1">
<a ng-click="add(item)"></a>
</div>
</div>
</li>
In the controller im adding the item to a new list with selected items. I also want to add the value from the dropdown as a new value to the list in the controller.
$scope.add = function (item) {
//New value with the value from the dropdown
item.recipientType = typemodel;
$scope.selected.push(item);
};
The list :
$scope.items = [
{
"Name":"Name1",
"userGroups":[
{ "type": "gruop1" },
{ "type": "gruop2" },
{ "type": "group3" }
]
},
{
"Name":"Name2",
"userGroups":[
{ "type": "gruop1" },
{ "type": "gruop2" },
{ "type": "group3" }
]
}
]
In short i need the selected value from the dropdown when i hit the "add", the value of the current typemodel.
This is how it looks now, but it dont work. I know i have to get the correct model and maybe track the items list by $index, but after searching the web the whole day for a solution, im still stuck!
All help is appreciated.
-Thanks!
ps. please comment if something is missing from the question, or something more is needed to solve this.

First, change your dropdown list to
<select ng-options="usertype in item.userGroups" ng-model="item.recipientType">
Then when you trigger the add function, item's property recipientType is already set.
$scope.add = function (item) {
console.log(item.recipientType);
$scope.selected.push(item);
};

Related

Create inputs as array in angular form

Tried my level best please help me out..
I am making an angular dynamic form with a form splitting into total of three parts in which the two parts were made already. Now I am making part three which will be generated by selecting an option from dropdown...
Even those part also is done...
But I am unable to make a form array in it... As I am new in angular please help me.
HTML:
Form part 3 will be here which will be array
<select multiple (change)="changeEvent($event)">
<option *ngFor="let opt of persons" [value]="opt.key">{{opt.value}}</option>
</select>
<div *ngFor="let item of array">
{{item.value}} is the parent
<div *ngFor="let child of item.templateChild">
{{child.property_name}}
<div *ngFor="let partThree of questionsParthree">
<ng-container>
<app-question [question]="partThree" [form]="formPartThree"></app-question>
</ng-container>
</div>
</div>
</div>
Select Box change event:
changeEvent(e) {
if (e.target.value == 1) {
this.array = [];
this.array.push(
{
key: 1, value: "Template one",
templateChild: [
{ property_name: "Property one" },
{ property_name: "Property two" }
]
}
);
let propertiesArray = [];
this.array.forEach(element => {
element.templateChild.forEach(data => {
propertiesArray.push(
{
key: data.property_name,
label: data.property_name,
"elementType": "textbox",
"type": "text"
}
)
});
});
this.questionsPartThree = this.service.getQuestions(propertiesArray);
this.formPartThree = this.qcs.toFormGroup(this.questionsPartThree);
this.formJoin = new FormGroup({ form1: this.form, form2: this.formPartTwo, form3: this.formPartThree });
}
}
Continuation like part 1 and 2..
I have posted the code related to creating the form array alone..
Updated Stackblitz https://stackblitz.com/edit/angular-x4a5b6-mnyifs
Here if we select any option then you will get the input boxes with values..
I would like to create array with it like,
If we select the first option Template One, Output expected is exactly as like
"templateChild" : [
{"property_one": "", "property_two":""}
]
So the final output of whole form going to be if i select Template One and also Template Two from select box (as select box is multi select),
{
"form1": {
"project_name": "",
"project_desc": ""
},
"form2": {
"property_one": "",
"property_two": ""
},
"template_details" : [
{ "template_name": "Template One",
"templateChild" : [{"property_one": "", "property_two":""}]
},
{ "template_name": "Template Two",
"templateChild" : [{"property_three": "", "property_four":"",
"property_five":""}]
}
]
}
Have a work around in the demo i have provided and give me a better solution..
Kindly please help me to create a form as like the above when we select an option from dropdown.. If i am wrong in my approach also please correct me..
If i finish this third part then everything will get alright any angular technical expert please help me..
Taking too long please help me out..
You can dynamically change an AbstractController inside a FormGroup using the setControl() method.
Add an empty form3 part for the moment
this.form3 = new FormGroup({});
this.formJoin = new FormGroup({ form1: this.form, form2: this.formPartTwo, form3: this.form3 })
When selecting an item, generate a new FormGroup according the form you create.
if (e.target.value == 1) {
this.array = [];
this.form3 = new FormGroup({'Property one': new FormControl('insert whatever you want')});
this.formJoin.setControl('form3', this.form3);
You should be able to do something what that start!

Select all if all checkboxes are selected, angular js

On my page I have angular ui accordion, inside of each panel, I'm rendering list with items and checkboxes, also I have checkbox "select all".
For selection method and logic I used this resource. In this resource logic seems working, but however I'm putting this logic to my code, it stops working.
What I want to achieve is when all checkboxes are selected, checkbox "select all" has been selected automatically, and if some of checkboxes is unselect, checkbox "select all" has to be unselect as well.
I have tried multiple suggestions provided here, here, here, but in the end I'm getting the same result.
I appreciate if somebody could help me to resolve my problem.
$scope.categories = [
{
id: 1,
name: "category 1"
},
{
id: 2,
name: "category 2"
},
{
id: 3,
name: "category 3"
}
]
$scope.selectedAll = false;
$scope.selectAll = function(array) {
$scope.selectedAll = !$scope.selectedAll;
angular.forEach(array, function(item) {
item.Selected = $scope.selectedAll;
});
};
$scope.checkIfAllSelected = function(array) {
$scope.selectedAll = array.every(function(item) {
return item.Selected == true
})
};
html
<div>
<div class="row" ng-class="{'selected': selectedAll, 'default': !selectedAll}">
<div>Select all
<input type="checkbox"
ng-model="selectedAll" ng-click="selectAll(categories)" >
</div>
</div>
<div class="row" ng-repeat="item in categories | orderBy : 'id'" ng-class="{'selected': item.selected, 'default': !item.selected}">
<div > {{ item.name }}
<input type="checkbox"
ng-model="item.Selected" ng-click="checkIfAllSelected(categories)"
>
</div>
</div>
This is my plunker
Please take a look at this fork of your plunker: https://plnkr.co/edit/OW3F1VMke9iLuNkt5p3o?p=preview
Two things:
1. It's a good practice to create an object to your view model (you can find it under the name model in the plunker $scope.model. This will solve 2 way data binding issues.
2. I have changed the ng-click to ng-change (this is not part of the solution though - its just more correct in my opinion).
Please let me know if you need more clarifications.

angularjs - ng-options with nested json based on previous select option

i'm kind of new in Angular, and I facing a problem, I didn't find an answer that could help me, if some one could, thank you. :)
I have a json like this:
"items": [
{
"post_type": "release",
"label": "Releases"
},
{
"post_type": "news",
"label": "Notícias",
"options": [
{
"id": 1,
"name": "Galeria de Fotos"
},
{
"id": 2,
"name": "Agência de Notícias"
},
{
"id": 3,
"name": "Rádio"
},
{
"id": 4,
"name": "TV"
}
]
},....
And I m getting data like:
var _preparingPostTypes = function ($scope) {
$scope.post_types = [];
PostTypeService.getPostTypes().then(function (data) {
$scope.post_types = data.data;
});
};
What I want to do is create 2 selects, 1st - with the post_type ('release', 'news') and a second one with the 'options' array from a post_type, that is only visible when select an option with the 'options' in the array like 'news'. I did something like this, where I can get the post_type like a charm, but I don't know how to proceed:
<div class=form-group>
<label>Pesquisar em:</label>
<select title="Pesquisar em:" class="form-control select-post-type"
ng-model="widget.post_type"
ng-options="item.post_type as item.label for item in post_types.items"></select>
</div>
EDIT:
In my request I need to pass the post_type string to server, from the first select, so the ng-options is:
ng-options="item.post_type as item.label for item in post_types.items
Not:
ng-options="item as item.label for item in post_types.items
Thanks everybody!
You can add an ng-change to the first select that calls a function that loads the options
<select title="Pesquisar em:" class="form-control select-post-type"
ng-model="widget.post_type"
ng-options="item as item.label for item in post_types.items" ng-change="typeChanged()"></select>
And the function would load inside $scope.options the selected type options. Then you iterate over $scope.options in the second select
UPDATE:
I haven't tested the code, but it may guide you
Select:
<select title="Options:" class="form-control select-post-type"
ng-model="widget.option"
ng-options="option as option.name for option in options">
Change function (triggered when the value of the first select changes, so it will have the responsibility of loading the options of the post_type selected):
$scope.typeChanged = function() {
for (var i = 0; i < $scope.post_types.items.length; ++i) {
if ($scope.post_types.items[i].label == $scope.widget.post_type) $scope.options = $scope.post_types.items[i].options || [];
}
}
widget.post_type should contain the selected item. So the other select can have options like option as option.name in widget.post_type.options. Note that you should probably have an options collection on each item if you want this to work.
You can do this very easily using following technique. You just need to use the ng-model from the first select. See my approach:
<label>Pesquisar em:</label>
<select title="Pesquisar em:" class="form-control select-post-type"
ng-model="firstSelect"
ng-options="item as item.label for item in post_types.items"></select>
<select title="Second one" class="form-control select-post-type"
ng-model="secondSelect" ng-show="firstSelect.options"
ng-options="option as option.name for option in firstSelect.options"></select>

Radio buttons in multiple nested ng-repeats (angular + JSON)

I want to replace tags with radio buttons inside ng-repeats with angular and json. I display a list of products that have sub products. I would like to be able to put a radio button beside each sub product (eg. Product1-Type1) and group them by the parent product code (eg. Product1) If a user selects a sub product, the "Selected" value would be set to true and the other sub products would be set to false. And also call the displayFullPricing(prices) function.
Here is the code used to display the json (working)
<div ng-repeat="product in groups.Products">
<h3>{{product.Code}}</h3>
<div ng-repeat="prices in product.Prices">
{{prices.Code }} - {{prices.monthly.RetailPrice}}
<a ng-click="displayFullPricing(prices)">select</a>
</div>
</div>
And the json I am using...
{
"ID":"",
"Groups":[
{
"Products":[
{
"Code":"Product1",
"Prices":[
{
"Code":"Product1-Type1",
"Monthly":{
"RetailPrice":2,
"MinimumPrice":4
},
"Selected":false
},
{
"Code":"Product1-Type2",
"Monthly":{
"RetailPrice":5,
"MinimumPrice":2
},
"Selected":false
}
]
},
{
"Code":"Product2",
"Prices":[
{
"Code":"Product2-Type1",
"Monthly":{
"RetailPrice":7,
"MinimumPrice":3
},
"Selected":false
},
{
"Code":"Product2-Type2",
"Monthly":{
"RetailPrice":2,
"MinimumPrice":8
},
"Selected":false
}
]
}
]
}
]
}
Could anyone help me achieve this? I had tried moving ng-click into a radio button but it didnt work. Many thanks
Here is plunker for you.
Key thing is giving same name for radio groups so I give name with using their parent product.
<input type="radio" name="group-{{product.Code}}" ng-model="subProduct.Selected">{{subProduct.Code}}
for function call you can use ng-click.
<input type="radio" ng-click="displayFullPricing()" name="group-{{product.Code}}" ng-model="subProduct.Selected">{{subProduct.Code}}

Angular view not updating properly on ng-click

Im writing selecting button menu and when I try to get to next select level nothing happens.
In first list item i want to write selected value from next level, in second I have successfully listed all items from first level and in third I want to display second (last) level oprions.
My code looks like:
<div ng-if="selected.type=='number' && selected.values[0].values">
<ul class="smsUl">
<li ng-if="selected.selected">
<button class="btn btn-warning btn-block">{{selected.selected}}</button>
</li>
<li ng-repeat="value in selected.values" ng-if="attributes == undefined">
<button class="btn btn-info btn-block" ng-click="$parent.attributes=value.values">{{value.value}}</button>
</li>
<li ng-repeat="attribut in attributes" ng-if="attributes != undefined">
<button class="btn btn-info btn-block" ng-click="selected.value=attribut.id; selected.selected=attribut.value; attributes=undefined">{{attribut.value}}</button>
</li>
</ul>
</div>
And part of jason with selected.values looks like:
[
{
"value": "clothing_glasses",
"values": [
{
"id": 1,
"value": "coat"
},
{
"id": 2,
"value": "glasses"
}
]
},
{
"value": "book_stationery",
"values": [
{
"id": 3,
"value": "book"
},
{
"id": 4,
"value": "document"
}
]
}
]
In nf-if expression I tried with:
!attributes
but nothing has changed.
Update:
If I set attribute variable in controller staticly it lists the content I want, but if I select, i should go back to the 1. level.
Are you sure you are not doing something like this in controller:
$scope.attributes = [someArray]
(bla bla, some code)
$scope.someOnClickFunction = function() {
$scope.attributes = [otherArray]
}
if so, than you are losing scope of the correct variable, and angular no longer watches what you think it should.
I reccomend creating some object called eg. "observable", put there all those 'attributes', 'selected' etc, and add to your controller:
$scope.$watchCollection('observable.attributes', function() {});
$scope.$watchCollection('observable.selected', function() {});
and when you want to change something in those arrays dont replace them (by applying new arrays to old variable).
If you dont want to play with pushgin, shifting, poping elements you can always use:
someDefinedArray.length = 0;
for-loop {
someDefinedArray.push(yoursobjects); //push objects back to array but with changes you wanted to make to array
}

Categories

Resources