prevent onclick event while changing radio button of primeng - javascript

Hi have simple radio buttons of primeng, while changing the choise, I have some logic on the onClick function, checking if the user changed some fields, if he changed I will show message if he sure he want to leave the choice of the radio button, if he will press "cancel" I want to cancel all the event of the onlick function and to undo to his last choise. but the event of the onclick not doing it, I checked all the function of java script. I tried now to add HostListener that if some boolean field(the one that said the user want to undo)it will stopImmediatePropagation. but on runtime the onclick function called and not the HostListener. some ideas what to do?
radio button
<p-radioButton name="treesDetailsType" [(ngModel)]="selectedType" formControlName="selectedType" (onClick)="onChangeType(type,$event)" class="treeDetails" value="{{type.id}}" label="{{type.desc}}" [disabled]="isReadOnly && type.id != data.selectedType"></p-radioButton>
the onclick function
onChangeType(type, event) {
let change = this.checkChanges(type, event);
if (change) {
//HERE I WANT TO CANCEL ALL THE CHANGE AND TO LEAVE THE FUNCTION
this.clickDisallowed = true;
}
else {
switch (type.id)
.....
}
}
the host listner
#HostListener('click', ['$event']) onClick(event) {
if (this.clickDisallowed) {
event.stopImmediatePropagation();
}
console.log(event);
}

Maybe you are using the hostlistener wrongly.
In the angular example it is used inside a directive
https://angular.io/api/core/HostListener
Try this example!
#Directive({selector: 'button[counting]'})
class CountClicks {
numberOfClicks = 0;
#HostListener('click', ['$event.target'])
onClick(btn) {
console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
}
}
#Component({
selector: 'app',
template: '<button counting>Increment</button>',
})
class App {}

Related

Remove mouse over and mouse out event after clicking that element

I have a input box in which i am toggling the text on mouse over and mouse out event but when I click that box i want to remove mouse hover effect,but after clicking it still changes on mouse hover
onMouseOver() {
this.placeHolder= 'text1';
}
onMouseOut() {
this.placeHolder = 'text2';
}
onMouseFocus() {
this.placeHolder ='text3';
}
There are many ways to do this. See here a possible duplicate.
But short version that I prefer:
Work with variable
clicked: boolean = false;
onClick() {
if (!clicked) {
// Do what you wanna do
clicked = true;
}
}
Second with html
// Code behind
clicked: boolean = false;
onClick() {
// Do what you wanna do
clicked = true;
}
// HTML
<button (click)="!clicked ? onClick() : null">CLICK ME</button>
So, yes, other ways are possible like removeEventListener with Angular's renderer2 and so on. But that's not good. Never change the html directly by yourself. Let Angular doing it.

Simple way to detect click outside of child component

I want to expand and contract child div component depending on the value of a variable, but I want to be able to click out of that component (in the parent of the sibling) as well as collapsing it.
Here's an stackblitz example. I have attempted to use HostListener from what I found in this question, but it did not help my case.
#HostListener('document:click', ['$event'])
documentClick(event: MouseEvent) {
// your click logic
}
Objectives:
When I click on the child (hello) component, I want it to expand if it is not already and contract if it is already expanded
When I click on anything else (ie. parent or sibling component), I want the child (hello) component to contract if it is expanded.
I do not want the child (hello) component to expand when clicking in the parent/sibling.
Update: Using HostListener
hello.component.html
<div class="box" (click)="clicked()" [ngClass]="{large: isEnlarged}">Hello.component</div>
hello.component.ts
export class HelloComponent {
isEnlarged = false;
clicked() {
this.isEnlarged = !this.isEnlarged;
}
#HostListener('document:click', ['$event'])
documentClick(event: MouseEvent) {
console.log('clicked');
this.isEnlarged = false;
}
}
app.component
export class AppComponent {
}
The problem is your click handler is setting expanded to true before document click event handler sets it to false, so it's always false.
You could only set it to false if the event target is not your component:
https://stackblitz.com/edit/mouse-click-anywhere-8bwg6p?file=src/app/hello.component.ts
#HostListener('document:click', ['$event'])
documentClick(event: MouseEvent) {
console.log('clicked');
console.log(event);
if (event.target.id !== 'box') {
this.isEnlarged = false;
}
}

Polymer 3, onfocusout or onblur events

how can I invoke onfocusout or onblur menthods in Polymer 3? on-click event works perfectly when I click on menu button but the on-blur or on-focusout doesn't work? I want the menu to close when someone click outside menu?
static get properties() {
return {
_openMenu: Boolean
};
}
_toggleMenu(){
this._openMenu= !this._openMenu;
}
_closeMenu(){
this._openMenu= false;
}
My button looks something like this
<button on-click="${this._toggleMenu()}" on-blur="${this._closeMenu()}">
Ok I fixed my problem like this. Just removed the on-click and on-blur event from my button
<button>Click</button>
On connectedCallBack() I add eventListener to window object, so I can find out where the click has happened. If the click is inside the menu then I toggle my _openMenu, if the click is outside Menu then I false _openMenu
connectedCallback() {
super.connectedCallback();
this._boundClickHandler = this._clickHandler.bind(this);
window.addEventListener('click', this._boundClickHandler);
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener('click', this._boundClickHandler);
}
_clickHandler(event) {
let clickedInsideMenu = false;
event.path.forEach((node) => {
if (!clickedInsideMenu && node === this) {
clickedInsideMenu = true;
}
});
if (clickedInsideMenu) {
this._toggleMenu();
} else {
this._openMenu= false;
}
}
That's because on-blur and on-focusout are not defined yet in Polymer library. You can check the existing support gesture events here.
What you can do is to add events imperatively by selecting the menu then add an event to it.

Change model in renderer.listen function in Angular 5

I have custom drop-down in my application. I need to handle clicks outside the component for hiding drop-down list. I want to make it dynamically.
HostListener is not the case, because it adds event listeners for all dropdown components on the page. So i decided to add and remove listener dynamically with renderer.listener.
So i have function that fired when user is clicking input element:
onClickInput() {
if (this.isOpened) {
return this.isOpened = false;
}
this.clickOutsideHandler();
}
Where clickOutsideHandler is:
clickOutsideHandler() {
this.clickOutside = this.renderer.listen('document', 'click', (evt) => {
if (!this.el.nativeElement.contains(evt.target) && this.isOpened) {
this.isOpened = false;
this.cdRef.detectChanges();
this.clickOutside();
}
});
}
Is it the best solution to use this.cdRef.detectChanges(), because angular didn't update the view without it when i change this.isOpened = false; in renderer.listener. Is there better way to do this?

Angular2 remove click event binding after first click

In my application I have a button with a click even on it:
<button class="btn btn-default" (click)="doSomething()">
From within the doSomething method, is there any way to remove the (click) event from the button (so the user can't trigger the functionnality anymore?).
I tried to set a disabled prop on the button but it doesn't change Angular2 behavior.
I tryed to use (click)="doSomething($event) and then
doSomething($event) {
// My method logic goes here
...
...
console.log('Method Logic');
//Attempt to overwrite click event
let target = event.target || event.srcElement || event.currentTarget;
this.renderer.listen(target, 'click', (event) => {
console.log('clic block');
});
}
But It doesn't "replace" the click event. So after that, on click, both original logic and the "click block" console log are triggered!
Method 1:
You can set a boolean variable, so if the user calls the function, boolean value changes and the user will be able to call the function on click again but actually nothing will happen.
bool: boolean = true;
doSomething($event) {
if (this.bool) {
// My method logic goes here
...
...
console.log('Method Logic');
this.bool = false;
}
}
Method 2:
You can add a condition to your html component, if specified variable (in this case bool) is true, the function is going to be executed, but only once because the bool variable will be set to false and the click function will execute nothing (null) from now on.
bool: boolean = true;
doSomething($event) {
// My method logic goes here
...
...
console.log('Method Logic');
this.bool = false;
}
(click)="bool ? doSomething($event) : null"
The downside of just adding a guard variable for the execution is that the actual event listener is still in place and will trigger Angular's change detection when clicked, even though it doesn't do anything.
To actually remove the event listener, you have to add it via the component's Renderer. This will return a function that removes the event listener when called:
import {Component, AfterViewInit, Renderer, ViewChild, ElementRef} from '#angular/core';
#Component({
template: `<button #button>...</button>`
})
export class SampleComponent implements AfterViewInit {
#ViewChild('button') button: ElementRef;
private cancelClick: Function;
constructor(private renderer: Renderer) {}
ngAfterViewInit() {
this.cancelClick = this.renderer.listen(this.button.nativeElement, 'click',
($event: any) => this.handleClick($event));
}
handleClick($event: any) {
this.cancelClick();
// ...
}
}
If your goal is to just remove the event listener when the event is fired for the first time, this can be implemented as a plugin to Angular's event system. I added it as a part of my ng2-events utility library [source], which lets you now do the following:
<button (once.click)="handleClick($event)">...</button>
For people dealing with Observable / Subject for handling some events :
<button (click)="clickEvents$.next($event)">
class MyComponent {
clickEvents$ = new Subject<MouseEvent>();
firstClick$ = this.clickEvents.take(1); // Observable of first click
}

Categories

Resources