I retrieve from the database what options should I show for all companies (only for showing purposes), this is my model:
export class OpcionesModel {
name: string;
isActive: boolean;
id?: string;
}
Then, I show all the options that are available (active):
<div class="row" *ngFor="let option of optionsArray; let i=index">
<div class="col-4">
<h5>{{option.name | titlecase}}</h5>
</div>
<div class="col">
<input type="checkbox">
</div>
</div>
What I want to do is to get all option's names and if its checkbox is checked or not and store that in an array, e.g:
[{'option 1', true}, {'option 2'}, false}, {'option 3', false}...].
EDIT: I've created an array: checkes: boolean[] =[];
if I do this <input type="checkbox" [(ngModel)]="checkes[i]">, I can get the checkboxes value but I need the option name too.
Thanks !!
<label>
<input type="checkbox" name="isActive" [(ngModel)]="option.isActive">
{{ option.name }}
</label>
taken from here: https://scotch.io/tutorials/how-to-deal-with-different-form-controls-in-angular-2
In your ts file, Your optionsArray array will be binded and the checked values will be updated when it changes
If you want to map it to an array with a different structure you can use the map method:
this.optionsArray.map(oa=> {return { myOptionName:oa.name, active:oa.isActive} })
Related
I'm developing an application using Angular 6. I have a big problem.
Using a template-driven form I would like that the item selected in a radio button can be sent when I press the submit button.
It's all right when I work with <input type="text" [(ngModel)] = "value" /> (value is a data field of my component), but if I try with this:
<div class="form-group">
<div *ngFor = "let option of options">
<div class="radio">
<input type = "radio"
name = "radio"
[(ngModel)] = "value"
/>
<label for="{{option.id}}">{{option.id}}</div>
</label>
</div>
</div>
</div>
The result is a bug! I can't even click the multiple buttons by moving the selector! Everything is stuck! Obviously it does not work with the form.
If I remove [(ngModel)] = "value" graphically it works, but without ngModel directive if I enter this code inside a template-driven form that uses (ngSubmit) it does not work.
Thanks a lot.
You are missing a value for each of the radio buttons so the binding does not work correctly. It is unable to determine which input should be checked so none of them get checked. Update the template to be something like:
<div *ngFor="let option of options">
<div class="radio">
<input type="radio"
name="radio"
id="radio-{{option.id}}"
[(ngModel)]="value"
[value]="option.value"
/>
<label for="radio-{{option.id}}">{{option.id}}
</label>
</div>
Stackblitz Demo
Radio buttons work different. To need to add a value to make it work. If you want to assign a value from angular use [value].
I have make it running in an example of stackblitz:
<div class="form-group">
<div *ngFor="let option of options; let i=index">
<div class="radio">
<input type="radio" id="{{option.id}}" name="radio{{i}}" [(ngModel)]="option.value" [value]="option.id" />
<label for="{{option.id}}">{{option.id}}</label>
</div>
</div>
</div>
<hr>
<h2>Values for options</h2>
<ul>
<ng-container *ngFor="let option of options; let i=index">
<li *ngIf="option.value !== ''">Value for {{option.id}}: {{option.value}}</li>
</ng-container>
</ul>
Component
value: any;
options = [
{
id: "test1",
value: ''
},
{
id: "test2",
value: ''
},
{
id: "test3",
value: ''
}];
Extension/Hints:
You can even use [(ngModel)] = "value" to assign the last selected value to value.
Give these radio buttons the same name name="radio" to ensure that only one of this group can be selected.
Inside the ts file :
radio_button_value = null;
box_options = [
{
"name": "Word",
"value": "word",
},
{
"name": "Line",
"value": "line"
},
]
Inside the html file:
Do notice of the tag 'name', it would we a great concern inside another for loop.
<div *ngFor="let box_opt of box_options; let i=index">
<input name="option-{{i}}" type="radio" [value]="box_opt.value" [(ngModel)]="radio_button_value">
{{box_opt.name}}
<br>
</div>
I am working an edit form, it happens that I have several options to choose, these options are obtained by ajax with axios and I assign them to the variable permisos of the component that later renders through a v-for, the checked elements I have them in a array selected that is assigned to the vue-model as follows
<div class="row">
<div v-for="permiso in permisos" class="col-md-5 col-12 col-sm-5" >
<input type="checkbox" :value="permiso.id"
class="form-control" :id=permiso.id
v-model="selected" :checked=selected.filter(e => e.id === permiso.id).length > 0 > {{ permiso.name}}
</div>
</div>
later I make another ajax call to know what options I had before editing the item to know what options or checkbox I will assign the checked attribute, this is where I have problems do not check correctly.
axios.get('api/allpermisos')
.then(response =>{
this.permisos = response.data; //dataok
})
if(this.action===2){
axios.get('api/allpermisos/'+ this.dataobject.id)
.then(response =>{
this.selected = response.data;//data ok
})
}
How can I do so that when I get the ajax call from the options already selected, the attribute checked is assigned automatically and those that are not, are not assigned. try with includes but I do not have the desired result?
The code works correctly if I remove the v-model. Why is this happening?
<input type="checkbox" :value="permiso.id" class="form-control"
:id=permiso.id :checked=selected.filter(e => e.id === permiso.id).length > 0 > {{ permiso.name}}
You don't need both v-model and :checked. v-model is a two way binding.
https://jsfiddle.net/bbsimonbb/eywraw8t/15613/
<div v-for="permiso in permisos" class="col-md-5 col-12 col-sm-5" >
<input type="checkbox" :value="permiso.id"
class="form-control" :id=permiso.id
v-model="selected"> {{ permiso.name}}
</div>
Consider creating a component for your input. Form inputs inside a v-for rapidly gets complicated.
You need to keep their ids in "selected" array, you are probably keeping whole objects which didn't work from what I checked.
HTML:
<div id="app">
<div class="row">
<div v-for="permiso in permisos" class="col-md-5 col-12 col-sm-5" >
<input type="checkbox" :value="permiso.id"
class="form-control" :id=permiso.id
v-model="selected" :checked=selected.includes(permiso.id)> {{ permiso.name}}
</div>
</div>
</div>
Vue:
new Vue({
el: '#app',
data() {
return {
selected: [2, 4],
permisos: [{id: 1, name: "test1"}, {id: 2, name: "test2"}, {id: 3, name: "test3"}, {id: 4, name: "test4"}]
}
}
})
https://jsfiddle.net/eywraw8t/15555/
This works.
If you are getting object array as response, you could do this:
this.selected = response.data.map(obj => obj.id);
I am trying display checkboxes for my user roles:
For eg. I have two user roles : 1.Admin 2.Employee
I have an array of roles in userObject:
user={
"name":"Bhushan",
"email":"bhushan#yaho.com",
"roles":['Admin','Employee']
}
I want to use reactive form to populate this model into form. I want to populate the roles array into read-only checkboxes i.e. when form loads, user can edit name & email but checkboxes will show admin toggeled if user has admin role or untoggled if he is not an admin. same can be said for employee role.
So far I have tried following:
<form [formGroup]="userForm" (ngSubmit)="onSubmit()" novalidate>
<div style="margin-bottom: 1em">
<button type="submit" [disabled]="userForm.pristine" class="btn btn-success">Save</button>
<button type="reset" (click)="revert()" [disabled]="userForm.pristine" class="btn btn-danger">Revert</button>
</div>
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">
</label>
</div>
<div class="form-group">
<label class="center-block">Email:
<input class="form-control" formControlName="email">
</label>
</div>
<div class="form-group" *ngFor="let role of roles;let i=index">
<label>
// I tried this, but it doesn't work
<!--<input type="checkbox" [name]="role" [(ngModel)]="role">-->
{{role}}
</label>
</div>
</form>
<p>userForm value: {{ userForm.value | json}}</p>`
Any Inputs?
Perhaps do something like the following. Build your form, and stick the roles in a form array:
this.userForm = this.fb.group({
name: [this.user.name],
roles: this.fb.array(this.user.roles || [])
});
// OPTIONAL: put the different controls in variables
this.nameCtrl = this.userForm.controls.name;
this.rolesCtrl = this.userForm.controls.roles.controls;
and the roles array you are iterating in the template could look like this:
roles = ['Admin', 'Employee','Some role 1', 'Some role 2']
and in your iteration just compare and set the role in roles array as checked in case it matches a value in the form array. Use safe navigation operator, as we know that the roles array is probably longer that the form array, so that an error won't be thrown trying to read an index that doesn't exist:
<div class="form-group" *ngFor="let role of roles;let i=index">
<input [checked]="role == rolesCtrl[i]?.value"
[disabled]="true" type="checkbox">{{role}}
</div>
DEMO
i have to following issue. I have an nested ng-repeat with two radio-buttons, when i select an radion-button the value is set correctly to the model. But when i filter to a value that's not in the collection the value is not set to the view (the model is still correct)
to reproduce:
Example
when you check all 3 radio-buttons to lets say 'read', than type 'x' into the input to filter, now remove the value from the input. the last radio is selected the others are not.
ps. i've tryed ng-value instead of value.
controller:
vm.list = [{id: 1, name: 'Item1', items: [{id: 1, name: 'SubItem1.1'}, {id: 2, name: 'SubItem1.2'}, {id: 3, name: 'SubItem1.3'}]}]
view:
<input type="text" ng-model="search" />
<ul>
<li ng-repeat="item in vm.list">
<h4 ng-bind="item.name"></h4>
<ul>
<li ng-repeat="subitem in item.items | filter:search">
<h4 ng-bind="subitem.name"></h4>
<input type="radio" name="{{item.id}}{{subitem.id}}" ng-model="subitem.permission" value="read" /> Read
<input type="radio" name="{{item.id}}{{subitem.id}}" ng-model="subitem.permission" value="write" /> Write
</li>
</ul>
</li>
change the input name
from
name="{{item.id}}{{subitem.id}}"
to
name="{{subitem.id}}"
I want to filter questions out by clicking on their associated category name checkbox. Ex: only questions with category X will be shown if only category X checkbox is checked.
I'm able to bind the names Cat1, Cat2, etc directly to the catfilters object:
<input type="checkbox" ng-model="catfilters.Cat1" /> Cat 1
<input type="checkbox" ng-model="catfilters.Cat2" /> Cat 2
<ul>
<li ng-repeat="q in questions | bycategory:catfilters">{{q.question.cat_id}}</li>
</ul>
This works.
However, I want to dynamically create the category checkboxes from a list in the controller, and bind them to the catfilters object:
$scope.cats = [
'Cat1',
'Cat2',
'Cat3'
];
//c is 'Cat1', 'Cat2', etc...
<div ng-repeat="c in cats">
<input type="checkbox" ng-model="catfilters.c">{{c}}</span>
</div>
<ul>
<li ng-repeat="q in questions | bycategory:catfilters">{{q.question.cat_id}}</li>
</ul>
But for some reason, this will not apply the filtering. I am not getting any errors though.
Note: I've also tried looking up by indexed property:
<div ng-repeat="c in cats">
<input type="checkbox" ng-model="catfilters[c]">{{c}}</span>
</div>
This also does not work
Filter:
angular
.module('DDE').
filter('bycategory', function() {
return function (questions, categories) {
var items = {
categories: categories,
out: []
};
angular.forEach(questions, function (value, key) {
if (this.categories[value.question.cat_id] === true) {
this.out.push(value);
}
}, items);
return items.out;
};
}
);
catfilters.c looks for a property called c in catfilters, regardless of if you have a variable c elsewhere.
Try looking it up by the indexed property catfilters[c] instead.
//c is 'Cat1', 'Cat2', etc...
<div ng-repeat="c in cats">
<input type="checkbox" ng-model="catfilters[c]">{{c}}</span>
</div>
I have made a plunkr. I implement using
<div ng-repeat="input in inputs">
<input type="text" ng-model="filter[input]">
</div>
and
$scope.inputs = ['foo','bar'];
$scope.filter={
'foo':"Foo",
'bar':"Bar"
}
It is working fine (which i think is similar to your scenario).There must be something error in your implementation.