Angular change the state of a checkbox after user click - javascript

I have the following code that should set the checked value to false on click:
#Component({
template: `
<input type="checkbox" [checked]="checked" (change)="onChange()">
`
})
export class AppComponent {
checked = false;
onChange() {
setTimeout(() => {
this.checked = false;
}, 1000)
}
}
The problem is that if we click on the input and we wait for a second, it'll stay checked. Why is this happening? Why Angular doesn't change it to false again?

Long story short Angular checkboxes are just broken : Issue
If you however want to achive this effect i will recommend you to create your own custom component that will act the same way as a checkbox.
Here is one more fun example of Checkbox madnes try to interact with both "With track by" and "No track by" blocks and see what happens.

I think you can do that easily by using [(ngModel)]="checked". Your code is working in the stackblitz link. Please check that. Here is my code given below.
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<input type="checkbox" [checked]="checked" [(ngModel)]="checked" (change)="onChange()" name="horns">
<label for="horns">Horns</label>
`,
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
checked = false;
onChange() {
setTimeout(() => {
this.checked = false;
}, 2000)
}
}

in angular you can manipulate dom using view child and element ref
first of all you need to import viewchild and elementRef in your component
app.component.ts
import { Component, VERSION } from "#angular/core";
import { ViewChild, ElementRef } from "#angular/core";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
#ViewChild("checkBox") el: ElementRef;
onChange() {
setTimeout(() => {
this.el.nativeElement.checked = false;
}, 100);
}
}
app.component.html
<input type="checkbox" #checkBox (click)="onChange()">
stackblitz

Related

angular form is not detecting the value changing

I don't know why the form is not working!
the input does not change the values in the form.
and the valueChanges is not detecting anything. any help?
applied on stackblitz:
https://stackblitz.com/edit/angular-ivy-w68v69?file=src/app/app.component.ts
import { Component, VERSION } from "#angular/core";
import { FormControl, FormGroup, Validators } from "#angular/forms";
#Component({
selector: "my-app",
template: `
<form [formGroup]="form">
<input
FormControlName="patientName"
placeholder="Enter Patient Name ..."
/>
</form>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent {
form: FormGroup;
ngOnInit() {
this.form = new FormGroup({
patientName: new FormControl("")
});
this.form.get("patientName").valueChanges.subscribe(x => console.log(x));
this.form.valueChanges.subscribe(next => {
console.log("valueChanges didtted");
console.log(next);
});
console.log("form created");
}
}
The property FormControlName in the HTML part should have the 'F' in lowercase : formControlName="patientName".
It you correct this, it works : https://stackblitz.com/edit/angular-ivy-cjntrr?file=src/app/app.component.ts

How to unchecked and check the Nebular Check box dynamically after rendering

I am using a nebular theme checkbox in the Angular 8 App.
<nb-checkbox [checked]="enable_checked" (checkedChange)="enable($event)" >Enable </nb-checkbox>
i am updating the checkbox using "enable_checked" Boolean .When the component loaded it works fine but when I changed the value dynamically of BOOLEAN("enable_checked") it is not getting updated at the front end but the boolean is updated.
It's working you must change it like this :
<nb-checkbox [checked]="enable_checked" (checkedChange)="enable($event)" >Enable </nb-checkbox>
<button (click)="changeCheckbox()">Set false</button>
For more information: Docs
Typescript :
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
enable_checked = true;
changeCheckbox() {
this.enable_checked = false
}
}
Stackblitz Example: link

Angular - How do I detect form events from inside a directive when they are initiated in component.ts file?

If I have a component with a form input and I want to detect the two statements in the OnInit block as events inside my directive, what is the correct way to do this? I have had luck with 'input' and 'ngModelChange', but none of the events I try to listen to catch the patchValue() method for model driven forms or the straight assignment for template driven forms (even though it reflects in the DOM).
Here is my Component:
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms'
#Component({
selector: 'my-app',
template:
`
<h5>Model form input</h5>
<form [formGroup]="inputForm">
<input patchable-input formControlName="input" />
</form>
<h5>Template form input</h5>
<input patchable-input [(ngModel)]="input" />
`
})
export class AppComponent implements OnInit {
inputForm = new FormGroup({
input: new FormControl('')
})
input = '';
ngOnInit() {
this.inputForm.patchValue({
input: 'testing patch'
})
this.input = 'testing override'
}
}
Here is my Directive:
import { Directive, HostListener } from '#angular/core';
#Directive({
selector: '[patchable-input]'
})
export class PatchableInputDirective {
#HostListener('ngModelChange', ['$event']) ngOnChanges($event) {
console.log($event);
}
}
and a minimal reproduction in StackBlitz (watch the console)
You have to implement AfterViewInit instead of OnInit. The reason for that is at this point in the life cycle your directive has been initialized and has subscribed to the ngModelChange event via the #HostListener decorator.
See also the Angular Life Cycle Hooks documentation.
stackblitz
import { Component, AfterViewInit } from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms'
#Component({
selector: 'my-app',
template:
`
<h5>Model form input</h5>
<form [formGroup]="inputForm">
<input patchable-input formControlName="input" />
</form>
<h5>Template form input</h5>
<input patchable-input [(ngModel)]="input" />
`
})
export class AppComponent implements AfterViewInit {
inputForm = new FormGroup({
input: new FormControl('')
})
input = '';
ngAfterViewInit() {
this.inputForm.patchValue({
input: 'testing patch'
})
}
}

Angular 2 update child component's class list from parent

I'm new to Angular 2 and I need some help with the following issue.
I have a parent and a nested, child component:
// The Parent:
import { Component, ViewChild } from 'angular2/core';
import {Preloader} from 'components/preloader/preloader';
#Component({
selector: 'console',
providers: [Preloader],
directives: [Preloader],
templateUrl: 'components/console/console.html'
})
export class Console {
#ViewChild(Preloader) preloader: Preloader;
constructor(preloader: Preloader) {
this.preloader = preloader;
}
ngAfterViewInit() {
this.preloader.showConsole();
}
}
// ...and the Child
import {Component} from 'angular2/core';
#Component({
selector: 'preloader',
template: `
<div [ngClass]="style"></div>
`
})
export class Preloader {
constructor() {
this.style = {
fullscreen: true,
done: false
};
}
showConsole() {
// this is not working:
this.style.done = true;
}
}
I'd like to set both variables in style object to true when the parent component is fully mounted. That actually happends, but in the Preloader's template I see only fullscreen class even after showConsole method was called and style.done was set to true.
console.html template is just like this:
<div class="main-window">
<preloader></preloader>
</div>
I just tested and your solution is working without any problem.
But if you still say fullscreen class remains same then you can consider below solution,
ngAfterViewInit() {
setTimeout(()=>{
this.preloader.showConsole();
},0)
}
showConsole() {
this.style.fullscreen = false; //<<<===added.
this.style.done = true;
}
I've figured it out!
The problem was in the communication between two components. First of all this is how I should have pass the data in the template:
<div class="main-window">
<preloader [start]='showConsole'></preloader>
</div>
But, the most important thing, it also requires to specificate input variables in the child #Component like this:
#Component({
inputs: ['start'],
selector: 'preloader',
template: `<div [ngClass]="style"></div>`
})

Angular 1 directive inside angular 2 application

We created an Angular 2 application using this awesome Angular2 Seed which works very well. So the question that I have is, how can I upgrade this Angular 1 directive:
import template from './sbgOutlineButton.html!text';
var app = angular.module('sbgOutlineButton', []);
app.directive('sbgOutlineButton', function() {
let link = function(scope, element, attributes) {
if (attributes.icon === undefined) {
let materialIcon = element.find('i.material-icons');
materialIcon.addClass('hidden');
}
};
return {
link: link,
restrict: 'E',
template: template,
replace: true,
transclude: true,
scope: { icon: '#' }
};
});
export default app;
So that I can use it in the following Angular 2 component:
import { Component, OnInit, ChangeDetectionStrategy } from '#angular/core';
import { UpgradeAdapter } from '#angular/upgrade';
#Component({
moduleId: module.id,
selector: 'test-page',
templateUrl: 'testpage.page.html',
styleUrls: ['testpage.page.css']
})
export class TestPage implements OnInit {
constructor() { }
ngOnInit() { }
}
Do you guys maybe have any idea on how I will be able to accomplish this? Is it even possible? Because a lot of the other articles that I have found during my research suggests that your "base" application should be Angular 1...
Thanks in advance.
Francois
How about converting your angular1 directive to angular2 directive?
NOTE: I don't know whether it will be useful or not but just have a look.
Look at the demo here : https://plnkr.co/edit/4Fhtm76iJl0aQmgjO7n0?p=preview
customeDirective.ts
import {Directive, Attribute,ElementRef,Renderer} from '#angular/core';
#Directive({
selector: '[myAttr]'
})
export class myDir {
constructor(#Attribute('icon') private icon,private el:ElementRef,private rd: Renderer){
console.log(this.icon);
if(this.icon===null){ //<--- you can play here as per your need.
console.log('icon is undefined');
}
else{
rd.setElementClass(el.nativeElement, 'myClass',true);
}
console.log(el.nativeElement);
}
}
AppComponent.ts
//our root app component
import {Component} from '#angular/core';
import {myDir} from 'src/customDirective';
#Component({
selector: 'my-app',
directives:[myDir],
template:
`
<style>
.myClass{
color:red;
background:yellow;
}
</style>
<div myAttr icon="myIcon">Angular2</div> <!-- icon attribute is present so it will add the class -->
<!-- OR USE BELOW HTML INSTEAD OF ABOVE -->
<div myAttr>Angular2</div> <!-- icon attribute is not present so it gives null -->
`
})
export class App {}
You need to upgrade to angular2 by using "#angular/upgrade": "2.0.0-rc.4",
Guide
Because a lot of the other articles that I have found during my
research suggests that your "base" application should be Angular 1...
It's if you have a already angular 1 project and you want to upgrade to one. Angular2 don't need angular1 as base
writing directive in angular2
import { Directive, ElementRef, Input } from '#angular/core';
#Directive({ selector: '[myHighlight]' })
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
My First Attribute Directive
Highlight me!
import { Component } from '#angular/core';
import { HighlightDirective } from './highlight.directive';
#Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
directives: [HighlightDirective]
})
export class AppComponent { }
you Don't need to mix up angular1 into two..

Categories

Resources