how to open 1 modal window with 3 different buttons? - javascript

I face the problem of opening the same modal window with different buttons. Unfortunately, my knowledge is not enough to solve the problem correctly. I made several scripts for each button, it works like this, but it's not a solution, there should be one code, but how exactly to write it?
An example of the code for 1 button below, I will be grateful for help in supplementing the opening code for the other 2 buttons.
(() => {
const refs = {
openBuyModalBtn: document.querySelector("[data-buy-modal-open]"), <sup>open button</sup>
closeBuyModalBtn: document.querySelector("[data-buy-modal-close]"), <sup>close button</sup>
buyModal: document.querySelector("[data-buy-modal]"),
body: document.querySelector("body"),
};
refs.openBuyModalBtn.addEventListener("click", toggleModal);
refs.closeBuyModalBtn.addEventListener("click", toggleModal);
function toggleModal() {
refs.buyModal.classList.toggle("is-hidden"); (.is-hidden {opacity: 0; pointer-events: none; transform: scaleX(0);} )
refs.body.classList.toggle("no-scroll");
}
})();
<button class="buy-now__button" data-buy-modal-2-open type="button">Buy now
<svg width="32" height="32" class="buy-now__icon">
<use href="./images/svg/icons.svg#icon-ep-arrow"></use>
</svg>
</button>
<button class="header-nav__button" data-buy-modal-open type="button">Buy now
<svg width="32" height="32" class="header-nav__icon">
<use href="./images/svg/icons.svg#icon-ep-arrow"></use>
</svg>
</button>
<div class="buy-modal__container is-hidden" data-buy-modal>
<div class="buy-modal">
<button class="buy-modal__button buy-modal__button--close" type="button" data-buy-modal-close>
<svg width="20" height="20">
<use href="./images/svg/icons.svg#icon-close"></use>
</svg>
</button>
<h2 class="buy-modal__title">Buy now</h2>
<ul class="buy-modal__picture-list"></ul>
</div>
</div>

Related

Vue3 Move/drag image vertically

I have an image inside a wrapper div. I want to move the image vertically inside the div because the image does not fit.
I found a few libs that do this in react but not many resources for Vue
I want to achieve a functionality like in Google Maps, where you can drag the map around. The map view always stays inside the wrapping container and the move extends only until the image top/bottom is reached
<script setup>
...
onMounted(() => {
let bgDiv = document.getElementById("test");
bgDiv.addEventListener('mousemove', e => {
let y = e.offsetY;
bgDiv.style.cssText = `transform: translate3d(0, ${y}px, 0)`;
});
})
</script>
<div class="test" id="test">
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1920 1080"
preserveAspectRatio="xMinYMin meet"
class="svg-content">
<!-- overhead appears when viewbox > image, otherwise should be fine, so just make them match/fit -->
<image
width="1920"
height="1080"
xlink:href="#/assets/background.gif"></image>
<a class="cursor-pointer" data-bs-toggle="modal" data-bs-target="#">
<rect
x="618"
y="140"
fill="#fff"
opacity="0.5"
width="155"
height="940"/>
</a>
</svg>
</div>

Both click() and dispatchEvent does not trigger automatic click in reactjs

I have a react component that has an SVG image. I have divided the SVG into multiple react box. I have query selector which selects all the react box and JS click event to auto click that react.
I tried working with both click and dispatch event. But none of them works in my scenario.
Below is the section of the code I am working on.
componentDidMount() {
var element = document.querySelectorAll("square");
for(var i = 0; i<element.length; i++) {
element[i].dispatchEvent(new Event('click'));
}
}
render(){
return (
<React.Fragment>
<div className="col-12">
<svg viewBox="0 0 100 100">
<image xlinkHref={imageFile} height="100%" width="100%" />
<g><rect className="square" x="10" y="10" width="20" height="10" fillOpacity=".2" onClick={() =>console.log("clicked")}></rect> </g>
<g><rect className="square" x="30" y="10" width="20" height="10" fillOpacity=".4" onClick={() =>console.log("clicked")}></rect> </g>
</svg>
</div>
</React.Fragment>
)
}
I also tried using the click() function and did not work for SVG images and also is there a way we could automate a click in each square every 10 seconds?
You forgot a . in the query selector so the node list was actually empty.
If you want to automate a click in each square every 10 seconds, this code does the trick:
const elements = document.querySelectorAll(".square");
const intervalsIdentifiers = Array.from(elements).map(x => setInterval(() => x.dispatchEvent(new Event('click')), 10000));
The dispatchEvent method is indeed the only way, because the rect element doesn't have a click method (only HTML elements do, not SVG elements) as demonstrated below:
console.log('click' in SVGRectElement.prototype); // false
console.log(HTMLElement.prototype.hasOwnProperty('click')); // true
console.log(HTMLButtonElement.prototype instanceof HTMLElement); // true (a button has the click method)
console.log(SVGRectElement.prototype instanceof HTMLElement); // false
The full working code (native JavaScript but should work as well with React in the componentDidMount hook):
const elements = document.querySelectorAll(".square");
const intervalsIdentifiers = Array.from(elements).map(x => setInterval(() => x.dispatchEvent(new Event('click')), 10000));
<div className="col-12">
<svg viewBox="0 0 100 100">
<image xlink:Href="https://img-19.ccm2.net/8vUCl8TXZfwTt7zAOkBkuDRHiT8=/1240x/smart/b829396acc244fd484c5ddcdcb2b08f3/ccmcms-commentcamarche/20494859.jpg" height="100%" width="100%" />
<g><rect class="square" x="10" y="10" width="20" height="10" fillOpacity=".2" onclick="console.log('clicked')"></rect> </g>
<g><rect class="square" x="30" y="10" width="20" height="10" fillOpacity=".4" onclick="console.log('clicked')"></rect> </g>
</svg>
</div>

Not able to click on the svg element

<div class="MuiGrid-root jss45 MuiGrid-item MuiGrid-grid-xs-12 MuiGrid-grid-sm-3 MuiGrid-grid-md-3 MuiGrid-grid-lg-3 MuiGrid-grid-xl-3">
<h4 class="MuiTypography-root jss48 MuiTypography-h4">Decks</h4>
<button class="MuiButtonBase-root MuiFab-root jss47 MuiFab-sizeSmall MuiFab-primary" tabindex="0" type="button" aria-label="add" title="Add">
<span class="MuiFab-label"><svg class="MuiSvgIcon-root" focusable="false" viewBox="0 0 24 24" aria-hidden="true">
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z">
</path>
</svg>
</span>
<span class="MuiTouchRipple-root">
</span>
</button>
</div>
Java Scriprt:
describe('Login', function () {
it('Login', function () {
browser.waitForAngularEnabled(false);// since it is React JS application
browser.get('http............');// cannot access this. since it requires vpn
element(by.css('input[type="text"]')).sendKeys('Username');
element(by.css('input[type="password"]')).sendKeys('Password');
element(by.buttonText('Login')).click();
element(by.css('svg[class="MuiSvgIcon-root"]')).click();
});
});
In the above code, I wanted to click on the add button. I tried with all locators. But I am getting element not found error. Can anyone please help me in resolving this.

Vue.js event target is null?

I got a component with two styled buttons and one same event
"mouseEnter".
<template>
<div>
<a
class="button red"
href="/about"
#mouseover="mouseEnter">
<svg viewBox="0 0 180 60">
<path d="..."/>
</svg>
<span class="buttonSpan">About</span>
</a>
<a
class="button green"
href="/contact"
#mouseover="mouseEnter">
<svg viewBox="0 0 180 60">
<path d="..."/>
</svg>
<span class="buttonSpan">Contact</span>
</a>
</div
</template>
When the event triggers I want to do something with the path and the span of the button that is hovered.
I'm trying to reference them with event.target but for the span I get null, and for the path everything is working good.
methods: {
buttonEnter(event) {
const buttonPath = event.target.querySelector('path')
const buttonSpan = event.target.querySelector('span')
...
}
How should i reference the span ? Is there any other way I can do it ?
the event target will bubble up starting from the children of the node that you attached your listener to. Use event.currentTarget

target id in inline SVG with jQuery

I would like to target an <a> tag's ID inside an inline SVG that is being used as a responsive image map. I don't need to manipulate the SVG, just launch a modal with fancybox by that ID if someone clicks on that <a href...>. (launch an iframe of a local page in this case)
I have read a dozen threads related to this and understand there is a namespace issue but I'm a JS noob and cant quite put it together - thank you for taking a look!
I did try the $('a[xlink\:href=#shows]’) but no joy.
<div id="inline-svg">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1280" preserveAspectRatio="xMidYMin slice" width="100%" height="100%">
<a xlink:href="http://www.facebook.com/" xlink:title="Facebook" xlink:show="new" id="facebook">
<rect x="1102" y="392” width="102" height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="http://twitter.com/" xlink:title="Twitter" xlink:show="new" id="twitter">
<rect x="1102" y="520" width="102" height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="#" xlink:title="Mailing List" id=“mlist">
<rect x="1215" y="392" width=“102” height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="shows.html" xlink:title=“Shows” id="shows" >
<rect x="1215" y="520” width=“102” height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<rect width="1920" height="1280" style="fill:none"/>
</svg>
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#shows”).fancybox({
maxWidth : 400,
maxHeight : 300,
type : 'iframe',
});
});
</script>
changing:
$("#shows”).
to:
$("#shows").
Should work fine.

Categories

Resources