Close popover in JS when another is opened with popper.js - javascript

I have some basic HTML and load popper.js.
I have about 3 popovers but they don't close when I click open another one.
I use tailwind as css and vanilla JS. I don't want to use jQuery to get this to work. It also shows some error about the event being deprecated but not sure how to fix it.
Please help!
Here is my pen: https://codepen.io/RobineSavert/pen/xxLMqpX
Here is my code:
function openPopover(event, tooltipID, position) {
let element = event.target;
while (element.nodeName !== "BUTTON") {
element = element.parentNode;
}
var popper = Popper.createPopper(
element,
document.getElementById(tooltipID), {
placement: position,
}
);
document.getElementById(tooltipID).classList.toggle("hidden");
}
<link href="https://unpkg.com/tailwindcss#^2/dist/tailwind.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/#popperjs/core#2.10.2/dist/umd/popper.min.js"></script>
<section class="bg-gradient-to-b from-night to-babyblue w-full h-95vh justify-center">
<div class="flex flex-1 pr-2 pt-2">
<button onclick="openPopover(event,'popover-cv-bottom', 'bottom')" class="mr-4 bg-red-400 flex h-12 justify-center p-3 rounded-full text-center text-white w-12" type="button">
click
</button>
<button onclick="openPopover(event,'popover-email-bottom', 'bottom')" type="button" class="mr-4 bg-red-400 flex h-12 justify-center p-3 rounded-full text-center text-white w-12">
click
</button>
<button onclick="openPopover(event,'popover-save-bottom', 'bottom')" type="button" class="mr-4 bg-red-400 flex h-12 justify-center p-3 rounded-full text-center text-white w-12">
click </button>
<div class="hidden bg-white border mr-3 block z-50 font-normal leading-normal text-sm max-w-xs text-left no-underline break-words rounded-lg" id="popover-cv-bottom">
<div>
<div
class="text-gray-700 opacity-75 font-semibold p-3
mb-0
border-b border-solid border-gray-100
uppercase
rounded-t-lg
"
>
Popover 1 - title
</div>
<div class="text-gray-700 p-3">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Saepe,
non.
</div>
</div>
</div>
<div class="hidden bg-white border mr-3 block z-50 font-normal leading-normal text-sm max-w-xs text-left no-underline break-words rounded-lg" id="popover-email-bottom">
<div>
<div
class="
text-gray-700
opacity-75
font-semibold
p-3
mb-0
border-b border-solid border-gray-100
uppercase
rounded-t-lg
"
>
Popover 2 - title
</div>
<div class="text-gray-700 p-3">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Saepe,
non.
</div>
</div>
</div>
<div class="hidden bg-white border mr-3 block z-50 font-normal leading-normal text-sm max-w-xs text-left no-underline break-words rounded-lg" id="popover-save-bottom">
<div>
<div
class="
text-gray-700
opacity-75
font-semibold
p-3
mb-0
border-b border-solid border-gray-100
uppercase
rounded-t-lg
"
>
Popover 3 - title
</div>
<div class="text-gray-700 p-3">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Saepe,
non.
</div>
</div>
</div>
</div>
</section>

You can try this:
allPoppers = [];
function openPopover(event, tooltipID, position)
{
var el = document.getElementById(tooltipID);
var state = el.style.visibility;
// Close all popovers
hideElements(allPoppers);
let element = event.target;
while (element.nodeName !== "BUTTON") {
element = element.parentNode;
}
Popper.createPopper(
element,
el, {
placement: position,
}
);
allPoppers.push(tooltipID);
toggle(el, state);
}
function toggle(el, state)
{
if (state == "hidden") {
el.style.visibility = "visible";
} else if (state == "visible") {
el.style.visibility = "hidden";
} else {
el.style.visibility = "visible";
}
}
function hideElements(elements)
{
var length = elements.length;
if (length > 0) {
for (var i = 0; i < length; i++) {
document.getElementById(elements[i]).style.visibility = "hidden";
}
}
}
.popover {
visibility: hidden;
}
<link href="https://unpkg.com/tailwindcss#^2/dist/tailwind.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/#popperjs/core#2.10.2/dist/umd/popper.min.js"></script>
<section class="bg-gradient-to-b from-night to-babyblue w-full h-95vh justify-center">
<div class="flex flex-1 pr-2 pt-2">
<button onclick="openPopover(event,'popover-cv-bottom', 'bottom')" class="mr-4 bg-red-400 flex h-12 justify-center p-3 rounded-full text-center text-white w-12" type="button">
click
</button>
<button onclick="openPopover(event,'popover-email-bottom', 'bottom')" type="button" class="mr-4 bg-red-400 flex h-12 justify-center p-3 rounded-full text-center text-white w-12">
click
</button>
<button onclick="openPopover(event,'popover-save-bottom', 'bottom')" type="button" class="mr-4 bg-red-400 flex h-12 justify-center p-3 rounded-full text-center text-white w-12">
click </button>
<div class="bg-white border mr-3 block z-50 font-normal leading-normal text-sm max-w-xs text-left no-underline break-words rounded-lg popover" id="popover-cv-bottom">
<div>
<div
class="text-gray-700 opacity-75 font-semibold p-3
mb-0
border-b border-solid border-gray-100
uppercase
rounded-t-lg
"
>
Popover A
</div>
<div class="text-gray-700 p-3">
A
</div>
</div>
</div>
<div class="bg-white border mr-3 block z-50 font-normal leading-normal text-sm max-w-xs text-left no-underline break-words rounded-lg popover" id="popover-email-bottom">
<div>
<div
class="
text-gray-700
opacity-75
font-semibold
p-3
mb-0
border-b border-solid border-gray-100
uppercase
rounded-t-lg
"
>
Popover B
</div>
<div class="text-gray-700 p-3">
B
</div>
</div>
</div>
<div class="bg-white border mr-3 block z-50 font-normal leading-normal text-sm max-w-xs text-left no-underline break-words rounded-lg popover" id="popover-save-bottom">
<div>
<div
class="
text-gray-700
opacity-75
font-semibold
p-3
mb-0
border-b border-solid border-gray-100
uppercase
rounded-t-lg
"
>
Popover C
</div>
<div class="text-gray-700 p-3">
C
</div>
</div>
</div>
</div>
</section>

Related

JQuery duplicate HTML div and edit its content before appending to html body

I have a that contains some input fields like so:
<div class="px-4 py-6 mb-4 border rounded-lg border-gray-400" id="datarow"
<div class="flex flex-row space-x-4 pb-5">
<div class="relative z-0 w-full mb-5">
<input type="text" id="f_name" name="f_name" placeholder="Enter Name here"
required class="pt-3 pb-2 block w-full px-4 mt-0 rounded bg-white border-0 border-b appearance-none" />
<label for="f_name" class="absolute duration-300 pl-2 text-lg top-3 z-1 origin-0 text-gray-500">Name</label>
</div>
<div class="flex z-0 w-full justify-end">
<input type="text" id="f_dest" name="f_dest" placeholder="Enter Destination here"
required class="pt-3 pb-2 block w-full px-4 mt-0 rounded bg-white border-0 border-b appearance-none" />
<label for="f_dest" class="absolute duration-300 pl-2 text-lg top-3 z-1 origin-0 text-gray-500">Destination</label>
</div>
</div>
And in jQuery I am duplicating the above div (on button click) and just appending to the main html body which would be displayed just below the original #datarow div. Heres the full snippet as how I have in my program.
$("#btn_addsector").click(function () {
var div = document.getElementById("datarow"),
clone = div.cloneNode(true);
//neither of the lines work
$(clone).find("#f_name").text = "Tisha";
$("#maincontent").append(clone);
$(clone).find("#f_name").text = "Tisha";
$(clone).find("#f_name").text("Tisha");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="maincontent" >
<button id="btn_addsector"
class="bg-transparent hover:bg-secondary-dark text-secondary-dark font-semibold hover:text-white py-2 px-4 border border-secondary-dark hover:border-transparent rounded">
Add Sector
</button>
<div class="px-4 py-6 mb-4 border rounded-lg border-gray-400" id="datarow">
<div class="flex flex-row space-x-4 pb-5">
<div class="relative z-0 w-full mb-5">
<input type="text" id="f_name" name="f_name" placeholder="Enter Name here" value="Hannah"
required class="pt-3 pb-2 block w-full px-4 mt-0 rounded bg-white border-0 border-b appearance-none" />
<label for="f_name" class="absolute duration-300 pl-2 text-lg top-3 z-1 origin-0 text-gray-500">Name</label>
</div>
<div class="flex z-0 w-full justify-end">
<input type="text" id="f_dest" name="f_dest" placeholder="Enter Destination here" value="Smallville"
required class="pt-3 pb-2 block w-full px-4 mt-0 rounded bg-white border-0 border-b appearance-none" />
<label for="f_dest" class="absolute duration-300 pl-2 text-lg top-3 z-1 origin-0 text-gray-500">Destination</label>
</div>
</div>
</div>
</div>
I can get the cloned div to appended properly but it does not alter the text of the input field.
There is multiple problem with your code:
1: You can't have multiple elements with the same ID, use class for this. So I've removed the id="f_name" and added it to the class selector class="the previous classes f_name"
2: To set the value of an input, you have to use .val() and not .text()
$(clone).find(".f_name").val("Tisha");
Demo
$("#btn_addsector").click(function() {
var div = document.getElementById("datarow"),
clone = div.cloneNode(true);
//neither of the lines work
$(clone).find(".f_name").val("Tisha");
$("#maincontent").append(clone);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="maincontent">
<button id="btn_addsector" class="bg-transparent hover:bg-secondary-dark text-secondary-dark font-semibold hover:text-white py-2 px-4 border border-secondary-dark hover:border-transparent rounded">
Add Sector
</button>
<div class="px-4 py-6 mb-4 border rounded-lg border-gray-400" id="datarow">
<div class="flex flex-row space-x-4 pb-5">
<div class="relative z-0 w-full mb-5">
<input type="text" name="f_name" placeholder="Enter Name here" value="Hannah" required class="pt-3 pb-2 block w-full px-4 mt-0 rounded bg-white border-0 border-b appearance-none f_name" />
<label for="f_name" class="absolute duration-300 pl-2 text-lg top-3 z-1 origin-0 text-gray-500">Name</label>
</div>
<div class="flex z-0 w-full justify-end">
<input type="text" name="f_dest" placeholder="Enter Destination here" value="Smallville" required class="pt-3 pb-2 block w-full px-4 mt-0 rounded bg-white border-0 border-b appearance-none f_dest" />
<label for="f_dest" class="absolute duration-300 pl-2 text-lg top-3 z-1 origin-0 text-gray-500">Destination</label>
</div>
</div>
</div>
</div>

JS: how to make sure only one html element is visible

i have two lists, currently Both lists are toggling at once,
i want only one lists items should be visible at one time,
if i click on list one only list one items should be visible and vice versa.
CODE
currently both lists items are showing on click.
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", function() {
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
});
}
<div class=" dropdown-btn font-bold text-lg text-gray-700 ml-4 mt-3 cursor-pointer">LIST ONE</div>
<div class="hidden">
<div class="cursor-pointer w-full border-gray-100 items-start border-b-2 " style="height:40px">
<div class=" text-base text-gray-700 ml-10 mt-7 ">option 1</a>
</div>
</div>
<div class="w-full border-gray-100 items-start border-b-2" style="height:40px">
<div class=" text-base text-gray-700 ml-10 mt-3"> option 2</a>
</div>
</div>
</div>
<div class="w-full border-gray-100 items-start border-b-2">
<div class="dropdown-btn font-bold text-lg text-gray-700 ml-4 mt-8 cursor-pointer" style="height:40px">LIST TWO
</div>
<div class="hidden">
<div class="w-full border-gray-100 items-start border-b-2" style="height:40px">
<div class=" text-base text-gray-700 ml-10 mt-1"><a href=>option 1</a></div>
</div>
<div class="w-full border-gray-100 items-start border-b-2" style="height:40px">
<div class=" text-base text-gray-700 ml-10 mt-3"><a href=>option 2</a></div>
</div>
</div>
</div>
</div>
You can delegate and toggle the hidden you already have
Note I added a class to the hidden div
const lists = document.querySelectorAll(".list")
const buttons = document.querySelectorAll(".dropdown-btn")
document.getElementById("container").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("dropdown-btn")) {
tgt.classList.toggle("active");
const thisList = tgt.nextElementSibling;
const show = tgt.classList.contains('active')
lists.forEach(list => list.classList.toggle("hidden", !show || list !=thisList))
buttons.forEach(btn => btn.classList.toggle("active",btn === tgt && show))
}
});
.hidden {
display: none;
}
.active {
color: red;
}
<div id="container">
<div class=" dropdown-btn font-bold text-lg text-gray-700 ml-4 mt-3 cursor-pointer">LIST ONE</div>
<div class="hidden list">
<div class="cursor-pointer w-full border-gray-100 items-start border-b-2 " style="height:40px">
<div class=" text-base text-gray-700 ml-10 mt-7 ">option 1
</div>
</div>
<div class="w-full border-gray-100 items-start border-b-2" style="height:40px">
<div class="text-base text-gray-700 ml-10 mt-3">option 2
</div>
</div>
</div>
<div class="w-full border-gray-100 items-start border-b-2">
<div class="dropdown-btn font-bold text-lg text-gray-700 ml-4 mt-8 cursor-pointer" style="height:40px">LIST TWO
</div>
<div class="hidden list">
<div class="w-full border-gray-100 items-start border-b-2" style="height:40px">
<div class=" text-base text-gray-700 ml-10 mt-1">option 1</div>
</div>
<div class="w-full border-gray-100 items-start border-b-2" style="height:40px">
<div class=" text-base text-gray-700 ml-10 mt-3">option 2</div>
</div>
</div>
</div>
</div>

Need to pass a input value to another DIV in AlpineJS

I need to pass the input values to a modal, but i can't do it with x-ref. Is this the right way to do it?
<div x-data="orderSearch()" class="container mt-2 mx-auto" x-ref="root">
<div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 mt-2 mb-3">
<div class="card m-1 p-1 cursor-pointer border border-gray-400 rounded-lg hover:shadow-md hover:border-opacity-0 transform hover:-translate-y-1 transition-all duration-200 bg-green-200">
<div class="flex flex-row w-full py-2 px-2 m-1 text-sm text-green-800" x-data="{ qty: '', val: '', total: ''}" x-effect="total = qty * val">
Definir estratégia de COMPRA:
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="valorcompra" type="text" placeholder="Valor" autofocus x-model.number="qty" x-ref="valorcompra" #keydown.enter="fetchOrder('buy',$refs.quantidadecompra.value,$refs.valorcompra.value)">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="quantidadecompra" type="text" placeholder="Quantidade" x-model.number="val" x-ref="quantidadecompra" #keydown.enter="fetchOrder('buy',$refs.quantidadecompra.value,$refs.valorcompra.value)">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="totalcompra" type="text" placeholder="Total" x-model.number="total" x-ref="totalcompra" #keydown.enter="fetchOrder('buy',$refs.quantidadevenda.value,$refs.valorcompra.value)" x-bind:disabled="true">
</div>
</div>
<div class="card m-1 p-1 cursor-pointer border border-gray-400 rounded-lg hover:shadow-md hover:border-opacity-0 transform hover:-translate-y-1 transition-all duration-200 bg-red-200">
<div class="flex flex-row w-full py-2 px-2 m-1 text-sm text-red-800" x-data="{ qty: '', val: '', total: ''}" x-effect="total = qty * val">
Definir estratégia de VENDA:
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="valorvenda" type="text" placeholder="Valor" autofocus x-model.number="qty" x-ref="valorvenda" #keydown.enter="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="quantidadevenda" type="text" placeholder="Quantidade" x-model.number="val" x-ref="quantidadevenda" #keydown.enter="modal=true">
<input class="field shadow appearance-none border rounded w-1/3 py-2 px-2 my-1 mx-1 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="totalvenda" type="text" placeholder="Total" x-model.number="total" x-ref="totalvenda" #keydown.enter="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)" x-bind:disabled="true">
</div>
</div>
</div>
<!-- Dialog (full screen) -->
<div class="absolute top-0 left-0 flex items-center justify-center w-full h-full" style="background-color: rgba(0,0,0,.5);" x-show="modal">
<!-- A basic modal dialog with title, body and one button to close -->
<div class="h-auto p-4 mx-2 text-left bg-white rounded shadow-xl md:max-w-xl md:p-6 lg:p-8 md:mx-0">
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg font-medium leading-6 text-gray-900">
Confirmação!
</h3>
<div class="mt-2">
<p class="text-sm leading-5 text-gray-500" x-text="'Deseja cadastrar a ordem de venda?'">
</p>
</div>
</div>
<!-- One big close button. --->
<div class="mt-4 flex justify-between">
<div class="cancela px-4 bg-red-400 p-3 rounded-lg text-white hover:bg-red-600" #click="modal=false">Cancelar</div>
<div class="ok px-4 bg-green-400 p-3 rounded-lg text-white hover:bg-green-600" #click="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)">Confirmar</div>
</div>
</div>
</div>
<!-- fim modal div -->
</div>
Must be read input values here:
<div class="ok px-4 bg-green-400 p-3 rounded-lg text-white hover:bg-green-600" #click="fetchOrder('sell',$refs.quantidadevenda.value,$refs.valorvenda.value)">Confirmar</div>
I tried to find this answer for two days but i cant.
Can you help me?
i tried a $store solution and it1s done:
<script>
const element = document.querySelector("#valorvenda")
element.addEventListener('change', (event) => {
const quantidadevenda = document.querySelector("#quantidadevenda").value
Alpine.store('venda', {
valorcompra: document.querySelector("#valorcompra").value,
quantidadecompra:quantidadevenda,
valorvenda: event.target.value,
quantidadevenda: quantidadevenda,
})
console.log(Alpine.store('fields').valorvenda);
})
</script>
It's like a state management and works fine!
Thanks all.

Adding comments to video with jQuery

I want to comment dynamically on a video with jQuery, but when I comment on what I'm doing, the old comment changes and all comments receive the same text. The value I get from the input is written to all comments. How can I fix this?
$(document).ready(function() {
$("#addCommentBtn").click(function() {
var comment = $("#commentText").val();
if (comment === "") {
$("#error-msg").fadeIn();
setTimeout(function() {
$("#error-msg").fadeOut();
}, 3000);
} else {
$('<li class="w-full comment mt-4"><div class="w-full md:w-1/2 comment flex flex-col"><div class="flex gap-4 items-center text-lg font-bold"><img src="assets/media/svg/NoPath - Kopya (75).png" class="rounded-full" alt=""><h1>André Potchinka</h1></div><div class="ml-16 flex flex-col justify-center"><div class=" mt-2 flex gap-1 items-center"><h1 class="comment-content text-gray-500 font-bold"></h1><span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-up" aria-hidden="true"></i>0</span><span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-down" aria-hidden="true"></i>0</span></div><div class="w-full flex flex-col"><input type="text" class="responseText border-b focus:outline-none bg-transparent mt-4" placeholder="Please login to leave a comment..."><ul class="responses p-4 flex flex-col gap-2"> </ul><button class="responseBtn text-right mt-2 text-gray-500">Answer</button></div></div></div></li>').appendTo(".comments");
$(".comment-content").text(comment);
$("#commentText").val("");
$("#valid-msg").fadeIn();
setTimeout(function() {
$("#valid-msg").fadeOut();
}, 3000);
}
});
});
<link href="https://unpkg.com/tailwindcss#^2/dist/tailwind.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="comments" class="hidden p-4">
<div class="container mx-auto">
<div class="w-full flex gap-4">
<img src="assets/media/svg/Group 199.png" alt="">
<input type="text" required id="commentText" class="pt-4 flex-1 focus:outline-none border-b border-gray-500 py-1 px-2 bg-transparent" placeholder="Please login to leave a comment...">
</div>
<div class="w-full flex gap-4 justify-end items-center mt-4">
Cancel
<button id="addCommentBtn" class="focus:outline-none bg-black px-6 border border-black py-1 rounded-full text-gray-500 flex items-center pt-3">Comment</button>
</div>
<ul class="w-full comments">
<li class="w-full comment mt-4">
<div class="w-full md:w-1/2 comment flex flex-col">
<div class="flex gap-4 items-center text-lg font-bold">
<img src="assets/media/svg/NoPath - Kopya (75).png" class="rounded-full" alt="">
<h1>André Potchinka</h1>
</div>
<div class="ml-16 flex flex-col justify-center">
<div class=" mt-2 flex gap-1 items-center">
<h1 class="text-gray-500 font-bold">Nice work, congragulations.</h1>
<span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-up"></i>0</span>
<span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-down"></i>0</span>
</div>
<div class="w-full flex flex-col">
<input type="text" class="responseText border-b focus:outline-none bg-transparent mt-4" placeholder="Please login to leave a comment...">
<ul class="responses p-4 flex flex-col gap-2 text-gray-500">
<li>Yoruma yanıt verildi :)</li>
</ul>
<div class="flex justify-end">
<button class="responseBtn mt-2 text-gray-500 w-24 text-center">Answer</button>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
With the selector .comment-content, you are selecting all the elements with that class, so of course all comments' text content will be overwritten. Save your new element into a variable and restrict the class selector on that new element instead:
$(document).ready(function() {
$("#addCommentBtn").click(function() {
var comment = $("#commentText").val();
if (comment === "") {
$("#error-msg").fadeIn();
setTimeout(function() {
$("#error-msg").fadeOut();
}, 3000);
} else {
let newComment = $('<li class="w-full comment mt-4"><div class="w-full md:w-1/2 comment flex flex-col"><div class="flex gap-4 items-center text-lg font-bold"><img src="assets/media/svg/NoPath - Kopya (75).png" class="rounded-full" alt=""><h1>André Potchinka</h1></div><div class="ml-16 flex flex-col justify-center"><div class=" mt-2 flex gap-1 items-center"><h1 class="comment-content text-gray-500 font-bold"></h1><span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-up" aria-hidden="true"></i>0</span><span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-down" aria-hidden="true"></i>0</span></div><div class="w-full flex flex-col"><input type="text" class="responseText border-b focus:outline-none bg-transparent mt-4" placeholder="Please login to leave a comment..."><ul class="responses p-4 flex flex-col gap-2"> </ul><button class="responseBtn text-right mt-2 text-gray-500">Answer</button></div></div></div></li>').appendTo(".comments");
$(".comment-content", newComment).text(comment);
$("#commentText").val("");
$("#valid-msg").fadeIn();
setTimeout(function() {
$("#valid-msg").fadeOut();
}, 3000);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="comments" class="hidden p-4">
<div class="container mx-auto">
<div class="w-full flex gap-4">
<img src="assets/media/svg/Group 199.png" alt="">
<input type="text" required id="commentText" class="pt-4 flex-1 focus:outline-none border-b border-gray-500 py-1 px-2 bg-transparent" placeholder="Please login to leave a comment...">
</div>
<div class="w-full flex gap-4 justify-end items-center mt-4">
Cancel
<button id="addCommentBtn" class="focus:outline-none bg-black px-6 border border-black py-1 rounded-full text-gray-500 flex items-center pt-3">Comment</button>
</div>
<ul class="w-full comments">
<li class="w-full comment mt-4">
<div class="w-full md:w-1/2 comment flex flex-col">
<div class="flex gap-4 items-center text-lg font-bold">
<img src="assets/media/svg/NoPath - Kopya (75).png" class="rounded-full" alt="">
<h1>André Potchinka</h1>
</div>
<div class="ml-16 flex flex-col justify-center">
<div class=" mt-2 flex gap-1 items-center">
<h1 class="text-gray-500 font-bold">Nice work, congragulations.</h1>
<span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-up"></i>0</span>
<span class="flex gap-2 -mt-1"><i class="fas fa-thumbs-down"></i>0</span>
</div>
<div class="w-full flex flex-col">
<input type="text" class="responseText border-b focus:outline-none bg-transparent mt-4" placeholder="Please login to leave a comment...">
<ul class="responses p-4 flex flex-col gap-2 text-gray-500">
<li>Yoruma yanıt verildi :)</li>
</ul>
<div class="flex justify-end">
<button class="responseBtn mt-2 text-gray-500 w-24 text-center">Answer</button>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>

Close custom modal when click outside the modal in vanilla JS

I've done this but the modal won't open whatsoever
document.addEventListener('click', ({ target }) => {
if (!target.closest('#modal-submit')) {
document.getElementById('modal-submit').classList.add('hide-visibility');
}
})
The trickier part is that there's a form inside the modal.
This to trick "mostly code" error: ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
document.getElementById('show-modal').onclick = (e) => {
document.getElementById('modal-submit').classList.remove('hide-visibility')
}
.hide-visibility {
opacity: 0;
visibility: hidden;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.1.2/tailwind.min.css" rel="stylesheet"/>
<div
id="modal-submit"
class="fixed z-10 inset-0 overflow-y-auto hide-visibility"
style="z-index: 9999; transition: all .5s;"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true"
>
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="bg-white px-4 pb-4 sm:p-3 sm:pb-4">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
Submit Exam
</h3>
<div class="mt-5">
<p class="text-sm text-gray-500">
<input id="certify-checkbox" type="checkbox" class="form-checkbox h-3 w-3 text-gray-600">
I certify that
</p>
</div>
<div class="mt-5">
<p class="text-sm text-gray-500">
<input id="final-checkbox" type="checkbox" class="form-checkbox h-3 w-3 text-gray-600">
I have conducted a final round of proofing before submitting this project.
</p>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm">
Submit
</button>
</div>
</div>
</div>
</div>
<button id="show-modal" class="border border-indigo-600">Show</button>
document.getElementById("show-modal").onclick = (e) => {
document.getElementById("modal-submit").classList.remove("hide-visibility");
};
document.addEventListener('click', (event) => {
const boolIsOutside = document.getElementById("grey-bg").isSameNode(event.target);
if (boolIsOutside) {
document.getElementById("modal-submit").classList.add("hide-visibility");
}
});
.hide-visibility {
opacity: 0;
visibility: hidden;
}
<div
id="modal-submit"
class="fixed z-10 inset-0 overflow-y-auto hide-visibility"
style="z-index: 9999; transition: all .5s; border: 2px solid black"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true"
>
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div id="grey-bg" class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="bg-white px-4 pb-4 sm:p-3 sm:pb-4">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
Submit Exam
</h3>
<div class="mt-5">
<p class="text-sm text-gray-500">
<input id="certify-checkbox" type="checkbox" class="form-checkbox h-3 w-3 text-gray-600">
I certify that
</p>
</div>
<div class="mt-5">
<p class="text-sm text-gray-500">
<input id="final-checkbox" type="checkbox" class="form-checkbox h-3 w-3 text-gray-600">
I have conducted a final round of proofing before submitting this project.
</p>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:w-auto sm:text-sm">
Submit
</button>
</div>
</div>
</div>
</div>
<button id="show-modal" class="border border-indigo-600">Show</button>
Using the concept of event propagation, you can use this,
// You can use any other selector according to your need
const ele = document.getElementById('someId');
// adding click event listener to the selected elem (can use any other event)
document.addEventListener('click', (event) => {
const boolIsInside = ele.contains(event.target);
if (boolIsInside) {
// logic if the click was inside the modal
} else {
// logic if the click was outside the modal
}
});

Categories

Resources