I am new in Angular 2. I am trying to expand dynamic forms according to https://angular.io/guide/dynamic-form. I did input radios and work as I need. But now I am trying to do checkboxes, but there is a problem. I have a group of checkboxes and I get only boolean value, if some checkbox is checked. Bud I need values, which checkboxes is checked. There is my plunker: https://plnkr.co/edit/EhtpprYdXIFmYJG7Lzxg
Thanks for help!
I hope this would be the solution for you.
templet.html
<form [formGroup] = "myForm" (ngSubmit) = "confirmFlights(myForm.value)">
<ng-template ngFor [ngForOf]="flightList" let-flight let-i="index" >
<input type="checkbox" [value]="flight.id" formControlName="flightid"
(change)="flightids[i]=[$event.target.checked,$event.target.getAttribute('value')]" >
</ng-template>
</form>
component.ts
flightids array will have another arrays like this
[ [ true, 'id_1'], [ false, 'id_2'], [ true, 'id_3']...]
here true means user checked it, false means user checked then unchecked it.
The items that user have never checked will not be inserted to the array.
flightids = [];
confirmFlights(value){
//console.log(this.flightids);
let confirmList = [];
this.flightids.forEach(id => {
if(id[0]) // here, true means that user checked the item
confirmList.push(this.flightList.find(x => x.id === id[1]));
});
//console.log(confirmList);
}
Why it isn't working:
because you are using one formControl key (question.key === 'skills') for all 3 checkboxes.
<span *ngSwitchCase="'checkbox'">
<p *ngFor="let opt of question.options">
<input [formControlName]="question.key"
[id]="opt.key" type="checkbox" [value]="opt.key">
<label>{{opt.value}}</label></p>
</span>
How to deal with it:
You should use formControl key for each input (checkbox), to track model changes - this is how Angular forms works.
So, if you split your Checkbox.options to separate Checkbox, it would work:
in dynamic-form-question.component.html change Checkbox to:
<span *ngSwitchCase="'checkbox'">
<input [formControlName]="question.key"
[id]="question.key" type="checkbox" [value]="question.value">
</span>
in question.service.ts change Checkbox to:
new CheckboxQuestion({
key: 'fast',
label: 'Fast',
value: false,
order: 5
}),
Here is changed Plunker:
https://plnkr.co/edit/2XIfMU?p=preview
A checkbox or radio doesn't update automatically (at this point I'm not sure if this is caused by angular design or possibly due to MDN: DOM input event).
The usage of a template reference variable works but only for one FormControl within a FormGroup.
More elegant solution: you can set a FormControl's value (in a FormGroup) directly from the change event:
(change)="formGroup.controls[element.name].setValue($event.target.checked)"
Since FormControl.setValue's emitEvent, emitModelToViewChange and emitViewToModelChange default to true, it's seems not necessary to update other attributes manually.
Modified for angular's dynamic form (working example on stackblitz):
<input *ngSwitchCase="'checkbox'" [formControlName]="question.key"
[id]="question.key" [type]="question.type" (change)="form.controls[question.key].setValue($event.target.checked)">
Related
Imagine this:
http://jsfiddle.net/wcuuj8do/9/
My current code:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.rowData = [];
$scope.addRow = function(title, number)
{
$scope.rowData.push({
'title': title,
'number': number
});
};
$scope.addRow('Car', '1200');
$scope.addRow('Car','');
}
When i type "Car" inside first input (T1) and then type some text to input (N1) i want angular to check each T# input if has same value as (T1). If has disable (or readonly) all N# inputs related to currently checked T# input.
Afterwards when i remove duplicated values from T# fields, related T# fields should be returned to default input states (remove disable / readonly)
This should work by adding new dynamic inputs as seen in fiddle.
You should create a method, that will do the checking part. This method will should be bound to blur or change event on T# inputs, depends on what you want.
The method will check for duplicity, and if found, mark the object, e.g. add new property disabled: true. This property will be then used in the template on N# fields via ng-disabled directive.
Here is your update fiddle: http://jsfiddle.net/wcuuj8do/10/
Note the new method $scope.checkDuplicity and new binding:
<tr ng-repeat="(key, item) in rowData">
<td>T{{ ($index+1) }}: <input type="text" ng-model="rowData[key].title" ng-change="checkDuplicity(key)" value="" style='margin-bottom:15px' /></td>
<td>N{{ ($index+1) }}: <input type="text" ng-model="rowData[key].number" value="" style='margin-bottom:15px' ng-disabled="rowData[key].disabled" /></td>
</tr>
This is simple one but i still somehow couldn't get it to work.
I have default value checked, checkbox. So when edit, of course the default value is chosen, but later I want to remove the default value and choose another value. Here it is
array1=[] //empty
After I check a checkbox, it will inserted to this array
array1=["sun"]
If I select 3 values (array1["sun","stars","moon"])
but I deselect the first selection (the default selection), it will be still in the array. (array1["sun","stars","moon"]) but I the expected result is this:
array1["stars","moon"]
No more first selection. So how to remove deselected value from array using Angular/Javascript?
I have tried use splice, remove and set
Same thing developed and used in project :
Template side :
<label *ngFor="let hobby of hobbies" #checkbox class="mdl-checkbox mdl-js-checkbox">
<input type="checkbox" name="hobbies" [value]="hobby"
(change)="populateMyHobbies(hobby,$event.target.checked)" class="mdl-checkbox__input">
<span class="mdl-checkbox__label">{{hobby}}</span>
</label>
Component Side :
selectedHobbies = [];
populateMyHobbies(value , status:boolean)
{
if(this.selectedHobbies.indexOf(value) === -1 && status)
{
this.selectedHobbies.push(value);
}
else if(!status)
{
let index = this.selectedHobbies.indexOf(value);
this.selectedHobbies.splice(index, 1);
}
}
Here selectedHobbies will give you what you want.
Have to change just name as per your app.
i used it once in my project. change the code according to your need. logic is same.
html part
<input type="checkbox" value="{{category._id}}" (change)="pushpopcategory(category._id)" id="{{category._id}}">
component code
pushpopcategory(value) {
if ((<HTMLInputElement>document.getElementById(value)).checked) {
this.categoryAdd.push(value);
} else {
let indexx = this.categoryAdd.indexOf(value);
this.categoryAdd.splice(indexx, 1);
}
}
Angular 1.*
I have:
<div class="filter-column">
<div class="filter-title">Market</div>
<div class="bottom-line"></div>
<div class="overflow-container">
<input type="radio" value="all" name="marketRadio"
ng-checked="true" class="resetAll" ng-model="filter.markets"
ng-change="radioMap('market')" checked>All
<div ng-repeat="choice in markets| orderBy: 'name'">
<input type="radio" value="{{choice.name}}" name="marketRadio"
ng-change="radioMap('market')" ng-model="filter.markets" >
{{choice.description}}
</div>
</div>
In the controller I have:
var ppvFilter = {
regions: [],
markets: [],
dealers: []
};
$scope.$watchCollection(function() {
return ppvFilter;
},
function(newValue) {
$scope.regions = newValue.regions;
$scope.markets = newValue.markets;
$scope.dealers = newValue.dealers;
});
When I refresh the radio button list programaticly(not page refresh) with ppvFilter.markets.length = 0; ppvFilter.markets = ppvFilter.markets.concat(['a', 'b', 'c']), the list of radio button choices updates as it should in the gui. However, ng-checked="true" no longer works for all and it is unchecked after the list updates.
I suspect it is because the angular form is referencing old memory even though it is showing the new list of radio buttons.
From the angular documentation on ngChecked: Note that this directive should not be used together with ngModel, as this can lead to unexpected behavior.
I figured it out.... the default item HAS to be in the ng-repeat. ng-check is not much use in real life.
Reference:
Radio button checked by default when using ng-repeat
I have checkbox list and I want to clear all checked data after Clear button.
The data is fetch from json for checkboxes.
HTML:
<div ng-repeat="data in array" >
<label class="Form-label--tick">
<input type="checkbox" id="statusid" value="{{data.id}}" class="Form-label-checkbox" ng-click="print(data.id)">
<span class="Form-label-text" id="statusname" value="{{data.name}}"> {{data.name}}</span>
</label>
</div>
JavaScript:
$scope.clearFilters = function() {
document.getElementById('statusid').value="";
document.getElementById('statusname').value="";
};
clearFilters() is called when Clear Button is clicked.But I am not able clear the checked boxes.It remains checked even after the clear button.
This code is not angular. Don't try to modify any DOM elements directly, but use the $scope variables to change their value.
In angular the checkbox return true or false so to uncheck a checkbox just change it's value to false.
so your code should look like this:
$scope.clearFilters = function() {
$scope.data.id = false;
$scope.data.name = "";
};
I used the jquery to remove the checked property of checkbox.The UI value is updated.However, the model value is not updated. The same old value is there in the model. If I manually check unchecked checkbox the model value is updated. I have a scenario where one checkbox is click the other checkbox should be unchecked.The required functionality is done through below code. But I need an updated value in the model.
answerClick: function (data, event) {
var element = event.target;
$(element).parents('.primaryCaseMain').find("div#" + valueToHide).find('input[type=checkbox]:checked').removeAttr('checked');
}
Here is the HTML code
<input type="checkbox" data-bind="attr:{id: $data.Id , Qid: $parent.Id , Qref: $data.QuestionRefSetStrings , Uid: $data.Uid , rel: $data.MutuallyExclusive ? 'true' : 'false'} ,checked: $data.Selected, click: $root.answerClick , if: $root.appendQrefQuestion($data.QuestionRefSetStrings, $data.NoAppendRequiredQref)">
You should use knockout to implemented this kind of functionality instead of jQuery.
In your viewmodel implement 2 properties, I call them checkbox1 and checkbox2.
var self = this; //to have access to this in anonymous functions
this.checkbox1 = ko.observable(true);
this.checkbox2 = ko.observable(false);
Then subscribe to changes of each of the observables and set the value of the other observable to false if the set value is true.
this.checkbox1.subscribe(function(newValue){
if(newValue){
self.checkbox2(false);
}
});
this.checkbox2.subscribe(function(newValue){
if(newValue){
self.checkbox1(false);
}
});
Then use the checked binding to bind the properties to the checkboxes.
<input type="checkbox" data-bind="checked: checkbox1" />
<input type="checkbox" data-bind="checked: checkbox2" />