Form regneration on every interaction, angular forms - javascript

I'm having a problem with a Angular form. The problem is a checkbox, that contains some values (around 10). I have an item i push into this form with some allready selected values. So what I use the form to is editting/updating this item.
My checkbox right now can show which of the values in the checkbox were chosen before the edit. example here: https://gyazo.com/3cda89f3fc5c42de690fd8803274990b (hover to show)
But when I try to select a new checkbox value it just regenerates the whole checkbox every time, and I don't know why.
Maybe I'm filling the form on the wrong way, I'm creating the form like this:
<div class="form-group row">
<div class="col">
<label for="">Typer af data der indhentes:</label>
<div formArrayName="DataTypes"
*ngFor="let test of this.createWhatItemData().controls; let j=index"
class="form-group">
<div>
<div class="form-check">
<label class="form-check-label">
<input type="hidden" />
<input type="checkbox" class="form-check-input" [checked]="test.value.selected" />
{{whatItemDataTypes[j].Name}}
</label>
</div>
</div>
</div>
</div>
</div>
and then it is initialized and filled like this:
private initFormWhatComponent() {
this.form2 = this.formBuilder2.group({
ConsentWhatItemDirection: this.whatItem.ConsentWhatItemDirection,
ConsentWhatItemType: this.whatItem.ConsentWhatItemType,
OrganizationIdentifier: this.whatItem.OrganizationIdentifier,
Name: this.whatItem.Name,
Description: this.whatItem.Description,
DataTypes: this.formBuilder2.array(this.whatItem.DataTypes)
});
this.addWhatItemFormGroupWhatComponent(this.whatItem);
}
This is to get the allready selected values into my checkbox, and if i console log eg. "test" in this function it logs every time i interact with the form.
createWhatItemData() {
let _formArray = this.formBuilder2.array(
this.whatItemDataTypes.map(s => {
return this.formBuilder2.group({
selected: this.whatItem.DataTypes.some(x => x.Id == s.Id),
Id: s.Id,
});
})
);
return _formArray
}
The values that are availible to choose is fetched from the database, and are then merged together with the item values sent to the form.
can anyone help me with fixing the checkbox so I can select new values and then update my item?
Thanks in advance.

private initFormWhatComponent() {
this.form2 = this.formBuilder2.group({
ConsentWhatItemDirection: this.whatItem.ConsentWhatItemDirection,
ConsentWhatItemType: this.whatItem.ConsentWhatItemType,
OrganizationIdentifier: this.whatItem.OrganizationIdentifier,
Name: this.whatItem.Name,
Description: this.whatItem.Description,
DataTypes: this.formBuilder2.array(this.whatItem.DataTypes)
});
this.addWhatItemFormGroupWhatComponent(this.whatItem);
//return anything in here..
}

Related

How to save double data in one field?

I have two checkbox and one radio button.
If 2nd checkbox is checked then don't show the radio buttons.
Here is the code:
$(document).ready(function() {
$("#clients").click(function() {
if ($(this).is(":checked")) {
$("#radio-button-option").addClass('hide');
} else {
$("#radio-button-option").removeClass('hide');
}
});
});
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" id="members" name="members" value="members">
<label for="members"> Members</label><br>
<input type="checkbox" id="clients" name="clients" value="clients">
<label for="clients"> Clients</label><br>
<div id='radio-button-option'>
<input type="radio" id="client1" name="client1" value="client1">
<label for="client1">Client1</label><br>
<input type="radio" id="client2" name="client2" value="client2">
<label for="client2">Client2</label><br>
</div>
I've a table named 'post'.
There have some field like (id, title, file, share_with).
Now i want to save this in database.
Table name post.
And i save this data into share_with field.
Generally save 'members' and 'clients'.
If i don't save client then show this radio button. And if i checked the members and choose the radio1 then save the 'members' and 'radio1'.
Is this possible?
Yes its possible to save multiple value in single column. you can splite client1 & client2 in comma saperated value or convert into json format then store it.
But i will not recommend you to do that.
Instead of store in single column, create new table with id(pk), share_with, Members_id(relation with ur table).
insert two row into this new table, if user selects multiple. Like
1 Client1 1
2 Client2 1

Angular FormControl CheckBox selection marks every sibling

StackBlitz: http://stackblitz.com/edit/angular-jul7bv
I am having trouble with Angular FromControl, that are being created dynamicly based od passed data.
My list displays Groups and Subgroups of specific Data, everything works almost perfectly fine, but whenever I check subgroup, every of its sibling is being marked and i am unable to come up whats wrong.
Thats my html:
<div *ngFor="let chapter of checkboxControlLabels; let i = index;">
<div class="input-checkbox-subgroup-list__checkbox">
<div class="input-checkbox">
<input type="checkbox" [attr.id]="chapter.id + '_checkboxControl_' + i"
[formControl]="getChapterControl(i)" />
<label [attr.for]="chapter.id + '_checkboxControl_'+ i">{{ chapter.title }} </label>
</div>
</div>
<div class="input-checkbox-subgroup-list__checkbox" *ngFor="let chart of chapter.charts; let x = index;">
<div class="input-checkbox chart">
<input type="checkbox" [attr.id]="chart.title + '_checkboxControl_' + x" [formControl]="getChartControl(i, x)" />
<label [attr.for]="chart.title + '_checkboxControl_' + x">{{ chart.heading }} </label>
</div>
</div>
</div>
And this is how I am mapping specific FormControl :
getChartControl(chapterIndex: string, chartIndex: number) {
return this.data.controls[chapterIndex].get('charts').controls[chartIndex];
}
As you can see on below image when I check subgroup, there is 11 selected and I have no idea how thats possible.
More intresting thing is that this doesnt apply to groups... So if I would check First group there would be only one selected...
This is FormGroupModel that I am using later on:
this.chapterChartsData.forEach(chapters => {
dataForm.push(new FormGroup({
chapter: new FormControl(false),
charts: new FormArray(Array(chapters.charts.length).fill(new FormControl(false)))
}))
});
Apparently problem was with populating list of form controls like that :
charts: new FormArray(Array(chapters.charts.length).fill(new FormControl(false)))

Checked radio button

I need to know if a radio button has been selected to hide / show other options.
<input #r4 type="radio" name="x">
<span>Group</span>
<div class="subOption" *ngIf="r4.checked"></div>
div.subOption must be displayed when it has been selected.
it's correct?¿
I would just create a new boolean variable in the component, that you set as true when radio button has been checked. With that boolean you then display the div. So for example:
isChecked: boolean = false; // our new variable
<input type="radio" name="x" (click)="isChecked = true">
<div *ngIf="isChecked">
<!-- Your code here -->
</div>
EDIT: As to multiple radiobuttons... as mentioned in a comment, radio buttons seems at this point be kind of buggy with Angular. I have found the easiest way to deal with radio buttons seems to be using a form. So wrap your radio buttons in a form, like so:
<form #radioForm="ngForm">
<div *ngFor="let val of values">
<input (change)="changeValue(radioForm.value)" type="radio" [value]="val.id" name="name" ngModel />{{val.name}}
</div>
</form>
whereas on radio button would look like the following in this example:
{
id: 1,
name: 'value1'
}
In the form there is a change event, from which we pick up the chosen radio button value.
(change)="changeValue(radioForm.value)"
Then I would just play with boolean and the value chosen:
changeValue(val) {
this.valueChosen = true; // shows div
this.chosenVal = val.name; // here we have the value chosen
}
A plunker to play with: here

Radio Button check issue using knockout foreach

Iam running foreach loop above the radio button but unfortunately i could not check any of radio button.Here is my view
<div class="tab-pane" id="tab3">
<div class="form-body">
<div class="row">
<div class="col-md-12">
<h3 class="form-section">Qualification Factor</h3>
<div class="row" data-bind="foreach: leadqualificlist">
//Here is my foreach loop
<div class="col-md-6">
<div class="form-group">
<div class="radio-list radio-list-padding">
<label class="radio-inline">
<input type="radio" name="serious" value="0" data-bind="checked:Scoreschk, attr: { name: 'grp' + $data.Negativescore}" />
Negative
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Iam having list in leadqualificlist observable array.
Radio buttons behave differently than checkboxes, see documentation:
For radio buttons, KO will set the element to be checked if and only if the parameter value equals the radio button node’s value attribute or the value specified by the checkedValue parameter. <...> When the user changes which radio button is selected, KO will set your model property to equal the value of the selected radio button.
So, having that said, you cannot set different names for your checkboxex (using attr binding), but should set value in binding, like this:
...
<input type="radio" name="serious" data-bind="value: Scoreschk, checked:$parent.selectedScoreCheck" />
...
Now your view model should look like this:
function ViewModel() {
var self = this;
self.leadqualificlist = ko.observableArray([new Qualification(0, 5),
new Qualification(1, 2),
new Qualification(2, 1)]);
self.selectedScoreCheck = ko.observable("2"); // Note here must be string!
}
Where Qualification is:
function Qualification(scoreCheck, negativeScore) {
this.Scoreschk = scoreCheck;
this.Negativescore = negativeScore;
}
See demo.

knockout validation - at least one field has a value and at least one checkbox checked

I'm trying to do some very simple validation using the knockout validation plugin. I want to validate if at least one text field has text and at least one checkbox is checked. All bindings work correctly and knockout itself is awesome so far. I've tested native validation rules and they work with messaging. I just can't get the validation to work for these 2 rules.
I realize I can check for empty values very easily with jQuery but I would really like to utilize knockout.
The model (without validation because I haven't found anything that works yet):
var SearchForm = function(collections) {
// main search fields
this.fullRecord = ko.observable();
this.title = ko.observable();
this.author = ko.observable();
// collections to search
var sources = [];
$.each(collections, function(index,collection) {
sources.push(new Source(collection));
});
this.sources = ko.observableArray(sources);
// Error handling vars
this.errors = ko.validation.group(this);
};
var Source = function(collection) {
$.extend(this,collection);
this.id = "collection-"+this.code;
this.selected = ko.observable(true);
};
Here I'm just creating a list of source objects from collection data that comes from the server. That data is irrelevant since I'm only concerned with the observable 'selected' property.
The markup:
<div id="advanced-controls" class="row">
<div class="col-sm-8">
<fieldset id="search-fields">
<div class="form-group">
<label for="fullrecord" class="control-label">Keywords:</label>
<input type="text" id="fullrecord" class="form-control" name="fullrecord" placeholder="Full Record Search" data-bind="value:fullRecord" />
</div>
<div class="form-group">
<label for="title" class="control-label">Title:</label>
<input type="text" id="title" name="title" class="form-control" data-bind="value:title"/>
</div>
<div class="form-group">
<label for="author" class="control-label">Author:</label>
<input type="text" id="author" name="author" class="form-control" data-bind="value:author"/>
</div>
<div class="form-group">
<button id="advanced-search-submit" class="btn btn-primary" data-bind="click:search">Search</button>
<button id="advanced-search-reset" class="btn" data-bind="click: clear">Clear All</button>
</div>
</fieldset>
</div>
<div class="col-sm-4">
<fieldset data-bind="foreach: sources">
<div class="form-group">
<input type="checkbox" name="collections" data-bind="attr:{ id:id, value:code }, checked:selected, click: $parent.clearRequiredSourceError ">
<label data-bind="attr:{ for:id }, text: name"></label>
</div>
</fieldset>
</div>
</div>
In the validation function before submitting:
// If there's any knockout validation errors
if (model.errors().length > 0) {
model.errors.showAllMessages();
isValid = false;
}
I've tried setting a custom validation extension on the observable array of sources like this:
this.sources = ko.observableArray(sources).extend({
validation: {
validator : function (sources) {
var anySelected = false;
$(sources).each(function(){
anySelected = this.selected();
});
return anySelected;
},
message: 'At least one source is required to search.'
}
});
But that doesn't fire when the checkboxes are clicked, only when the array is changed ~ push, pop, etc. Yes I have the config set correctly:
ko.validation.configure({
grouping: {
deep: true,
observable: true
}
});
This seems like it should be very simple to achieve. Maybe my brain is just fried from diving into the whole knockout world this week. Any suggestions are greatly appreciated. Thanks in advance!
Forgive me for not reading your entire question, as it is very long, but I am curious if you need Knockout validation for this or if you are looking for something like this -
var selectedOption = ko.observable();
var selectionsOk = ko.computed(function () {
((!!field1()|| !!field1()|| !!field1())&&!!selectedOption())
});
Where selectedOption is a list of radio buttons, and once one is selected returns the value, and you could either use an observableArray to contain each of your fields so it is dynamic or you list the fields out and make sure that at least one of them has a value. The !! will evaluate your observable as true or false, true would be returned unless the observables' value was null, undefined, '', or false
The selectionOk computed could be used to prevent clicking some button to proceed or inversely for displaying an error message until the conditions are met.

Categories