After adding an event listener to addPostBtn
to listen for clicks, it only works the first time it’s clicked and then stops responding. Below is the code I’m using. I don’t know what’s going wrong, please help me solve my Issue. Thank you
data_handle.js
import {onEnterEvent} from './passwd.js';
const mainEl = document.querySelector('.main')
let addPostBtn;
let postInput;
let createPostDialog;
let showPostError;
let numberInput;
let candidateInputForm;
let candidateInfoFormHeading;
let createPostSubmitBtn;
let candidateInfoContainer;
// Code to inject
const addPostCode = `<div class="add_post flex justify-center items-center flex-col gap-2">
<div class="flex justify-center">
<input type="text" class="input-n-r post-input input-normal" placeholder="Enter post name">
<input type="number" placeholder="No. of candidates" class="input-n number-input input-normal">
<button class="btn-primary add-post-btn input-btn">Add post</button>
</div>
<span id="showPostError" class="error"></span>
</div>
<dialog id='createPost' class="w-full max-w-xl p-8 rounded-xl shadow-md">
<div class="relative">
<img src="./img/admin/SVG/cross.svg" alt="" class="icon absolute -top-7 -right-7 hover:scale-[1.10] transition-all cursor-pointer" onclick="createPost.close()">
<h1 class="dialog-heading mb-2 candidateInfoFormHeading"></h1>
<form class='candidateInputForm flex w-full gap-2 flex-col'>
</form>
</div>
</dialog>`
// Code injection event
document.addEventListener('correct-passwd',()=>{
// Changing variables
mainEl.innerHTML+=addPostCode
addPostBtn = document.querySelector('.add-post-btn');
postInput = document.querySelector('.post-input');
createPostDialog = document.querySelector('#createPost');
showPostError = document.querySelector('#showPostError');
numberInput = document.querySelector('.number-input');
candidateInputForm = document.querySelector('.candidateInputForm')
candidateInfoFormHeading = document.querySelector('.candidateInfoFormHeading')
// Adding event listeners
addPostBtn.addEventListener('click', () => {
addPost();
console.log('On click')
});
onEnterEvent(postInput, addPost);
onEnterEvent(numberInput,addPost)
})
// Check if input is empty
function checkTextInputEmpty(el){
const elValue = el.value.trim();
if (elValue === '') {
return true;
}
}
// Add input for candidate names, images.
function addCandidateInfo(noOfCandidates, postName){
let flag = false
candidateInputForm.innerHTML=''
for (let i=1;i<noOfCandidates+1;i++){
let candidateInputFormCode = `<div class="flex candidate-info-container">
<input type="text" placeholder="Enter candidate ${i}" class="input-n-r input-secondary flex-grow candidate-name" required>
<label class="file-upload-btn input-btn btn-secondary-dialog cursor-pointer">
<input type="file" accept=".jpg,.jpeg,.png,.webp" class='candidate-image' required>
<span class="text-sm">Browse Image</span>
<span class="file-name"></span>
</label>
</div>`
candidateInputForm.innerHTML+=candidateInputFormCode
flag = true
}
// After adding inputs add a button to submit them
if(flag===true){
candidateInputForm.innerHTML+=`<button class="btn btn-primary input-btn createPostSubmitBtn" type="submit">Add Post</button>`
createPostSubmitBtn = document.querySelector('.createPostSubmitBtn')
// After submission of form add store candidate info.
candidateInputForm.addEventListener('submit',(event)=>{
event.preventDefault()
postInput.value=''
numberInput.value=''
storeCandidateInfo(postName,noOfCandidates)
createPostDialog.close()
})
// Code to add file name after input
candidateInfoContainer = document.querySelectorAll('.candidate-info-container')
candidateInfoContainer.forEach(div=>{
const fileInput = div.querySelector('input[type="file"]')
const fileNameEl = div.querySelector('.file-name')
fileInput.addEventListener('change',(event)=>{
const files = event.target.files;
if(files.length===1){
const fileName = files[0].name;
fileNameEl.innerText = fileName
}
else{
fileNameEl.innerText = ''
}
})
})
}
}
// Stores candidate info by taking post name and noOfCandidates as argument
function storeCandidateInfo(postName,noOfCandidates){
let candidateNameEl = document.querySelectorAll('.candidate-name')
let candidateImageEl = document.querySelectorAll('.file-name')
let candidateImageInput = document.querySelectorAll('.candidate-image')
let candidateImgName=[] // Store file name
let candidateName = [] // Store candidate's name
let candidateInfo = {} // Combines file name and candidate's name
candidateNameEl.forEach(el=>{
const name = el.value
candidateName = [...candidateName,name]
});
candidateImageEl.forEach(el=>{
const fileName = el.innerText
candidateImgName = [...candidateImgName, fileName]
})
// Saves selected image file in local directory for later use
candidateImageInput.forEach(el=>{
let file = el.files[0];
let reader = new FileReader();
reader.onload = ()=>{
let data = reader.result;
eel.save_image(file.name,data) // Calls python save_image function
}
reader.readAsDataURL(file)
})
// For loop to store data in candidateInfo object
for (let i=0;i<noOfCandidates;i++){
const curr_candidate_name = candidateName[i]
candidateInfo[curr_candidate_name] = [candidateImgName[i],0]
}
eel.store_candidate_info(postName,candidateInfo) // Store candidateInfo as json file
candidateInfoFormHeading.innerHTML=''
candidateInputForm.innerHTML = ''
displayAddedPost(postName,noOfCandidates,candidateName,candidateImgName)
}
// Function to display added post
function displayAddedPost(postName,noOfCandidates,candidateName,candidateImgName){
let postDiv = `<div class="flex gap-3 p-2 px-3">
<div class="bg-zinc-800 w-fit p-5 rounded-lg">
<h2 class="mb-2 text-lg text-neutral-100 font-semibold">${postName}</h2>
<div class="flex flex-col gap-2 ${postName}-container">
</div>
</div>
</div>`
mainEl.innerHTML+=postDiv
const candidateContainer = document.querySelector('.'+postName+'-container')
for (let i=0;i<noOfCandidates;i++){
candidateContainer.innerHTML+=`<div class="flex">
<p class="input-n-r input-secondary">${candidateName[i]}</p>
<label class="file-upload-btn input-btn btn-secondary-dialog cursor-pointer">
<input type="file" accept=".jpg,.jpeg,.png,.webp" class='candidate-image' required>
<span class="file-name">${candidateImgName[i]}</span>
</label>
</div>`
}
}
// Check post name input
function addPost () {
let postInputVal = postInput.value.trim()
if (checkTextInputEmpty(postInput)) {
showPostError.innerText = "Post name can't be empty.";
}
else if (Number(numberInput.value) < 2) {
showPostError.innerText = 'No. of candidatess should be at least 2.';
}
else {
candidateInfoFormHeading.innerHTML=`For the post of ${postInputVal}`
addCandidateInfo(Number(numberInput.value),postInputVal)
createPostDialog.showModal();
showPostError.innerText = '';
}
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="./css/output.css" rel="stylesheet">
<script type="text/javascript" src="/eel.js" defer></script>
<script src="./js/passwd.js" type="module"></script>
<script src="./js/data_handle.js" type="module"></script>
</head>
<body class="bg-zinc-900">
<header class="flex justify-between px-4 py-3 items-center">
<h1 class="h1">E-Voting | Admin</h1>
<p class="text-neutral-200">Made by Raghav Srivastava</p>
</header>
<dialog id="createPasswd" class="w-full max-w-xl p-8 rounded-xl">
<div class="flex flex-col gap-2">
<h3 class="dialog-heading" id="passwdHeading">Create an Admin password</h3>
<input type="password" placeholder="Password" class="input input-secondary input-passwd" required>
<input type="password" placeholder="Confirm" class="input input-secondary input-passwd" id="confirmPasswd" required>
<div class="flex items-center justify-between gap-2 py-2 flex-wrap">
<div>
<input id="showPasswd" type="checkbox" class="w-fit">
<label for="showPasswd" class="pl-2 text-neutral-300">Show password</label>
</div>
<span id="showPasswdError" class="error"></span>
</div>
<button type="submit" class="btn btn-primary input-btn" id="passwdSubmit">Submit</button>
</div>
<!-- </div> -->
</dialog>
<main class="main">
<!-- <div class="add_post flex justify-center items-center flex-col gap-2">
<div class="flex justify-center">
<input type="text" class="input-n-r post-input input-normal" placeholder="Enter post name">
<input type="number" placeholder="No. of candidates" class="input-n number-input input-normal">
<button class="btn-primary add-post-btn input-btn">Add post</button>
</div>
<span id="showPostError" class="error"></span>
</div>
<div class="flex gap-3 p-2 px-3">
<div class="bg-zinc-800 w-fit p-5 rounded-lg">
<h2 class="mb-2 text-lg text-neutral-100 font-semibold">Post Name</h2>
<div class="flex flex-col gap-2">
<div class="flex">
<p class="input-n-r input-secondary">Raghav Srivastava</p>
<label class="file-upload-btn input-btn btn-secondary-dialog cursor-pointer">
<input type="file" accept=".jpg,.jpeg,.png,.webp" class='candidate-image' required>
<span class="file-name">thanos.png</span>
</label>
</div>
<div class="flex">
<p class="input-n-r input-secondary">Raghav Srivastava</p>
<label class="file-upload-btn input-btn btn-secondary-dialog cursor-pointer">
<input type="file" accept=".jpg,.jpeg,.png,.webp" class='candidate-image' required>
<span class="file-name">thanos.png</span>
</label>
</div>
<div class="flex">
<p class="input-n-r input-secondary">Raghav Srivastava</p>
<label class="file-upload-btn input-btn btn-secondary-dialog cursor-pointer">
<input type="file" accept=".jpg,.jpeg,.png,.webp" class='candidate-image' required>
<span class="file-name">thanos.png</span>
</label>
</div>
</div>
</div>
</div> -->
</main>
</body>
</html>
I tried to add the event listener by calling a function, but still the problem persisted.