Angular 2 prevent router navigation on child component click - javascript

I have a template
<div (click)="handler()">
<input type='checkbox' (click)="$event.stopPropagation()" (change)="$event.stopPropagation()">
</div>
and in my component here is the handler
handler() {
this.router.navigate('path');
}
I wanted do nothing on checkbox click but to route on div click.
The above solution is not working.

First argument of navigate function has to be an array
this.router.navigate(['path']);
OR
you can use navigateByUrl,
this.router.navigateByUrl('path');
Since you are using $event.stopPropagation() when you click on the checkbox, navigation won't happen but when you simply click on the div, you will be navigated to expected route.

This setup works for me:
<div (click)="onDivClick()">
<mat-checkbox (click)="$event.stopPropagation()" (change)="onCheckboxChange($event)"></mat-checkbox>
</div>
...
onDivClick() {
console.log('div clicked');
}
onCheckboxChange(event) {
console.log(event);
}
Important to note:
MatCheckboxChange event type does not have a stopPropagation() function so your example code should actually display an error in the console.
So you want the stopPropagation() only on the checkbox click.

I figured out I have a label that wraps the checkbox. So, I needed to add the click event to stop propagation at the label element

Related

angular material checkbox: prevent ripple when link in label is checked

I have an Angular (10) Material checkbox with a link in the label that has a click handler to open a dialog with reference info:
<mat-checkbox formControlName="certification">
By checking this box, I certify that all shipment information provided is correct and I agree to adhere to the
<span class="fake-link" (click)="openUspsPrivacyAgreement($event)"> USPS Privacy Act Statement </span> and all
other country-specific requirements.
</mat-checkbox>
My click handler is
openUspsPrivacyAgreement(event: MouseEvent) {
this.dialogService.open(DialogUspsPrivacyAgreementComponent);
event.preventDefault();
event.stopPropagation();
}
It works in that the dialog opens and the checkbox is not selected, which is what I want.
However, the ripple fires on the checkbox anyway. Is there a way to prevent the ripple when I click on my text but have it work when the checkbox is clicked?
I thought what I did was enough, as it does prevent the click from getting to the checkbox and checking it.
It looks like mat-checkbox ignores internal element stopPropagation. So, you could create an workaround where you add dynamic variable isRippleDisabled as boolean flag to your checkbox
<mat-checkbox formControlName="certification" [disableRipple]="isRippleDisabled">
and switch it off (true) when modal open, and back to normal, when modal close (false).
openUspsPrivacyAgreement(event: MouseEvent) {
this.isRippleDisabled = true; // set to false when dialog close
this.dialogService.open(DialogUspsPrivacyAgreementComponent);
event.preventDefault();
event.stopPropagation();
return false;
}
Add
<mat-checkbox>Checked 1</mat-checkbox>
to the app.component in the source code and it still has 'hover' effect, it could be disabled it through CSS.
The fix would be:
.mat-ripple { display: none; }
or .mat-checkbox-ripple only for checkbox

Is there a way to add a function on close of ng-multiselect-dropdown?

I am using the ng-multiselect-dropdown package in angular 5 for creating a multi-select dropdown.
I want to do call a function on close or hide of the drop-down component.
like this
closeDropdown : function(){
console.log("dropdown close triggered");
}
According to the documentation you can pass closeDropDownOnSelection value true to close the dropdown whenever the selection is done
ng-multiselect dropdown
Incase of multiple selection you can call (onSelect)="onItemSelect($event)"
for more information check this Demo documentation
You can call the function within (change) event.
ex :
<ng-multiselect-dropdown
(blur)="closeDropdown($event)"
>
</ng-multiselect-dropdown>
To solve the bug identified by satira ( I couldn't comment due to low reputation), ie.
"When the component which has this multi-dropdown opens for the first time or you reload the page and click anywhere outside the dropdown, onDropDownClose() gets called." For me, it didn't happen after the first time. Anyway, i solved it by getting the id of any element on the screen(header, footer or any div) and used docuement.getElementById('element_id').click() on ngAfterViewInit.
ngAfterViewInit() { document.getElementById('header').click(); }
This made sure that no sideeffects take place on my app. I know this is a messy solution but since closeDropdown() of ng-multidropdown doesn't work, this was my only way out.
I had this issue recently and found a solution that works for me using a combination of (ngModelChange) and (click). When using ng-multiselect-dropdown the other normal HTML Element triggers like (blur) and (change) don't work, but the (ngModelChange) does work. Only problem with that is it triggers when being initialized. But I added a boolean variable to the (click) trigger that does seem to work.
Note that this also works to cover the onSelect, onDeSelect, etc
component.ts:
...
dropDownSelect: boolean = false;
dropDownSelection: number;
...
saveFunction(event) {
if(!this.dropDownSelect) return;
...
this.dropDownSelect = false;
}
component.html:
...
<ng-multiselect-dropdown [data]="dataSource" [(ngModel)]="dropDownSelection" [settings]="dropDownSettings" (click)="dropDownSelect = true" (ngModelChange)="saveFunction($event)"></ng-multiselect-dropdown>
...
I tried #misterz's solution but it didn't work. However I modified it and it works perfectly.
The trick:
In addition to (onDropDownClose), listen to a click event;
// this act as a differentiator between other calls(bug) and an intended call
(click)="dropDownSelect = true".
In your component, declare your variable and use it like this:
dropDownSelect = false;
saveFunction($event) {
if (this.dropDownSelect) {
// close the opening to subsequent actions
this.dropDownSelect = false;
// Perform action;
};
}

Click event is calling multiple times within function

I've created code for firing some click events. These events are just like nested with using functions. When I click the button the click event called multiple times.
For Ex. I've one button(b1) which opens a sidebar(already hidden). I've another button(b2) which is in the sidebar. When I open sidebar and click on b2 first time, then it's working fine that is it's calling one time. But when I close sidebar and open again the sidebar by using b1 and click on b2, click event triggered twice. Similarly, it triggers multiple times according to sidebar open using b1. Each time the triggers are increasing on click of b1
Below is my code:
<button class="b1">Show Sidebar</button>
<button class="b3">Hide Sidebar</button>
<div class="sidebar">
<input type="text" class="demo">
<button class="b2">Triggers</button>
</div>
<script>
function getSidebarEvents() {
$('.b2').click(function(){
console.log('Triggering Multiple times');
});
}
$('.b1').click(function() {
//Do something to open sidebar
getSidebarEvents();
});
$('.b3').click(function() {
//Do something to close sidebar
});
</script>
I know my function is calling multiple times on every click of b1 and click b2's event is initializing multiple time. But I can't change this structure with big changes because my code is so big now. I need something small change(s) that will help me to fix this.
You should assign the click event handler outside the function like so. Now if you want to simulate a click from inside that function, just call the click event.
function getSidebarEvents() {
$('.b2').click();
}
$('.b1').click(function() {
//Do something to open sidebar
getSidebarEvents();
});
$('.b2').click(function(){
console.log('Triggering Multiple times');
});
$('.b3').click(function() {
//Do something to close sidebar
});

Cannot bind after unbinding

I am attempting to bind a click event after previously unbinding it and I cannot get it to work.
Here is my HTML:
<div class="input-group date">
<input type="text" class="form-control" id="dp1" style="width: 100px; vertical-align: middle" />
<span class="input-group-addon" id="dp1Icon" style="outline-style:none"><img src="<%=context%>/images/calendar-glyph.png"></span>
</div>
The input is actually a bootstrap datepicker component. The span contains a bootstrap glyph that triggers the datepicker to open. I have a radio button group that toggles disabling these like this:
$(".date-wrap input[type='radio']").on("click", function(e){
if ($(e.target).val() == "permanent"){
$("#dp1, #dp1Icon").prop("disabled", true);
$("#dp1Icon").unbind("click"); // Disabled attribute only works on form controls, not spans. So we have to unbind the event
$("#dp1").removeAttr("readonly", "readonly");
}else{
$("#dp1, #dp1Icon, #e3").prop("disabled", false);
$("#dp1Icon").bind("click");
$("#dp1").removeAttr("readonly");
}
});
So, if the value of the radio button they click is "permanent", everything becomes disabled; that works great. Otherwise, I attempt to turn them back on.
The only thing I can think of is that when I try to bind the click event to the glyphicon again, I must define the actual handler that opens the datepicker; like this:
$("#dp1Icon").bind("click", $("#dp1").datepicker('show'));
But all that does is open the datepicker as soon as I click the other radio button. I want it to open only when they click it.
What important piece am I missing here? Does anyone have an idea?
Thanks for any tips.
bind("click") does not magically re-add the event. You need to add it back the event.
$("#dp1Icon").on("click", function(){ $("#dp1").datepicker('show'); } );
You might be better off just setting a flag inside that function and not removing the event.

Disable div with click event

I want to disable my div with image and click event that event does not call. I try do it with KO:
<div title="Delete Series" class="deleteSeriesButton" data-bind="css: { disabled: true}" ></div>
but this does not work with div.
Can I do it without unbind click event?
If you are using KnockoutJS, then you have a view model.
And if you have a view model, you should be able to add an observable property that tells you whether the "delete series" button is enabled or disabled.
self.isDeleteEnabled = ko.computed(function() {
// your code that tells whether the button is enabled or not
});
And let's say you in your view model the click action, like this:
self.clickAction = function() {
// do what you want to do
}
Thne, you can make your "click" binding dependent on this observable, like this:
<div class="button" data-bind="click: isDeleteEnabled() ? clickAction : null">
If the isDeleteEnabled observable returns true, then the button is clickable, otherwise it's not.
I made a fiddle so you can see how it's done in a real example.
you can block the div using the jQuery blockUI plugin.
link to blockUI

Categories