Javascript Delete Button does not work in editorjs
I am trying to write a mini-blog app, and I am trying to make a button to delete posts, but It doesn't work. It doesn't show any errors. I am confused. What I should do ? How can I tell what's going on to see where is the issue ? I have seen many relevant posts but it doesn't seems to be helpful for my situation.
Here is my code:
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<!-- style file -->
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<!-- editorjs adn -->
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/list@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/checklist@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/quote@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/code@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/table@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/embed@latest"></script>
<!-- CSS -->
<style>
body {
margin: auto;
max-width: 900px;
}
#editor {
border: 1px solid;
}
.inserted_time {
font-style: italic;
font-size: 8px;
text-align: right;
}
</style>
</head>
<body>
<h2>Create a Blog</h2>
<button onclick="toggleBlogForm()" id="switchbutton">Create Post</button>
<div id="allblogs"></div>
<div id="editor"></div>
<div id="conversion"></div>
<button id="post_to_blog">Submit</button>
<div id="message"></div>
<script>
function toggleBlogForm() {
var x = document.getElementById("switchbutton");
if (x.innerHTML == "Create Post") {
x.innerHTML = "View Post";
document.getElementById("allblogs").style.visibility = "hidden";
} else {
x.innerHTML = "Create Post";
}
}
// saved posts
const blogs = [{"time":1641955404060,"blocks":[{"id":"t_39IX2iIH","type":"header","data":{"text":"First Blog Post","level":2}},{"id":"jBunZLMaJC","type":"paragraph","data":{"text":"gogogo"}}],"version":"2.22.2"},{"time":1641955680472,"blocks":[{"id":"fbfQo5o1_y","type":"list","data":{"style":"ordered","items":["ABC","DEF","HIJ"]}}],"version":"2.22.2"},{"time":1641955749893,"blocks":[{"id":"idQrTDXnzJ","type":"checklist","data":{"items":[{"text":"English","checked":true},{"text":"French","checked":false},{"text":"German","checked":false}]}}],"version":"2.22.2"},{"time":1641957539439,"blocks":[{"id":"ztUBHu3HHg","type":"table","data":{"withHeadings":false,"content":[["Category","Language"],["1","Java"],["2","Python"]]}}],"version":"2.22.2"},{"time":1641959106166,"blocks":[{"id":"Q6Z-TKWLup","type":"embed","data":{"service":"youtube","source":"https://youtu.be/tbXpX4dAqjg","embed":"https://www.youtube.com/embed/tbXpX4dAqjg","width":580,"height":320,"caption":"This is a tutorial for learning PHP Symfony framework."}}],"version":"2.22.2"}]
const blog_inserted_time = ["11:43:24 12/1/2022", "11:43:24 12/1/2022", "11:43:24 12/1/2022", "12:18:59 12/1/2022", "12:45:6 12/1/2022"]
// retrieve posts when loading the page
console.log(blogs.length);
loadingPosts();
console.log('retrieved!')
// constructor for the blog
const editor = new EditorJS({
holder: 'editor',
tools: {
header: Header,
list: List,
checklist: Checklist,
quote: Quote,
code: CodeTool,
table: Table,
embed: {
class: Embed,
inlineToolbar: true,
config: {
services: {
youtube: true,
coub: true
}
}
}
}
});
// saving the new post
let saveBtn = document.getElementById('post_to_blog');
saveBtn.addEventListener('click', function() {
editor.save().then((outputData) => {
// save to local variable
const jsondata = outputData;
blogs.push(jsondata);
console.log(blogs);
// get and save time
var currentdate = new Date();
var datetime = currentdate.getHours() + ":"
+ currentdate.getMinutes() + ":"
+ currentdate.getSeconds() + " "
+ currentdate.getDate() + "/"
+ (currentdate.getMonth()+1) + "/"
+ currentdate.getFullYear();
blog_inserted_time.push(datetime);
console.log("inserted time: " + currentdate);
// reload all posts
var divForReset = document.getElementById('allblogs');
while(divForReset.firstChild){
divForReset.removeChild(divForReset.firstChild);
}
loadingPosts();
}).catch((error) => {
console.log('Failed: ', error)
});
});
function loadingPosts() {
for(var i = 0; i < blogs.length; i++) {
var getBlocks = blogs[i]['blocks'];
//console.log('retrieving');
//console.log(getBlocks);
for(var y = 0; y < getBlocks.length; y++) {
console.log('printing text.......');
console.log(getBlocks[y]);
var msg = convertDataToHtml(getBlocks);
console.log(msg);
}
// create a div for a post
var addblog = document.createElement('div');
// get post data from json array
var textmsg = document.createTextNode(msg);
//addblog.appendChild(textmsg);
var addblog = document.createElement('div');
// deleteButton
const deleteButton = document.createElement('button');
deleteButton.innerHTML = 'delete';
addblog.appendChild(deleteButton);
deleteButton.addEventListener('click', evt => {
evt.preventDefault();
alert('it does not work!!!');
});
// get time
addblog.innerHTML += "<p class='inserted_time'>"+blog_inserted_time[i]+"</p>";
// get post
addblog.innerHTML += msg;
addblog.style.cssText = "border: 1px solid; padding: 10px";
document.getElementById('allblogs').appendChild(addblog);
msg = '';
}
}
function convertDataToHtml(blocks) {
var convertedHtml = "";
blocks.map(block => {
switch (block.type) {
case "header":
convertedHtml +=
`<h${block.data.level}>${block.data.text}</h${block.data.level}>`;
break;
case "embed":
convertedHtml += `<div><iframe width="560" height="315" src="${block.data.embed}" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>`;
convertedHtml += `<p>${block.data.caption}</p></div>`;
break;
case "paragraph":
convertedHtml += `<p>${block.data.text}</p>`;
break;
case "delimiter":
convertedHtml += "<hr />";
break;
case "image":
convertedHtml += `<img class="img-fluid"
src="${block.data.file.url}" title="${block.data.caption}" /><br />
<em>${block.data.caption}</em>`;
break;
case "list":
convertedHtml += "<ul>";
block.data.items.forEach(function(li) {
convertedHtml += `<li>${li}</li>`;
});
convertedHtml += "</ul>";
break;
case "checklist":
convertedHtml += "<ul>";
block.data.items.forEach(function(li) {
if (li["checked"] == true) {
convertedHtml += `<ol>✓ ${li["text"]}
</ol>`;
} else {
convertedHtml += `<ol>
${li["text"]}</ol>`;
}
});
convertedHtml += "</ul>";
break;
case "table":
convertedHtml += "<table class='table table-striped table-hover'>";
block.data.content.forEach(function(tdata) {
convertedHtml += "<tr>";
for (a = 0; a < tdata.length; a++) {
convertedHtml += "<td>" + tdata[a] + "</td>";
}
convertedHtml += "</tr>";
});
convertedHtml += "</table>";
break;
case "code":
convertedHtml += `<code>${block.data.code}</code>`;
default:
console.log("Unknown block type", block.type);
break;
}
});
return convertedHtml;
}
</script>
</body>
</html>
The issue with your code is that you're first appending the deleteButton
element with the click
event listener to the addBlog
element and then using innerHTML
to append further content to addBlog
.
Using innerHTML this way will remove any previously defined event listener:
Please note that using innerHTML to append html elements (e.g. el.innerHTML += "link") will result in the removal of any previously set event listeners. That is, after you append any HTML element that way you won't be able to listen to the previously set event listeners.
A way to solve the issue is retrieving the button and adding the event listener after any DOM manipulation has been completed (adding a unique id
to any delete button will help):
// create a div for a post
const addblog = document.createElement('div');
// deleteButton
const deleteButton = document.createElement('button');
deleteButton.setAttribute('id', 'deleteBtn_' + i);
deleteButton.setAttribute('type', 'button');
deleteButton.innerHTML = 'delete';
addblog.appendChild(deleteButton);
// get time
addblog.innerHTML +=
"<p class='inserted_time'>" + blog_inserted_time[i] + '</p>';
// get post
addblog.innerHTML += msg;
addblog.style.cssText = 'border: 1px solid; padding: 10px';
document.getElementById('allblogs').appendChild(addblog);
// Add event listener at least
document
.getElementById('deleteBtn_' + i)
.addEventListener('click', function (evt) {
evt.preventDefault();
alert('it does work!!!');
});
msg = '';