Error when using Hover function of new Elements added by JavaScript - javascript

I need to add new divs when I click on the (+ Add Element) button, where this button will add new divs to each new click.
Elements with a ('.zone div') need to execute the hover function, but this does not happen, the function does not work on new elements added by the (+ Add Element) button.
Obs. I can't just use CSS class, I need the hover function to work through javascript.
How do I solve this question, so that every new div created by the button (+ Add Element) can work with the hover function?
function addElemnt(){
var div = document.createElement('div');
div.innerHTML = 'Hi there - Element!';
div.className = 'box m-2';
document.querySelector('.zone').appendChild(div);
}
let hover = document.querySelectorAll('.zone div');
for (let elem of hover) {
elem.addEventListener('mouseenter', () => {
elem.style.backgroundColor = 'red'
})
elem.addEventListener('mouseleave', () => {
elem.style.backgroundColor = ''
})
};
.box, .zone{
transition: .4s;
}
.zone{
padding: 16px;
background: #bdbdbd21;
min-width: 282px;
min-height: 200px;
}
.box{
cursor: move !important;
padding: 16px;
box-shadow: 0 2px 2px -1px #a0a0a0cc;
width: 250px;
margin-bottom: 10px;
border-radius: 4px;
font-weight: 600;
font-size: 18px;
background-color: #FFF;
}
.status{
width: 30px;
height: 8PX;
background: gray;
margin-bottom: 16px;
border-radius: 8px;
}
.status.red{
background: red;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>
<h1>Hello!</h1>
<div class="container text-center">
<div class="row">
<div class="col p-3" style="background-color: silver;">
<a class="btn btn-primary" onclick="addElemnt()" role="button">+ Add Element</a>
</div>
<div class="col-8 zone">
<div class="box m-2">Hi there - 01!</div>
<div class="box m-2">Hi there - 02!</div>
</div>
</div>
</div>
</body>
</html>

You can use event delegation on the .zone element.
let zone = document.querySelector('.zone');
zone.addEventListener('mouseenter', e => {
if (e.target.matches('.box')) e.target.style.backgroundColor = 'red';
}, true);
zone.addEventListener('mouseleave', e => {
if (e.target.matches('.box')) e.target.style.backgroundColor = '';
}, true);
function addElemnt() {
var div = document.createElement('div');
div.innerHTML = 'Hi there - Element!';
div.className = 'box m-2';
document.querySelector('.zone').appendChild(div);
}
let zone = document.querySelector('.zone');
zone.addEventListener('mouseenter', e => {
if (e.target.matches('.box')) e.target.style.backgroundColor = 'red';
}, true);
zone.addEventListener('mouseleave', e => {
if (e.target.matches('.box')) e.target.style.backgroundColor = '';
}, true);
.box,.zone{padding:16px;transition:.4s}.zone{background:#bdbdbd21;min-width:282px;min-height:200px}.box{cursor:move!important;box-shadow:0 2px 2px -1px #a0a0a0cc;width:250px;margin-bottom:10px;border-radius:4px;font-weight:600;font-size:18px;background-color:#fff}.status{width:30px;height:8PX;background:gray;margin-bottom:16px;border-radius:8px}.status.red{background:red}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<h1>Hello!</h1>
<div class="container text-center">
<div class="row">
<div class="col p-3" style="background-color: silver;">
<a class="btn btn-primary" onclick="addElemnt()" role="button">+ Add Element</a>
</div>
<div class="col-8 zone">
<div class="box m-2">Hi there - 01!</div>
<div class="box m-2">Hi there - 02!</div>
</div>
</div>
</div>

Related

I am trying to change the background-color/opacity of a modal before it is opened/shown in a simple Bug tracker

I am creating a simple bug tracker that uses a modal to pop up different bugs. The problem I have is that when I delete a bug, there is a thin grey box where the background of the modal was. So basically the list of bugs is empty but it shows the background of the modal even when it should not be there. For example , if you load up the files and open with live server; create a new bug, then delete the bug, you will see the grey box where the bug was just at. I am trying to have the background not be there, when there is no bugs in the list. Any help is greatly appreciated.
I have tried changing the opacity of the modal and issuesList as well as background color, but tbh I am completely lost on how to dynamically change the opacity.
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"
crossorigin="anonymous">
<script src="https://kit.fontawesome.com/4582c8b826.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/css/styles.css">
<title>Issue Tracker</title>
</head>
<body>
<div class="contaienr">
<h1>Issue Tracker</h1>
<div class="jumbotron">
<h3>Add New Issue:</h3>
<form id="issueinputform">
<div class="form-group">
<label for="issueDescription">Description</label>
<input type="text" class="form-control" id="issueDescription" placeholder="Describe the issue ...">
</div>
<div class="form-group">
<label for="issueSeverity">Severity</label>
<select class="form-control" id="issueSeverity">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</div>
<div class="form-group">
<label for="issueAssignedTo">Assigned To</label>
<input type="text" class="form-control" id="issueAssignedTo" placeholder="Enter responsible ...">
</div>
<button id="add-issue" onclick="submitIssue()" class="btn btn-primary">Add</button>
</form>
</div>
<div class="col-lg-12">
<div id="issuesList">
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="emptyField" tabindex="-1" role="dialog" aria-labelledby="emptyFieldLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="emptyFieldLabel">Invalid Input!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Please provide the desciption of the issue and also the person name who you want to assign the issue.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.3.0-alpha1/dist/js/bootstrap.min.js" integrity="sha384-mQ93GR66B00ZXjt0YO5KlohRA5SY2XofN4zfuZxLkoj1gXtW8ANNCe9d5Y3eG5eD" crossorigin="anonymous"></script>
<script src="app.js"></script>
</body>
</html>
app.js
function submitIssue(e) {
const getInputValue = id => document.getElementById(id).value;
const description = getInputValue('issueDescription');
const severity = getInputValue('issueSeverity');
const assignedTo = getInputValue('issueAssignedTo');
const id = Math.floor(Math.random() * 100000000) + '';
const status = 'Open';
if ((description.length == 0) || (assignedTo.length == 0)) {
alert("Please fill all fields with required data.");
document.getElementById('add-issue').setAttribute("data-toggle", "modal");
document.getElementById('add-issue').setAttribute("data-target", "#emptyField")
}
else {
document.getElementById('add-issue').removeAttribute("data-toggle", "modal");
document.getElementById('add-issue').removeAttribute("data-target", "#emptyField")
const issue = { id, description, severity, assignedTo, status };
let issues = [];
if (localStorage.getItem('issues')) {
issues = JSON.parse(localStorage.getItem('issues'));
}
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssues();
}
}
const closeIssue = id => {
const issues = JSON.parse(localStorage.getItem('issues'));
const currentIssue = issues.find(issue => issue.id == id);
currentIssue.status = 'Closed';
currentIssue.description = `<strike>${currentIssue.description}</strike>`
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssues();
}
const deleteIssue = id => {
const issues = JSON.parse(localStorage.getItem('issues'));
const remainingIssues = issues.filter(issue => ((issue.id) != id))
localStorage.removeItem('issues');
localStorage.setItem('issues', JSON.stringify(remainingIssues));
fetchIssues();
}
const fetchIssues = () => {
const issues = JSON.parse(localStorage.getItem('issues'));
const issuesList = document.getElementById('issuesList');
issuesList.innerHTML = '';
for (let i = 0; i < issues.length; i++) {
const { id, description, severity, assignedTo, status } = issues[i];
issuesList.innerHTML += `<div class="well">
<h6>Issue ID: ${id} </h6>
<p><span class="label label-info"> ${status} </span></p>
<h3> ${description} </h3>
<p><i class="fa-solid fa-bolt"></i> ${severity}</p>
<p><i class="fa-solid fa-user"></i> ${assignedTo}</p>
<button onclick="closeIssue(${id})" class="btn btn-warning">Close</button>
<button onclick="deleteIssue(${id})" class="btn btn-danger">Delete</button>
</div>`;
}
}
fetchIssues();
styles.css
*{
box-sizing: border-box;
}
.jumbotron{
background: rgb(225, 224, 224);
margin-top: 20px;
margin-left: 150px;
margin-right: 150px;
padding-left: 60px;
padding-right: 60px;
padding-top: 50px;
padding-bottom: 50px;
border-radius: 6px;
}
.container{
}
p{
margin: 0 0 10px;
}
h1{
font-size: 36px;
margin-top: 20px;
margin-bottom: 10px;
margin-left: 150px;
}
/* .col-lg-12{
display: block;
font-size: 14px;
line-height: 1.42857143;
color: #333;
} */
#issuesList{
padding-top: 40px;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
display: block;
margin-left: 170px;
margin-right: 170px;
margin-top: 40px;
margin-bottom: 20px;
background-color: rgb(233, 233, 233);
border-radius: 6px;
border: solid grey transparent ;
border-width: thin;
}
h6{
font-size: 12px;
font-family: inherit;
margin-bottom: 10px;
}
h3{
margin-bottom: 10px;
margin-top: 30px;
font-weight: 500;
line-height: 1.1;
}
.label{
background-color: #5bc0de;
border: solid rgb(10, 198, 240);
border-radius: 0.25em;
padding: 3px;
color: white;
line-height: 1;
font-weight: 700;
font-size: 75%;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
}
#add-issue{
margin-top: 20px;
}
.container::after{
clear: both
}
.modal
{
opacity:0.5 !important;
}

How can I delete specific <li> item from the list?

I want to make a to do list with HTML, CSS and JS but I can not add delete function. I wanna hold these tasks in localStorage at the same time. When I click second item's delete button, always first item gets deleted. What can I do?
Basically, I want to seperate li's with [data-text=tasklist[i] and delete the li item that has attribute or when clicked.
HTML:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="css/style.css" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l"
crossorigin="anonymous"
/>
<link rel="shortcut icon" href="#">
<title>To Do List</title>
</head>
<body>
<!-- Toast start Task -->
<div class="position-fixed bottom-0 right-0 p-3"
style="z-index: 5; right: 0; top: 0;">
<div id="liveToast" class="toast hide" role="alert" aria-live="assertive"
aria-atomic="true" data-delay="6000">
<div class="toast-header">
<strong class="mr-auto">Kodluyoruz </strong>
<span id="toast-img"></span>
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="toast-body font-weight-bold">
</div>
</div>
</div>
<!-- Toast End For task -->
<!-- Container Start -->
<div class="container col-sm-8 mt-5">
<div class="row text-center d-block">
<!-- Header Start -->
<div class="header my-3 rounded ">
<img
src="https://cdn.sanity.io/images/9kdepi1d/production/65c832d202a503b15d99e628f4313782f3ef50db-300x62.png"
class="mb-1"
alt=""
/>
<h2>To Do List</h2>
<div id="searchBar" class="input-group">
<input class="input-group rounded-left d-inline" type="text"
name="task" id="task" placeholder="Bugün ne yapacaksın?" />
<div class="input-group-append">
<button class="btn btn-primary" onclick="newElement()" id="liveToastBtn">Ekle</button>
</div>
</div>
</div>
<!-- Header End -->
<!-- Task List Start -->
<ul class="list-group" id="list">
</ul>
<!-- Task List End -->
<script
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"
></script>
<script src="js/app.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns"
crossorigin="anonymous"
></script>
</div>
</div>
<!-- Container End -->
</body>
</html>
JS:
var TASK = document.querySelector('#task');
let ulEl = document.querySelector('#list');
const toastEl = document.querySelector('#liveToast');
const toastBody = document.querySelector('.toast-body');
const toastImg = document.querySelector('#toast-img');
let collapseBtn = `<button id="clsBtn" onclick="deleteTask()" type="button" class="close"
data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>`
let taskList = !localStorage.getItem('tasks') ? [] : (localStorage.getItem('tasks').split(','));
console.log(taskList)
console.log(taskList.length)
// get the list of tasks in local storage
if(taskList.length>0){
for (let i=0; i < taskList.length; i++) {
if(checkForText(taskList[i])){
TASK.value = taskList[i];
const liDOM = document.createElement('li');
liDOM.innerHTML = `${TASK.value} ${collapseBtn}`;
liDOM.classList.add('list-group-item','d-flex',
'justify-content-between', 'align-items-center');
liDOM.setAttribute('data-text',TASK.value);
ulEl.append(liDOM);
TASK.value = '';
}
}
}
// check for <text> is in the list?
function checkForText(text) {
let found = false;
if(taskList.includes(text.toLowerCase())) {
found = true;
}
return found;
}
// add new Task
function newElement (){
console.log(TASK.value);
console.log("running");
const liDOM = document.createElement('li');
if (TASK.value.length > 0){
if(checkForText(TASK.value)){
//toast
toastBody.innerHTML = `<p class= "text-danger">
Eklemek istediğiniz görev listede mevcut!!</p>`
toastImg.innerHTML = `<img id="toastImg" style="width: 5px;"
src="img/exclamation-solid.svg" class="rounded mr-2" alt="">`
//Showing and Hiding Toast automatically -JQuery
$(document).ready(function(){
$('#liveToast').toast('show');
});
TASK.value= '';
}else{
liDOM.innerHTML = `${TASK.value} ${collapseBtn}`;
liDOM.classList.add('list-group-item','d-flex',
'justify-content-between', 'align-items-center');
liDOM.setAttribute('data-text',TASK.value);
ulEl.append(liDOM);
taskList.push(TASK.value.trim());
localStorage.setItem('tasks',(taskList));
//************************************ */
// toast
toastBody.innerHTML = `<p class= "text-success">Görev listeye eklendi.</p>`;
toastImg.innerHTML = `<img id="toastImg" style="width: 15px;"
src="img/check-solid.svg" class="rounded mr-2" alt="">`
//Showing and Hiding Toast automatically -JQuery
$(document).ready(function(){
$('#liveToast').toast('show');
});
TASK.value= '';
}
}else if (TASK.value.length <1 ){
// toast
toastBody.innerHTML = `<p class= "text-danger">Listeye boş ekleme yapamazsınız!!</p>`
toastImg.innerHTML = `<img id="toastImg" style="width: 5px;"
src="img/exclamation-solid.svg" class="rounded mr-2" alt="">`
//Showing and Hiding Toast automatically -JQuery
$(document).ready(function(){
$('#liveToast').toast('show');
});
// toastEl.classList.replace('hide', 'show');
// await sleep (7000);
// toastEl.classList.replace( 'show', 'hide');
}
}
// delete Task
//if(localStorage.getItem('tasks').length > 0 || taskList.length > 0 ){
function deleteTask(){
let liEl = document.querySelectorAll('.list-group-item');
let i = 0;
for(; i < taskList.length; i++){
if(liEl("data-text") === taskList[i]){
// taskList.splice(taskList.indexOf(taskList[i]), 1);
// liEl.querySelector(`[data-text="${taskList[i]}"]`).removeChild();
console.log( "attr"+liEl.getAttribute("data-text"));
localStorage.setItem('tasks', taskList);
// console.log(taskList);
// console.log(localStorage.getItem('tasks'))
}
}
}
CSS:
* {
box-sizing: border-box;
}
ul {
margin: 0;
padding: 0;
}
ul li {
cursor: pointer;
position: relative;
padding: 12px 8px 12px 40px;
background: #eee;
font-size: 18px;
transition: 0.2s;
list-style-type: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
ul li:nth-child(odd) {
background: #f9f9f9;
}
ul li:hover {
background: #ddd;
}
ul li.checked {
background: #276678;
color: #fff;
text-decoration: line-through;
}
ul li.checked::before {
content: "";
position: absolute;
border-color: #fff;
border-style: solid;
border-width: 0 2px 2px 0;
top: 10px;
left: 16px;
transform: rotate(45deg);
height: 15px;
width: 7px;
}
.close {
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close:hover {
background-color: #f78501;
color: white;
}
.header {
background-color: #f78501;
padding: 30px 40px;
color: white;
text-align: center;
}
img {
background-color: white;
}
.header:after {
content: "";
display: table;
clear: both;
}
input {
margin: 0;
border: none;
border-radius: 0;
width: 75%;
padding: 10px;
float: left;
font-size: 16px;
}
.button {
padding: 10px;
width: 25%;
background: #d9d9d9;
color: #555;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
}
.button:hover {
background-color: #bbb;
}
#task {
width: 94%;
}
I found the solution if anyone need.
Firstly, i create a node list with css attribute selector. (line 98 app.js)
Then i added event listener with for loop (line 100 app.js)
Only bad side of this solution, page have to reload with 'location.reload' function when add a new task. Here all codes:
var TASK = document.querySelector('#task');
let ulEl = document.querySelector('#list');
const toastEl = document.querySelector('#liveToast');
const toastBody = document.querySelector('.toast-body');
const toastImg = document.querySelector('#toast-img');
let collapseBtn = `<button data-delete="cls" class= "Btn rounded small border-secondary" type="button" class="close"
data-dismiss="alert" aria-label="Close">
<span class=" font-weight-bold" aria-hidden="true">×</span>
</button>`
let taskList = !localStorage.getItem('tasks') ? [] : (localStorage.getItem('tasks').split(','));
console.log(taskList)
console.log(taskList.length)
//get the list of tasks in local storage
if(taskList.length>0){
for (let i=0; i < taskList.length; i++) {
if(checkForText(taskList[i])){
TASK.value = taskList[i];
const liDOM = document.createElement('li');
liDOM.innerHTML = `<p>${TASK.value}</p> ${collapseBtn}`;
liDOM.classList.add('list-group-item','d-flex',
'justify-content-between', 'align-items-center');
liDOM.setAttribute('data-text',TASK.value);
ulEl.append(liDOM);
TASK.value = '';
}
}
}
//check for 'text' is in the list?
function checkForText(text) {
let found = false;
if(taskList.includes(text.toLowerCase())) {
found = true;
}
return found;
}
//Add new Task
async function newElement (){
console.log(TASK.value);
console.log("running");
const liDOM = document.createElement('li');
if (TASK.value.length > 0){ //if value length is greater than zero
if(checkForText(TASK.value)){ //if value is already in the list
//toast
toastBody.innerHTML = `<p class= "text-danger">
Eklemek istediğiniz görev listede mevcut!!</p>`
toastImg.innerHTML = `<img id="toastImg" style="width: 5px;"
src="img/exclamation-solid.svg" class="rounded mr-2" alt="">`
//Showing and Hiding Toast automatically -JQuery
$(document).ready(function(){
$('#liveToast').toast('show');
});
TASK.value= '';
}else{ //if value is not in the list, add it to the list
liDOM.innerHTML = `<p>${TASK.value}</p> ${collapseBtn}`;
liDOM.classList.add('list-group-item','d-flex',
'justify-content-between', 'align-items-center');
liDOM.setAttribute('data-text',TASK.value);
ulEl.append(liDOM);
taskList.push(TASK.value.trim());
localStorage.setItem('tasks',(taskList));
//************************************ */
//toast
toastBody.innerHTML = `<p class= "text-success">Görev listeye eklendi.</p>`;
toastImg.innerHTML = `<img id="toastImg" style="width: 15px;"
src="img/check-solid.svg" class="rounded mr-2" alt="">`
//Showing and Hiding Toast automatically -JQuery
$(document).ready(function(){
$('#liveToast').toast('show');
});
TASK.value= '';
//working like sleep function
await new Promise(done => setTimeout(() => done(), 3000));
//reload page for close button - addEventListener(deleteTask)
location.reload();
}
}else if (TASK.value.length <1 ){ // if value length is smaller than one
// toast
toastBody.innerHTML = `<p class= "text-danger">Listeye boş ekleme yapamazsınız!!</p>`
toastImg.innerHTML = `<img id="toastImg" style="width: 5px;"
src="img/exclamation-solid.svg" class="rounded mr-2" alt="">`
//Showing and Hiding Toast automatically -JQuery
$(document).ready(function(){
$('#liveToast').toast('show');
});
// toastEl.classList.replace('hide', 'show');
// await sleep (4000);
// toastEl.classList.replace( 'show', 'hide');
}
}
//Delete Task
if(taskList.length > 0 ){
let clsBtn = document.querySelectorAll(`[data-delete="cls"]`)
let i = 0;
for(; i < clsBtn.length; i++){
clsBtn[i].addEventListener('click', deleteTask)
}
function deleteTask(){
let txt = this.parentElement.querySelector('p')
taskList.splice(taskList.indexOf(txt.innerText),1);
this.parentElement.remove();
localStorage.setItem('tasks',taskList);
}
}

I want click and drag cursor to draw in grid using vue

i want to create something like pathfinding using vue. So when i click and drag in the grid i want to get all the data-x and data-y value in array and change the color of those cells,
and when i click on obstacle button then it should draw accordingly.
i can use python for backend if that helps somehow .
here's my code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<style>
.g-x {
width: max-content;
display: flex;
}
.g-y {
border: 1px solid #d8d6de;
margin: 1px;
box-shadow: 0 4px 24px 0 rgb(34 41 47 / 10%);
}
#grid {
box-shadow: 0 4px 24px 0 rgb(34 41 47 / 10%);
}
span.inner-grid {
width: 20px;
display: block;
height: 20px;
transition: all 0.2s ease-in-out;
background-color: rgb(233, 166, 166);
border-radius: 5px;
margin: 3px;
}
span.inner-grid:hover {
background-color: rgb(189, 224, 65);
}
.start {
background-color: green;
}
.end {
background-color: red;
}
.wall {
background-color: rgb(0, 0, 0);
}
</style>
</head>
<body>
<div class="">
<div id="buttons" class="row">
<div class="col-4 my-5 text-center btn-parent">
<button
class="btn btn-primary btn-sm setVal"
v-on:click="setMode('start')"
type="button"
>
Select Start
</button>
</div>
<div class="col-4 my-5 text-center btn-parent">
<button
class="btn btn-primary btn-sm setVal"
v-on:click="setMode('end')"
type="button"
>
Select End
</button>
</div>
<div class="col-4 my-5 text-center btn-parent">
<button
class="btn btn-primary btn-sm setVal"
v-on:click="setMode('wall')"
type="button"
>
Select Obstacle
</button>
</div>
</div>
<div class="row">
<div id="grid" class="col-12">
<span class="g-x" v-for="(x, index) in grid_x">
<span class="g-y" v-for="(y, index) in grid_y">
<span
v-on:click="setVal()"
:data-x="x"
:data-y="y"
class="inner-grid"
>
</span>
</span>
</span>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.14/dist/vue.js"></script>
<script>
var grid_x = [];
var grid_y = [];
var mode = "start";
for (let i = 0; i < 50; i++) {
grid_x.push(i);
grid_y.push(i);
}
var example2 = new Vue({
el: "#grid",
data: {
parentMessage: "Parent",
grid_x: grid_x,
grid_y: grid_y,
},
methods: {
setVal: function () {
var element = event.target;
var x = element.getAttribute("data-x");
var y = element.getAttribute("data-y");
},
},
});
var button = new Vue({
el: "#buttons",
methods: {
setMode: function (type) {
mode = type;
},
},
});
</script>
</body>
</html>

How to disable and enable a tag click

On clicking the "minus" span the value in "count" input decreases, but it should stop decreasing when it reaches 0. So I disable "minus" span but it remains disabled when value is positive again.
$(document).on('click','.plus',function(){
$(this).closest('.content').find('.count').val(parseInt($(this).closest('.content').find('.count').val()) + 1 );
});
$(document).on('click','.minus',function(){ $(this).closest('.content').find('.count').val(parseInt($(this).closest('.content').find('.count').val()) - 1 );
if ($(this).closest('.content').find('.count').val() == 0) {
$(this).closest('.content').find('.count').val(0);
$(this).closest('.minus').prop('disabled', true);
}else{
$(this).closest('.minus').prop('disabled', false);
}
});
.qty .count {
border: 1px solid #e1ecfb;
color: #000;
display: inline-block;
vertical-align: top;
font-size: 15px;
font-weight: 450;
padding: 0 0;
width: 35px;
text-align: center;
}
.qty .plus {
cursor: pointer;
display: inline-block;
vertical-align: top;
color: white;
background-color: #cee0f9;
width: 25px;
height: 25px;
font: 25px/1 Arial,sans-serif;
text-align: center;
border-radius: 30%;
}
.qty .minus {
cursor: pointer;
display: inline-block;
vertical-align: top;
color: #ffffff;
background-color: #cee0f9;
width: 25px;
height: 25px;
font: 23px/1 Arial,sans-serif;
text-align: center;
border-radius: 30%;
background-clip: padding-box;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<title>Document</title>
</head>
<body>
<div class="produk_list">
<div class="container-fluid" style="padding-bottom:50px;">
<div class="row data_produk" id="data_produk" style="text-align: center;">
<div class="col-6 gallery" value="1">
<div class="content">
<img src="https://awsimages.detik.net.id/community/media/visual/2021/04/06/sandwich-keju-tomat-dan-alpukat-1_43.jpeg?w=700&q=90" width="150" height="150">
<h6>Product Name</h6>
<h6>Product Price</h6>
<div class="qty" id="qty">
<span class=" btn-primary minus b-dark">-</span>
<input type="number" class="count" name="qty" value="1">
<span class="plus b-dark">+</span>
</div>
<button class="buy-1 btn-button" id="pesan"><i class="fas fa-cart-plus"></i></button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>
The problem is that else is never reached since when it's 0 it's now disabled and won't be clicked again.
Try this:
$(document).on('click','.plus',function(){
let countField=$(this).siblings('.count');
let iniVal=parseInt(countField.val());
iniVal++;
countField.val(iniVal);
$(this).siblings('.minus').prop('disabled', false);
});
$(document).on('click','.minus',function(){
let countField=$(this).siblings('.count');
let iniVal=parseInt(countField.val());
iniVal--;
countField.val(iniVal);
if(iniVal===0){
$(this).prop('disabled', true);
}
});
or you can avoid using .prop():
$(document).on('click','.plus',function(){
let countField=$(this).siblings('.count');
let iniVal=parseInt(countField.val());
iniVal++;
countField.val(iniVal);
});
$(document).on('click','.minus',function(){
let countField=$(this).siblings('.count');
let iniVal=parseInt(countField.val());
if(iniVal>0){
iniVal--;
countField.val(iniVal);
}
});
Try the below code it works fine.
$(document).on('click','.plus',function(){
var currVal = parseInt($('.count').val()) + parseInt(1);
$('.count').val(currVal);
$('.minus').prop('disabled', false);
});
$(document).on('click','.minus',function(){
var currVal = parseInt($('.count').val()) - parseInt(1);
$('.minus').prop('disabled', false);
if(currVal == 0){
$('.minus').prop('disabled', true);
}
$('.count').val(currVal);
});

Progress bar jQuery percent counter not working

I created a skill progress bar for my project using HTML CSS and jquery. All things working fine but the percent counter option is not working when the animation run.
I need to count the percentage from 0 to the value along with the animation bar. Please help me. Thanks.
jQuery(function($){
$(window).scroll(function() {
var top_of_element = $(".work-process").offset().top;
var bottom_of_element = $(".work-process").offset().top + $(".work-process").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
var top_of_screen = $(window).scrollTop();
if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
$('.project-percent').each(function(){
var $this = $(this);
var percent = $this.attr('percent');
$this.css("width",percent+'%');
$({animatedValue: 0}).animate({animatedValue: percent},{
duration: 2000,
step: function(){
$this.attr('percent', Math.floor(this.animatedValue) + '%');
},
complete: function(){
$this.attr('percent', Math.floor(this.animatedValue) + '%');
}
});
});
}
});
});
.nb-progressbar-row {
width: 90%;
margin: 0 auto;
}
.project{
width: 60%;
margin: 0 auto;
}
.work-process h3 {
margin: 30px 0px 10px;
}
.project-bar {
height: 18px;
background: #e0e0e0;
border-radius: 30px;
}
.project-percent {
height: 18px;
background-color: #2196F3;
border-radius: 30px;
position: relative;
width: 0;
transition: 2s linear;
}
.project-percent::before {
content: attr(percent);
position: absolute;
right: 0px;
left: 0px;
padding: 1px 0px;
color: #ffffff;
font-size: 15px;
border-radius: 25px;
font-weight: bold;
width: 20px;
margin: 0px auto;
}
<!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">
<title>HTML 5 Boilerplate</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
</head>
<body>
<section class= " my-5 nb-progressbar-wrapper">
<div class="container my-5 nb-progressbar-conainer">
<div class="row nexnomic-progressbar-row">
<div class=" col work-process">
<h2 class="text-center my-5">SCROLL DOWN</h2>
<div class=" pt-5 project">
<h6>Xyzzz & ABCD</h6>
<div class="project-bar">
<div class="project-percent" percent="95"></div>
</div>
</div>
<div class="project">
<h6>Abcd-xyz</h6>
<div class="project-bar">
<div class="project-percent" percent="80"></div>
</div>
</div>
<div class="project">
<h6>ABCDYZX</h6>
<div class="project-bar">
<div class="project-percent" percent="75"></div>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/js/bootstrap.min.js" integrity="sha384-skAcpIdS7UcVUC05LJ9Dxay8AXcDYfBJqt1CJ85S/CFujBsIzCIv+l9liuYLaMQ/" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</body>
</html>

Categories

Resources