Close custom modal when click outside the modal in vanilla JS - javascript

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
}
});

Related

Popover on hover vue headllessui

I'm trying to implement the popover from headlessui of vue package with hover. I try to use the mouseenter and mouseleave and the other mouse events but nothing change.
Any solution? There is a better solution? i search on internet I cant nothing about this. I search on headlessui github discussions but nothing.
<template>
<div class="fixed top-16 w-full max-w-sm px-4">
<Popover v-slot="{ open }" class="relative">
<PopoverButton
:class="open ? '' : 'text-opacity-90'"
class="group inline-flex items-center rounded-md bg-orange-700 px-3 py-2 text-base font-medium text-white hover:text-opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
>
<span>Solutions</span>
<ChevronDownIcon
:class="open ? '' : 'text-opacity-70'"
class="ml-2 h-5 w-5 text-orange-300 transition duration-150 ease-in-out group-hover:text-opacity-80"
aria-hidden="true"
/>
</PopoverButton>
<transition
enter-active-class="transition duration-200 ease-out"
enter-from-class="translate-y-1 opacity-0"
enter-to-class="translate-y-0 opacity-100"
leave-active-class="transition duration-150 ease-in"
leave-from-class="translate-y-0 opacity-100"
leave-to-class="translate-y-1 opacity-0"
>
<PopoverPanel
class="absolute left-1/2 z-10 mt-3 w-screen max-w-sm -translate-x-1/2 transform px-4 sm:px-0 lg:max-w-3xl"
>
<div
class="overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5"
>
<div class="relative grid gap-8 bg-white p-7 lg:grid-cols-2">
<a
v-for="item in solutions"
:key="item.name"
:href="item.href"
class="-m-3 flex items-center rounded-lg p-2 transition duration-150 ease-in-out hover:bg-gray-50 focus:outline-none focus-visible:ring focus-visible:ring-orange-500 focus-visible:ring-opacity-50"
>
<div
class="flex h-10 w-10 shrink-0 items-center justify-center text-white sm:h-12 sm:w-12"
>
<div v-html="item.icon"></div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-900">
{{ item.name }}
</p>
<p class="text-sm text-gray-500">
{{ item.description }}
</p>
</div>
</a>
</div>
<div class="bg-gray-50 p-4">
<a
href="##"
class="flow-root rounded-md px-2 py-2 transition duration-150 ease-in-out hover:bg-gray-100 focus:outline-none focus-visible:ring focus-visible:ring-orange-500 focus-visible:ring-opacity-50"
>
<span class="flex items-center">
<span class="text-sm font-medium text-gray-900">
Documentation
</span>
</span>
<span class="block text-sm text-gray-500">
Start integrating products and tools
</span>
</a>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
</div>
</template>
Seems like common request in HeadlessUI community.
Another solution found this solution on Github that worked fine for me.
for vanilla vue 3 with js the original solution link Github Issue
Nuxt 3 with typescript maintaining accessibility here's the code ↓
<script setup lang="ts">
import { Popover, PopoverButton, PopoverPanel } from '#headlessui/vue'
interface Props {
label: string
hasHref?: boolean
href?: string
}
const props = defineProps<Props>()
const popoverHover = ref(false)
const popoverTimeout = ref()
const hoverPopover = (e: any, open: boolean): void => {
popoverHover.value = true
if (!open) {
e.target.parentNode.click()
}
}
const closePopover = (close: any): void => {
popoverHover.value = false
if (popoverTimeout.value) clearTimeout(popoverTimeout.value)
popoverTimeout.value = setTimeout(() => {
if (!popoverHover.value) {
close()
}
}, 100)
}
</script>
<template>
<Popover v-slot="{ open, close }" class="relative">
<PopoverButton
:class="[
open ? 'text-primary' : 'text-gray-900',
'group inline-flex items-center rounded-md bg-white text-base font-medium hover:text-primary focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2'
]"
#mouseover="(e) => hoverPopover(e, open)"
#mouseleave="closePopover(close)"
>
<span v-if="!hasHref">{{ props.label }}</span>
<span v-else>
<NuxtLink :to="href">
{{ props.label }}
</NuxtLink>
</span>
<IconsChevronDown
:class="[
open ? 'rotate-180 transform text-primary' : '',
' ml-1 h-5 w-5 text-primary transition-transform group-hover:text-primary'
]"
aria-hidden="true"
/>
</PopoverButton>
<transition
enter-active-class="transition ease-out duration-200"
enter-from-class="opacity-0 translate-y-1"
enter-to-class="opacity-100 translate-y-0"
leave-active-class="transition ease-in duration-150"
leave-from-class="opacity-100 translate-y-0"
leave-to-class="opacity-0 translate-y-1"
>
<PopoverPanel
class="absolute left-1/2 z-10 mt-3 ml-0 w-auto min-w-[15rem] -translate-x-1/2 transform px-2 sm:px-0"
#mouseover.prevent="popoverHover = true"
#mouseleave.prevent="closePopover(close)"
>
<div
class="overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5"
>
<div class="relative grid gap-1 bg-white p-3">
<slot> put content here </slot>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
</template>
It is in the docs:showing-hiding-popover.
open is an internal state used to determine if the component is shown or hidden. To implement your own functionality, you can remove it and use the static prop to always render a component. Then you can mange the visibility with your own state ref and a v-if/v-show. The mouse-action has to be in the upper scope, so it is not triggered leaving the component, e.g. moving the mouse from button to panel.
Below is a modified example from the API documentation:
<template>
<Popover
#mouseenter="open = true"
#mouseleave="open = false"
#click="open = !open"
>
<PopoverButton #click="open = !open">
Solutions
<ChevronDownIcon :class="{ 'rotate-180 transform': open }" />
</PopoverButton>
<div v-if="open">
<PopoverPanel static>
Insights
Automations
Reports
</PopoverPanel>
</div>
</Popover>
</template>
<script setup>
import { ref } from 'vue';
import { Popover, PopoverButton, PopoverPanel } from '#headlessui/vue';
import { ChevronDownIcon } from '#heroicons/vue/20/solid';
const open = ref(false);
</script>

How to get html element in #document of iframe tag

i'm new with Stack Overflow. I don't have enough 10 reputation to embed image. Sorry for this inconvenience but I have some question about iframe tag:
I tried some way to get html element in #document of iframe tag, but somehow it still not work. Can you explain why for me and how can I get element have id = "check". I'm try to learn
There is test.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<iframe src="/login" width="100%" height="100%" id="iframe"></iframe>
<script>
const iframe = $("#iframe");
console.log(iframe);
console.log(iframe.contents());
console.log(iframe.contents().find("#check").html());
</script>
</body>
</html>
There is login.blade.php
<x-common :title="'Login'">
<x-slot name='main'>
<div class="w-full lg:w-4/12 px-4">
<div class="pt-20"></div>
<div
class="relative flex flex-col min-w-0 break-words w-full mb-6 shadow-lg rounded-lg bg-gray-200 border-0">
<div class="rounded-t mb-0 px-6 py-6">
<div class="text-center mb-3">
<h6 class="text-gray-500 text-sm font-bold">
Sign in with
</h6>
</div>
<div class="btn-wrapper text-center">
<button
class="bg-white active:bg-gray-50 text-gray-700 px-4 py-2 rounded outline-none focus:outline-none mr-2 mb-1 uppercase shadow hover:shadow-md inline-flex items-center font-bold text-xs ease-linear transition-all duration-150"
type="button">
<img alt="..." class="w-5 mr-1"
src="{{ asset('assets/img/github.svg') }}" />Github</button><button
class="bg-white active:bg-gray-50 text-gray-700 px-4 py-2 rounded outline-none focus:outline-none mr-1 mb-1 uppercase shadow hover:shadow-md inline-flex items-center font-bold text-xs ease-linear transition-all duration-150"
type="button">
<img alt="..." class="w-5 mr-1" src="{{ asset('assets/img/google.svg') }}" />Google
</button>
</div>
<hr class="mt-6 border-b-1 border-gray-300" />
</div>
<div class="flex-auto px-4 lg:px-10 py-10 pt-0">
<div class="text-gray-400 text-center mb-3 font-bold">
<small>Or sign in with credentials</small>
</div>
<x-alert></x-alert>
<form action="login" method="post">
<div class="relative w-full mb-3">
<label class="block uppercase text-gray-600 text-xs font-bold mb-2"
for="grid-password">Email</label><input type="email"
class="border-0 px-3 py-3 placeholder-gray-300 text-gray-600 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150"
placeholder="Email" name="email" value="{{ old('email') }}" />
</div>
<div class="relative w-full mb-3">
<label class="block uppercase text-gray-600 text-xs font-bold mb-2"
for="grid-password">Password</label><input type="password" autocomplete="on"
class="border-0 px-3 py-3 placeholder-gray-300 text-gray-600 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150"
placeholder="Password" name="password" value="{{ old('password') }}" />
</div>
<div id="check">
<label class="inline-flex items-center cursor-pointer"><input id="customCheckLogin"
type="checkbox"
class="form-checkbox border-0 rounded text-gray-700 ml-1 w-5 h-5 ease-linear transition-all duration-150"
name="remember" /><span class="ml-2 text-sm font-semibold text-gray-600">Remember
me</span></label>
</div>
<div class="text-center mt-6">
<button
class="bg-gray-800 text-white active:bg-gray-600 text-sm font-bold uppercase px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 w-full ease-linear transition-all duration-150"
type="submit">
Sign In
</button>
</div>
#csrf
</form>
<div class="flex flex-wrap">
<div class="w-1/2">
<a href="password/forgot" class="text-gray-500 text-sm font-bold"><small>Forgot
password?</small></a>
</div>
<div class="w-1/2 text-right">
<a href="register" class="text-gray-500 text-sm font-bold"><small>Create new
account</small></a>
</div>
</div>
</div>
</div>
</div>
</x-slot>
</x-common>
Console
Elements
I think the iframe document is not ready when you try to access the nodes. You should wait for the iframe load event after that you can access the child nodes.
$('#iframe').on("load", function() {
// do the stuff here
});
You should try to catch the event 'load' of the iframe using javascript:
document.querySelector("iframe").addEventListener( "load", function() {
console.log("This will appear on the console when the iframe is loaded");
});
Or you can use jquery instead:
$('iframe').on("load", function() {
// content for the iframe when it is loaded
}

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>

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

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>

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>

Categories

Resources