Stop propagation of a div inside a div - vuejs2

I have a card inside another clickable card. In my case, a carousel inside a card.
In a usual situation, I know I have to use #click.stop to prevent opening the parent card from opening when I click something clickable inside it.... but in my case, I'm having a carousel which do not have a click event, hence, I'm unable to use stop event on it. So what happens is when I click the next arrow of the carousel, the parent card pops up too.
Any idea how do I use stop event handling on something that do not have click event?
________________
| <-|---- Master Card
| ------------ |
| | <--|-|---- Carousel
| |__________| |
| |
| |
|______________|

tl;dr:
In Vue, if you want to stop the native click events, you have to use the native event modifier:
<carousel #click.native.stop />
or
<carousel #click.native.stop="yourMethod" />
Internally, the .stop modifier calls .stopPropagation() on the native click event, besides running yourMethod with the click event as param (when yourMethod is specified).
$emit()-ted click events (i.e: $emit('click', payload) don't need stopping, as they are not propagating by default.
complete answer: (regardless of Vue)
Any HTML element has an onclick event.
Therefore,
document.querySelector('.your-selector').onclick = function(event) {
event.stopPropagation()
}
will stop the click event's propagation (assuming document.querySelector('.your-selector') does select your carousel - note querySelector only returns the first element matching the selector).
If you want to do this on multiple elements matching the same selector, you'll need to use querySelectorAll and iterate through each element. Example:
[...document.querySelectorAll('.your-selector')].forEach(el => {
el.onclick = function(e) {
e.stopPropagation();
}
});
There are less verbose ways of doing it using frameworks, such as jQuery:
$('.your-selector').on('click', e => { e.stopPropagation(); })
... which does it on the entire collection returned by $('.your-selector'), out of the box.

Related

cannot locate 'iframe' using cypress

I am using cypress to test my site what I want to achieve is the following :
under this link: https://www.glassboxdigital.shop/product-page/classic
when I click on 'Add to Cart'
there is a side panel that pops out from the right side :
I want to click on 'View Cart' button my first go was the naive one - getting the element locator and click on it, as I saw it failed, I investigated a little bit and found out it is 'iframe' I tried using 'iframe' by pointing it out as following:
cy.get("iframe[frameborder='0']:nth-child(2)").then(function($elem){
var ifele = $elem.contents().find("a[id*='view-cart-button']")
cy.wrap(ifele).click()
but when I ran it the result was :
Expected to find element: undefined, but never found it
cy.get("iframe[frameborder='0']:nth-child(2)").then(function($elem){
16 | var ifele = $elem.contents().find("a[id*='view-cart-button']")
> 17 | cy.wrap(ifele).click()
| ^
18 | })
19 |
20 | }
It cannot locate the element because the side panel is generated into the html when the side bar is called upon, but Cypress is searching for the element on the page before the side bar is called.
Edit the code to execute whatever scripting is forming the side bar and then use the element location you tried previously.
Since cypress doesn't provide a native way to deal with iframes hence we will create a custom command, basically to traverse through an iframe. Go to cypress/support/command.js and write:
Cypress.Commands.add('getIframe', (iframe) => {
return cy.get(iframe)
.its('0.contentDocument.body')
.should('be.visible')
.then(cy.wrap);
})
Your Test should look like:
it('Go inside iframe and click', function() {
//Visit webpage
cy.visit("https://www.glassboxdigital.shop/product-page/classic")
//Wait till the Let's Chat header is visible
cy.get('#comp-jor13ajz > .yuKeh').should('be.visible')
//Click on the Add to Cart button
cy.get('[data-hook="add-to-cart"]').click()
//Go inside iframe and click View cart button
cy.getIframe('iframe[name*="tpapopup"]').contains('View Cart').click({
force: true
})
})
After Execution:

How to stop click propagation when clicking on a leaflet popup?

I have a popup in a leaflet map that can be closed by clicking on the 'x' in its upper right corner. How do I make the click event not propagate to the map itself?
I've tried using preventPropagate() in many places and forms, but none of them seem to work.
My latest code looks like that:
<div class="actions" #click="stopPropagation($event)">
(...)
stopPropagation(e) {
e.stopPropagation()
}
The above div (.actions) is the popup's main div.
I have also tried calling the function at a click in the popup's component tag in the parent component, but the result was the same, meaning clicking the 'x' closes the popup as expected but also results in a click event in the map that lies behind.
I use Vue and vue2-leaflet.
I appreciate any insight from you guys. Thanks!
UPDATE: actually, doesn't matter where in the popup the click happens, it always gets propagated to the map behind.
So, for reference, here's my solution:
<div class="actions" #click="someMethod($event)">
(...)
someMethod(e) {
(... some code)
return false
}
The command 'return false' is what solved my problem.
I tried using '#click.stop', but it gives me the '$event.stopPropagation() is not a function' error. The same happens if I run 'e.stopPropagation()' from inside the function.
The accepted answer didn't work for me so I wrapped my l-map in a div and applied the click.stop to that.
<div #click.stop.prevent.self="">
<l-map...>
</div>
It seems to me that the actual click event is parsed by the leaflet library rather than the Vue-compatible vue-2-leaflet, so the event that is received by the function doesn't have stopPropagation or preventDefault methods on the object. Thus, when Vue calls them with .stop or .prevent, the JS engine throws an error.
This is what I figured out for my issue dealing with event handling and stopping the propagation.
e.g.
someReference.on("click", (evt: L.LeafletEvent) => {
// You don't try to reference the event (evt) that is passed in
L.DomEvent.stopPropagation; // Just call this and it kills the propagation
// or you can call
// L.DomEvent.preventDefault(evt);
...
})
Could try an event modifier
Perhaps the stop modifier:
<div class="actions" #click.stop="closePopup">

How to click dijit.form.Button programmatically

I have form and input inside.
<input type="submit" label="Upload" data-dojo-type="dijit.form.Button" data-dojo-attach-point="leftLogoSubmit" id="leftLogoSubmit"/>
Is it possible push this button programmatically?
I tried
this.leftLogoSubmit.onclick();
but it not works.
Uncaught TypeError: this.leftLogoSubmit.onclick is not a function
You need to use on.emit().
It can be done in 2 ways:
As #tik27 stated:
dijit.registry.byId("leftLogoSubmit").emit('click', { cancelable:true, bubbles: true})
Note the 2 properties on the object. Without this, the click will not work properly.
You can also do:
on.emit(dojo.byId("leftLogoSubmit"), 'click', { cancelable:true, bubbles: true})
Where on is required as dojo/on
Last but not least, you can call the onClick method of the button directly (like #frank proposed):
dijit.registry.byId("leftLogoSubmit").onClick();
Difference is:
- in 1st case the widget is use to access the emit method (only works with Evented widgets)
- in 2nd case dojo/on is used so we need to pass the button domNode instead of the widget
- in 3rd it is not a native click (so will not bubble). It just call the button click handler
You can write like this
this.leftLogoSubmit.on("click", function() {
// Your code
});
you can fire the click function as.
this.leftLogoSubmit.onClick();
note: the capital C in the onClick.
You can go with core JavaScript solution
document.getElementById("leftLogoSubmit").click();

Cancel WinJS.UI.Animation.pointerDown if not clicked

I'm using WinJS.UI.Animation.pointerDown and WinJS.UI.Animation.pointerUp within a WinJS repeater's item template.
The problem is if a user holds their finger or the mouse button down on an item and moves off it, the pointerUp animation doesn't seem to fire or it fires but has no effect because the element that the up event is on is not the same as the one before. The best example of this is in the animation sample in example 6 (tap and click). Hold down the mouse button on a tile and move it off. It will stay in it's animated state and won't fire the pointerup event. Here's the code I'm using.
How can I cancel the pointerdown animation if the user moves off the element?
target1.addEventListener("pointerdown", function () {
WinJS.UI.Animation.pointerDown(this);
}, false);
target1.addEventListener("pointerup", function () {
WinJS.UI.Animation.pointerUp(this);
}, false);
target1.addEventListener("click", function () {
//do something spectacular
}, false);
I'm using the click event to commit the click action so that the right click remains clear for launching the navigation at the top of the app.
Have you tried adding an event listener for pointerout? That's the event that's dispatched when a pointing device (e.g. mouse cursor or finger) is moved out of the hit test boundaries of an element.
See the docs on pointer events here:
http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx

Setting input focus after tab is clicked

When a page has a search box with multiple tabs, one of the tabs is always selected; either the default tab is selected or the user has changed the tab. In either case the search input box of the selected tab should always have the keyboard focus so the user can just start typing their keywords.
Example: search box on http://www.lib.umd.edu/
Do you know how I could get the focus to be in the input box when a different tab is clicked? I got it to work on the first tab, but when I click another tab, the focus is lost.
The script I am using:
<script type="text/javascript" language="JavaScript">
document.forms[''].elements[''].focus();
</script>
$(document).ready(function () {
setTimeout(function () {
// focus on the txtenclude text area first visible and enabled input field or textarea
$(":input:visible:enabled").each(function () {
if ($(this).is('textarea')) {
$(this).focus();
return false;
}
});
}, 1000);
Your code snippet
To set the focus on a certain element you have to specify which element should receive the focus. In your snippet this specification is missing:
document.forms[''].elements[''].focus();
If you want to you can use this line: document.getElementById("DuringSearch").focus();
DuringSearch is the id of the input element that should receive the focus <input id="DuringSearch" type="text">
The problem that needs to be solved is to change the id based on the tab that was clicked.
There are several ways to achieve this. In a previous post is used an attribte named data-tab.
Example to wire up tabs and focus to input
To attach an event handler to a click on a tab you can do the follwing (using jQuery) on document.ready:
// add event handler for click on tab
$("#tabs li").click(function () {
loadTabs(this);
setFocusOnInput(this);
return false;
});
If you click on a tab the attached event fires and executes the 2 functions: loadTabs and setFocusOnInput.
To set the focus you need to know the id of that input-box. In my exmaple i am using an attribute data-tab
<li data-tab="Before">
Before
</li>
In my example i use the following function:
function setFocusOnInput(_this){
var tab = $(_this).attr("data-tab");
var searchId = tab + "Search"
console.log("_this:", _this);
document.getElementById(searchId).focus();
}
See more explanations on my previous post.
Could you elaborate what you want to know. Do you want to know how to wire it up in general or how to do it in a specific case?