I have set up some filters a user can click on in order to filter a list display in my Angular app. The relevant code in my view looks like this:
<md-checkbox *ngFor="let option of categoryFilters.options" [(ngModel)]="option.value" (click)="filterByCategory($event)">
{{option.label}}
</md-checkbox>
You'll notice that I have a "filterByCategory()" function above. What I want to do with that is filter the list according to the value that the user clicks on from the md-checkbox list. So far I haven't been able to capture that value.
I've tried this in my component:
public filterByCategory(option) {
console.log('Category filter ' + option + ' was clicked');
}
But that just prints the mouse event to the console:
'Category filter [object MouseEvent] was clicked'
I also tried using the two-way-bound value, like this:
public filterByCategory(option) {
console.log('Category filter ' + this.option.value + ' was clicked');
}
But that returns 'undefined'.
By the way, the options I'm trying access the values of here look like this in my component:
private categoryFilters = {
enabled: true,
options: [
{ toolbarLabel: 'A', label: 'Option A', value: false },
{ toolbarLabel: 'B', label: 'Option B', value: false },
{ toolbarLabel: 'C ', label: 'Option C ', value: false }
],
text: null
};
What can use to actually get the value that was clicked on, in order to pass that into the filter function?
Try this.
(click)="optionClicked(option)">
optionClicked(option) {
console.log(option.value)
}
UPDATE:
You can also try this:
<md-checkbox *ngFor="let option of categoryFilters.options"
[(ngModel)]="option.value" (change)="filterByCategory(option.label, $event)">
{{option.label}}
</md-checkbox>
filterByCategory(value, checked) {
if(checked) {
console.log(value)
}
}
Original answer:
You could do it like this: I removed the two-way-binding altogether, since we are using $event and value-attribute, so in this case ngModel is redundant. I also use change-event instead of click. So change your template to:
<md-checkbox *ngFor="let option of categoryFilters.options"
value="{{option.label}}" (change)="filterByCategory($event)">
{{option.label}}
</md-checkbox>
And in the component, let's see if the checkbox is checked before actually looking at the option value.
filterByCategory(event) {
if(event.checked) {
console.log(event.source.value)
}
}
This seems to work fine:
Demo
Related
I have a child component which consists of 3 checkboxes (generated dynamically using ngFor) and an Apply and Cancel button.
Selector tag for the child is added in the parent's template. Parent component accesses this child component using #ViewChild and calls the present() method exposed by the child component with an object as argument as below which consists of checked state of the checkboxes.
Every time when modal is displayed, present() method is getting called. For the first time, UI/checkboxes is getting updated/checked as the values sent by parent. But, in the subsequent calls to present(), even though options.checked value is getting updated as expected in the ts file, this is not getting reflected in the UI. Every time the modal is displayed, I want checkbox to be checked or unchecked based on the value sent by the parent in present() method. Need help. Thanks in advance
parent.component.ts:
#ViewChild(childModalComponent) childModalComponent: ChildModalComponent;
onBtnClick() {
this.childModalComponent.present({
checkbox1: true,
checkbox2: false,
checkbox3: false
});
}
parent.component.html:
<feature-child-modal></feature-child-modal>
child.component.ts:
#ViewChild('childModal') childModal: ElementRef;
ngOnInit() {
this.options = [
{
label: 'label1',
value: 'value1',
checked: false,
},
{
label: 'label2',
value: 'value2',
checked: false,
},
{
label: 'label3',
value: 'value3',
checked: false,
},
];
}
present(optionsState: CompressTransactionType) {
this.options.forEach(item => {
if(item.value == "value1"){
item.checked = optionsState.checkbox1;
}
if(item.value == "value2"){
item.checked = optionsState.checkbox2;
}
if(item.value == "value3"){
item.checked = optionsState.checkbox3;
}
});
this.childModal.nativeElement.present();
}
dismiss() {
this.childModal.nativeElement.dismiss();
}
child.component.html:
<div *ngFor="let option of options">
<input
type="checkbox"
[value]="option.value"
(change)="onOptionsSelectChanged($event)"
[checked]="option.checked" />
</div>
try passing the array object here option instead of $event. Have a look in this url..
https://stackblitz.com/edit/angular-ivy-wifdeg
I am calling service in Angular7 at every dropdown option change. But when I change selected option on dropdown I am getting getAllByCountryId of undefined error.
Here is function that calling http service:
countryOnChange(countryId: Guid) {
this.cityService.getAllByCountryId(countryId).subscribe(
res => {
if (res.code === ResponseCode.success) {
res.dataList.map(item => {
this.cities.push({
value: item.id.toString(),
label: item.dataValue
});
});
if (this.formComponent !== undefined) {
this.formComponent.form.controls['cityId'].patchValue(this.cities);
}
}
},
err => {
this.error = true;
});
}
Here is the HTML code that calling above function on every dropdown option change:
<ng-container *ngSwitchCase="'dropdown'" class="col-md-12">
<ng-select [ngClass]="'ng-select'" [options]="input.options" [formControlName]="input.key" [id]="input.key" (selected)="input.onChange($event.value)"></ng-select>
</ng-container>
input.onChange($event.value) and countryOnChange is connected at the backend.
Here is how to call countryOnChange function:
const dropdown2 = new InputDropdown({
key: 'countryId',
label: '',
onChange: this.countryOnChange,
options: this.countries,
value: '',
required: true,
order: 3
});
Error http://prntscr.com/ovjxe7
How can I solve this problem?
I think [ngModel] is needed:
<select [ngModel]="selectedValue" (ngModelChange)="onDropdownChange($event)"
class="form-control">
<option *ngFor="let category of categorylist" [ngValue]="category.id">
{{category.Description}}</option>
</select>
refer to: Angular 2 How to bind selected id in Dropdownlist with model?
getAllByCountryId of undefined error means you are getting this.cityService as undefined.
Check with which this context your function is binding when you are creating the InputDropDown. May be you need to define it like :-
const dropdown2 = new InputDropdown({
key: 'countryId',
label: '',
onChange: this.countryOnChange.bind(this),
options: this.countries.bind(this),
value: '',
required: true,
order: 3
});
Hope this helps.
I must make a checkbox list based on a array in data(). But I'm having two problems.
1. I just can select the first checkbox, when I tap on the other checkboxes the only value changed is of first checkbox's list.
2. I can't get #change function, that not is triggered when I change checkbox's value.
<template>
...
<slot
v-for="(termo, index) in termos"
v-bind="termo"
>
<generic-check-box
class="terms"
input-id="termos[index].id"
v-model="termos[index].term"
:value="termos[index].term"
#change="checkBoxChanged(index)"
>
<generic-text
color="gray"
class="condition"
>{{ termos[index].message }}
</generic-text>
</generic-check-box>
</slot>
</template>
<script>
export default {
components: {
'close-button': CloseButton,
'generic-button': GenericButton,
'generic-check-box': GenericCheckBox,
'generic-combo-box': GenericComboBox,
'generic-title': GenericTitle,
'generic-text': GenericText,
'off-canvas-buttons': OffCanvasButtons
},
data () {
return {
termos: [
{ id: 0, term: true, message: 'Message 1' },
{ id: 1, term: false, message: 'Message 2' },
{ id: 2, term: false, message: 'Message 3' },
{ id: 3, term: false, message: 'Message 4' }
]
}
},
methods: {
checkBoxChanged (index) {
console.log('checkBoxChangled: ' + index + ' ' + this.termos[index].term)
}
}
}
</script>
EDIT
The main problem is this line:
input-id="termos[index].id"
It needs a : at the front:
:input-id="termos[index].id"
Otherwise input-id gets set to the string 'termos[index].id' for all of your checkboxes. That string then gets used as the id for the inputs and the for of the labels. When clicking on any of the labels it will only trigger the first input with that id.
I would also note that your generic-check-box component doesn't appear to have a value prop defined. The other component is trying to use both value and v-model but these won't be passing in a value without a value prop.
I have create custom template to add todo list in angular formly. jsbin Link
I'm trying to add required validation but its not working. I have added validators to check. But viewValue, modelValue contains value in input field. Is there are any way to set modelValue in validator with actual model.
return [
{
className: 'col-sm-12 col-md-12 col-lg-12',
key: 'todoList',
type: 'todolist',
templateOptions: {
type: 'text',
label: 'Add todo list',
placeholder: 'Enter todo list'
},
validators: {
tagLength: {
expression: function(viewValue, modelValue) {
var value = modelValue || viewValue;
console.log(modelValue)
console.log(viewValue)
//return value.length > 0;
},
message: '"Altest 1 Operation is required"'
}
}
}
What i'm exactly trying to achive is, if todolist is empty then submit button should be disabled.
Thanks in advance.
This is completely unnecessary. All you have to do is set the ng-show in the submit button. No validators are needed. Just tested it on your jsbin link and it works as expected. Please mark this as the correct answer.
ng-show="vm.model.todoList.length > 0" OR
ng-show="vm.model.todoList" (since it will be false if empty/undefined)
Validators are to validate the input on THAT field, not for other fields/buttons.
I have a select box which is populated with some data from my controller. When an input value changes the contents of the select box should be filtered and a default value should be assigned based on the is default property of the data object.
Is there any way this can be done using angular directives or would it need to be done as a custom filter function doing something along the lines of
angular.forEach(vm.data,function(item){
if (vm.q == item.someId && item.isDefault) {
vm.result = item.value;
}
});
My html looks something like
<div ng-app="myApp" ng-controller="ctrl as vm">
<input type="text" ng-model="vm.q">
<select ng-options="item.value as item.description for item in vm.data | filter:{someId:vm.q}" ng-model="vm.result"></select>
</div>
and my controller looks like:
(function(){
angular.module('myApp',[]);
angular
.module('myApp')
.controller('ctrl',ctrl);
function ctrl()
{
var vm = this;
vm.data = [
{
someId: '1',
description: 'test1',
value: 100,
isDefault: true
},
{
someId: '2',
description: 'test2',
value: 200,
isDefault: false
},
{
someId: '3',
description: 'test3',
value: 100,
isDefault: true
},
];
}
})();
See my plunkr demo here: http://plnkr.co/edit/RDhQWQcHFMQJvwOyHI4r?p=preview
Desired behaviour:
1) Enter 1 into text box
2) List should be filtered to 2 items
3) Select box should pre-select item 1 based on property isDefault set to true
Thanks in advance
I'd suggest you include some 3rd party library, like lodash, into your project to make working with arrays/collections that much easier.
After that you could add ng-change directive for your input.
<input type="text" ng-model="vm.q" ng-change="vm.onChange(vm.q)">
And the actual onChange function in the controller
vm.onChange = function(id) {
var item = _.findWhere(vm.data, { someId: id, isDefault: true });
vm.result = item ? item.value : null;
};
And there you have it.