I'm trying to create a dropdownlist using Kendo UI, it's working great except for having a default selected value when the screen loads.
according to their documentation my code should look like this:
HTML:
<kendo-dropdownlist formControlName="description"
[data]="definitionData.Languages"
[(ngModel)]="languageValue"
[textField]="'Value'"
[valueField]="'Key'"
[value]="2"
[valuePrimitive]="true">
</kendo-dropdownlist>
<span class="left col-xs-6">
<input type="text" id="descriptionField" class="form-control" [value]="getValue(descriptionForm.controls.description.value)" #descriptionField (blur)="updateDescriptionValue(descriptionField.value, languageValue)" />
</span>
COMPONENT:
public descriptionForm: FormGroup = new FormGroup({
description: new FormControl()
});
My dropdown works, but the default selected value is blank when I load the page, and it should be the object with Key: 2
note: I don't want to use [defaultItem] since It will just duplicate the item, meaning it will be in the dropdown list 2 times.
I've tried numerous things, but I can't figure out what I should do!
Thanks in advance
You should choose between value and ngModel binding. From documentation:
The DropDownList does not support the simultaneous usage of the value property and the ngModel value binding.
Solution with value property:
Delete ngModel from HTML.
Bind to valueChange event and set value in your model.
HTML:
<kendo-dropdownlist formControlName="description"
[data]="definitionData.Languages"
(valueChange)="handleValue($event)"
[textField]="'Value'"
[valueField]="'Key'"
[value]="2"
[valuePrimitive]="true">
</kendo-dropdownlist>
COMPONENT:
handleValue(value) {
this.languageValue = value;
}
Solution with ngModel property:
Delete value from HTML.
Set default value in your model.
HTML:
<kendo-dropdownlist formControlName="description"
[data]="definitionData.Languages"
[(ngModel)]="languageValue"
[textField]="'Value'"
[valueField]="'Key'"
[valuePrimitive]="true">
</kendo-dropdownlist>
COMPONENT:
constructor(){
this.languageValue = 2;
}
Related
I have a set of data response from an API and dynamically generating checkboxes on my HTML file using DataView component of PrimeNG.
The goal is to have a functionality where I can select/unselect all checkbox via button click and store their values in an array, for example.
Here's what I have so far;
Component HTML
<p-dataView [value]="requestList" {...} >
<ng-template let-request pTemplate="listItem">
<p-checkbox
name="reqNo"
inputId="reqNo"
(click)="getCheckBoxValue()"
value="{{ request.requestNo }}"
[(ngModel)]="reqNo"
[ngModelOptions]="{ standalone: true }"
></p-checkbox>
</ng-template>
</p-dataview>
Main TS File
reqNo: any; reqNo is binded using ngModel.
Giving me arrays of values when consoled;
['R08000036', 'R08000002']
Each object in the API response looks like this;
{
requestNo: "R08000036",
requestBy: "SUPER_USER",
requestTs: "2021-02-18T04:27:05.710+0000",
collectTs: "2008-07-30T16:00:00.000+0000",
testReason: "After Visit",
noOfPrisoner: 2,
status: "Printed",
printTs: "2008-07-21T16:00:00.000+0000",
escortingOfficer: "00552",
}
getCheckBoxValue event handler;
getCheckBoxValue() {
console.log(this.reqNo);
}
I'm new to Angular and I think I'm using the ngModel wrong. Can someone please teach me?
You can select all values by setting a new value for reqNo by values from requestList.
selectAll() {
this.reqNo = this.requestList.map(item => item.requestNo);
}
unselectAll() {
this.reqNo = [];
}
Example
I have name and values ,calling from the ts side and want to validate it.the values are'nt getting from the event and it's been comming such as (on) .
<form [formGroup]="reactiveForm">
<div *ngFor="let item of checkBoxValueList">
<input
type="radio"
formControlName="yourChoice"
[value]="item"
(change)="event($event)"
>
{{item}}
</div>
</form>
<pre>
{{reactiveForm.value | json}}
</pre>
checkBoxValueList = [
'Reading',
'Watching',
'Traveling',
'Cooking'
];
reactiveForm: FormGroup = new FormGroup({
yourChoice: new FormControl()
});
constructor() {}
edit(eve) {
console.log(eve);
console.log("target", eve.target.value);
}
You can pass directly your value instead of event.
Try it.
(change)="edit(item)".
Hope this helps.
I guess that you only need the selected value on change event and validate it. So here you can access the selected value of radio button by our reactiveForm variable.
event(eve) {
console.log(eve);
// console.log("target", eve.target.value);
console.log(this.reactiveForm.value['yourChoice']); //this will give your selected value
}
Hope this helps!!
From what I know VueJS has a way to use a getter and setter for their computed properties per this documentation on Computed property.
I have here the vue component where you can see the amount is an object and we have a group of persons from the vuex store.
data() {
return {
form: {
amounts: {},
},
};
},
mounted() {
const persons = this.$store.getters.getPersons()
persons.forEach((person) => {
this.$set(this.form.amounts, person.id, '0.00');
});
},
I made it so I can associate a person to the amount he has paid on the form by linked it using the ID and the payment. This is an example of what this.form.amounts should look like.
{'HKYDUPOK': 0.00},
{'RYYJPUKA': 0.00},
{'KZMUYTAK': 0.00}
Now by default, their values should be 0.00, on the input number field where they entered the amount, by default I applied them to v-model which looks like this:
<div v-for="person in persons">
<input
class="form-control"
v-model="form.amounts[person.id]"
type="number"
step=".01"
min="0"
required>
</input>
</div>
But here is the thing, when you open your code snippet on the browser, you notice that the input number field has the default value of 0.00 which acts as somewhat a placeholder. I wanted to remove the default value of 0.00 on the number input and have it instead to an empty input yet the underlying value of the amounts per person is not null but still 0.00 or 0. This is so that the form is clear of input when the user tries to input values on the input box instead of having to erase and replace 0.00 with an actual value (Hope this is clear). Now there is a possibility that on the total amount, there are at least 1 or more persons with an amount of 0. I wanted to make sure that an empty input number field does not result in null but instead, it's 0. Is this possible?
I tried checking the computed property getter and setter for this to change the default binding yet how do you map the form.amounts to match the amount to its corresponding person? On the Get, if the value is not more than 0.00 or 0, then return an empty value to the input field. Set is the bigger problem for it only accepts one parameter which is called newValue and would be hard to say pass the personId to map the amounts to the corresponding person. Is there a way to touch upon and manipulate the binding of a data property which is an object yet also change the default behavior on the model to return empty instead of 0.00? I hope my question is clear enough.
I assume this is a follow on from your previous question...
At this stage, you're best creating a component to represent your data input element.
Something like this (using a single-file component example)
<!-- number-input.vue -->
<template>
<input class="form-control" type="number"
step=".01" min="0"
:value="amount"
#input="updated"
required />
</template>
<script>
export default {
name: 'NumberInput',
props: {
value: Number
},
computed: {
amount () {
return this.value || ''
}
},
methods: {
updated ($event) {
this.$emit('input', parseFloat($event.target.value) || 0)
}
}
}
</script>
Then you can use it in your parent template
<div v-for="person in persons" :key="person.id">
<NumberInput v-model="form.amounts[person.id]" />
</div>
Just remember to import and use the component...
<script>
import NumberInput from 'number-input'
export default {
components: { NumberInput },
// etc
}
</script>
JSFiddle Demo
Also see https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components
I've got the following 'triple level' nested form:
FormGroup->ArrayOfFormGroups->FormGroup
Top level (myForm):
this.fb.group({
name: '',
description: '',
questions: this.fb.array([])
});
Nested form array element for 'questions':
this.fb.group({
priority: ['1'],
params: this.fb.group({parameter: ['']})
});
Nested form group element for 'params' is a key:value object of random length.
I'm using the following ngFor to go through elements:
<tr *ngFor="let questionConfigForm of myForm.controls.questions.controls; let i=index" [formGroupName]="i">
...
<div *ngFor="let param of objectKeys(questionConfigForm.controls.params.controls)" formGroupName="params">
<input type="text" [formControlName]="param">
I've got the following behavior:
When I'm updating any of the fields on first two form levels I could instantly see changes in corresponding form controls values with {{myForm.value | json}}.
But if I input something in one of 'params' controls I couldn't see any changes in myForm values, but the form data for 'params' controls will be updated if I will make any changes in corresponding 'questions' form.
For me it looks like 'param' form control receives input data, but doesn't trigger some update event, and I don't know how to fix that, except writing my own function to react on (change) and patchValue in form..
So my question is how to make 'params' controls update myForm without that strange behavior?
UPD:
initQuestionConfig() {
return this.fb.group({
priority: ['1'],
params: this.fb.group({parameter: ['']}),
});
}
addQuestionConfig() {
const control = <FormArray>this.myForm.controls['questions'];
const newQuestionCfg = this.initQuestionConfig();
control.push(newQuestionCfg);
}
Finally the problem is solved.
The root of this issue was the way I've cleaned up already existing 'params'.
To remove all parameters from 'questions' I used the following code:
const control = <FormArray>this.myForm.controls['questions'];
control.controls[index]['controls'].params = this.fb.group([]);
And the reason of those glitches was this new 'fb.group' instance.
Now I'm removing params one by one, keeping original formGroup instance and it works as expected:
const control = <FormArray>this.myForm.controls['questions'];
const paramNames = Object.keys(control.controls[index]['controls'].params.controls);
for (let i = 0; i < paramNames.length; i++) {
control.controls[index]['controls'].params.removeControl(paramNames[i]);
}
#MilanRaval thanks for your time again :)
Try this: Give formArrayName and formGroupName like below...
<div formArrayName="testGroup">
<div *ngFor="let test of testGroup.controls; let i=index">
<div [formGroupName]="i">
<div class="well well-sm">
<label>
<input type="checkbox" formControlName="controlName" />
</div>
</div>
</div>
</div>
I have a simple input that I want to reset the value to empty string after I am adding hero. The problem is the value is not updated. why?
#Component({
selector: 'my-app',
template: `
<input type="text" [value]="name" #heroname />
<button (click)="addHero(heroname.value)">Add Hero!</button>
<ul>
<li *ngFor="let hero of heroes">
{{ hero.name }}
</li>
</ul>
`,
})
export class App {
name: string = '';
heroes = [];
addHero(name: string) {
this.heroes.push({name});
// After this code runs I expected the input to be empty
this.name = '';
}
}
You have one-way binding so when you're typing something in your input your name property isn't changed. It remains "". After clicking on Add hero! button you doesn't change it.
addHero(name: string) {
this.heroes.push({name}); // this.name at this line equals ''
this.name = ''; // it doesn't do any effect
}
Angular2 will update value property only if it is changed.
Use two-way binding which is provided by #angular/forms
[(ngModel)]="name"
to ensure that your name property will be changed after typing.
Another way is manually implementing changing
[value]="name" (change)="name = $event.target.value"
In Angular Template binding works with properties and events, not attributes. as per html attribute vs dom property documentation of angular so as you have used [value] binding its binding to attributes not to the property of that input and because of it value remain in it after you set this.name = "".