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/bootstrap#5.0.2/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 = '';
Related
I developing comment section for my HTMl page. I place it in div container in body section in my page, like that:
<body>
...
<div id='commentsTree'></div>
...
</body>
Commment section generated by script, here it is
function createCommentsTree(commentsData) {
resultHTML = "";
let commentsArray = JSON.parse(commentsData);
//let result = "";
resultHTML = resultHTML + "<ul id='myUL'>";
commentsArray.forEach(element => {
if (element.hasOwnProperty("subordinates")){
resultHTML = resultHTML + "<li>" +
"<span class='caret'></span><textarea class='textFieldRoot'>" + element.content + "</textarea>" +
"<div align='right'>" +
"<button>Save</button>" +
"<button>Answer</button>" +
"<button>Delete</button>" +
"</div>";
createCommentsTreeHyerarchycally(element);
resultHTML = resultHTML + "</li>";
}
else{
resultHTML = resultHTML + "<li>" +
"<textarea class='textField'>" + element.content + "</textarea>" +
"<div align='right'>" +
"<button>Save</button>" +
"<button>Answer</button>" +
"<button>Delete</button>" +
"</div>" +
"</li>";
}
});
resultHTML = resultHTML + "</ul>";
return resultHTML;
}
function createCommentsTreeHyerarchycally(source) {
resultHTML = resultHTML + "<ul class='nested'>";
source.subordinates.forEach(element => {
if (element.hasOwnProperty("subordinates")){
resultHTML = resultHTML + "<li>" +
"<span class='caret'></span><textarea class='textFieldRoot'>" + element.content + "</textarea>" +
"<div align='right'>" +
"<button>Save</button>" +
"<button>Answer</button>" +
"<button>Delete</button>" +
"</div>";
createCommentsTreeHyerarchycally(element);
resultHTML = resultHTML + "</li>";
}
else{
resultHTML = resultHTML + "<li>" +
"<textarea class='textField'>" + element.content + "</textarea>" +
"<div align='right'>" +
"<button>Save</button>" +
"<button>Answer</button>" +
"<button>Delete</button>" +
"</div>" +
"</li>";
}
})
resultHTML = resultHTML + "</ul>";
}
in result i have hyerarchycally comments tree, you can see it on example here
https://jsfiddle.net/Obliterator/wogurs6L/, or, on picture "comment section" added below.
On picture you can see "caret" symbol, looks like black small arrow near textareas, i mark it on picture. When i click it, comment line must unfold, and show subordinate comment lines. You can try it in example here https://jsfiddle.net/Obliterator/wogurs6L/, in this example it works totally correct. But, in my web page, when i click on "caret" symbol, nohing happens, comment line do not unfold. And this is a problem.
For unfold by clicking "caret" symbol i make this script and css:
script:
var toggler = document.getElementsByClassName("caret");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("caret-down");
});
}
css:
/* Remove default bullets */
ul, #myUL {
list-style-type: none;
}
.textFieldRoot {
position: relative;
left: 15px;
width: 100%;
}
.textField {
position: relative;
width: 100%;
}
/* Remove margins and padding from the parent ul */
#myUL {
margin: 0;
padding: 0;
}
/* Style the caret/arrow */
.caret {
cursor: pointer;
user-select: none; /* Prevent text selection */
position: absolute;
}
/* Create the caret/arrow with a unicode, and style it */
.caret::before {
content: "\25B6";
color: black;
display: inline-block;
margin-right: 6px;
vertical-align: top;
}
/* Rotate the caret/arrow icon when clicked on (using JavaScript) */
.caret-down::before {
transform: rotate(90deg);
}
/* Hide the nested list */
.nested {
display: none;
}
/* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */
.active {
display: block;
}
i add css and script in my page, for which i trying add comment section, that way (treeListScript.js and treeListStyle.css):
<head>
...
<script type="text/javascript" src="http://localhost/testapp/lib/others/treeList/treeListScript.js"></script>
<link rel="stylesheet" href="http://localhost/testapp/lib/others/treeList/treeListStyle.css">
...
</head>
<body>
...
<div id='commentsTree'></div>
...
</body>
i create my web page this way:
var windowTask = window.open("http://localhost/testapp/site/windows/formTask.html", "taskForm");
windowTask.onload = function(){
windowTask.document.getElementById("formTitle").innerText = "Task " + selectedRow.taskID;
windowTask.document.getElementById("taskID").value = selectedRow.taskID;
windowTask.document.getElementById("title").value = selectedRow.title;
windowTask.document.getElementById("status").value = selectedRow.status;
windowTask.document.getElementById("creator").value = selectedRow.creator;
windowTask.document.getElementById("responsible").value = selectedRow.responsible;
windowTask.document.getElementById("description").value = selectedRow.description;
windowTask.document.getElementById("dateCreation").value = selectedRow.dateCreation;
windowTask.document.getElementById("dateStart").value = selectedRow.dateStart;
windowTask.document.getElementById("dateFinish").value = selectedRow.dateFinish;
var comments = getCommentsTree(selectedRow.taskID, 'task');
windowTask.document.getElementById('commentsTree').innerHTML = createCommentsTree(comments);
line windowTask.document.getElementById('commentsTree').innerHTML = createCommentsTree(comments); creates comment section.
So, what i am doing wrong, what i mus do for my unfold fucntional works correct on my web page? If something unclear, ask, i try explain.
I solve problem by myself. Reason is i just incorrect add event handler to the .caretelements, i add it as script in head section, but i need to add it after i generate comment section, this way:
//creating new HTML page +++
var windowTask = window.open("http://localhost/testapp/site/windows/formTask.html", "taskForm");
windowTask.onload = function(){
windowTask.document.getElementById("formTitle").innerText = "Task " + selectedRow.taskID;
windowTask.document.getElementById("taskID").value = selectedRow.taskID;
windowTask.document.getElementById("title").value = selectedRow.title;
windowTask.document.getElementById("status").value = selectedRow.status;
windowTask.document.getElementById("creator").value = selectedRow.creator;
windowTask.document.getElementById("responsible").value = selectedRow.responsible;
windowTask.document.getElementById("description").value = selectedRow.description;
windowTask.document.getElementById("dateCreation").value = selectedRow.dateCreation;
windowTask.document.getElementById("dateStart").value = selectedRow.dateStart;
windowTask.document.getElementById("dateFinish").value = selectedRow.dateFinish;
//creating new HTML page ---
//creating comment section +++
var comments = getCommentsTree(selectedRow.taskID, 'task');
windowTask.document.getElementById('commentsTree').innerHTML = createCommentsTree(comments);
//creating comment section ---
//adding event handler +++
var toggler = windowTask.document.getElementsByClassName("caret");
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("caret-down");
});
}
//adding event handler ---
now everything works fine. If anyone spend some time for my question, thx.
I am trying to get array elements(which may be objects) in alert onclick. But, message is not binding on click.
this.openLink() method not getting alert for message and correct value.
I am missing something here while binding click events?
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function myBox(){
this.create = (id, id3 , arrData) => {
var html = "<div id='box1' class='col-12'></div>";
$("#box").append(html);
var html1 = "<div id='box2' class='col-12'></div>";
$("#box").append(html1);
this.createList(id, id3 , arrData)
}
this.createList = (id, id3 , arrData) =>{
var html = '';
html +='<ul id="' + id + '_List" class="col-12 rmpm" style="overflow-x:scroll;overflow-y:hidden;list-style- type:none;white-space:nowrap;font-size:0;padding: 0px 0px 10px 0px;">';
for (var i = 0; i < arrData.length; i++) {
var iD = id + '_utt' + i;
html += '<li id="' + iD + '" class="col-12 rmpm" style="display:inline;width:auto;border:1px solid #ccc;display:inline-block;font-size:14px;padding: 5px;border-radius: 5px;margin: 10px 10px 10px 0px; cursor: pointer;">';
html += arrData[i];
html += '</li>';
}
html += '</ul>';
$(id3).append(html);
// ---> here, some error for binding click event on li
arrData.forEach((element) => {
$(document).on('click', '#' + iD, () => {
this.openLink(element);
});
});
}
this.openLink = (message) =>{
alert(message); //a,b,c,as,bqsq,csqs <--- alert expecting here
}
}
</script>
<script>
function abc(){
var arrData = ['a','b','c'];
var arrData2 = ['as','bqsq','csqs'];
var bx = new myBox();
bx.create('arrData',"#box1" , arrData);
bx.create('arrData2',"#box2" , arrData2);
}
</script>
</head>
<body>
<button onclick="abc()">Clcik</button>
<div id="box" style=""></div>
</body>
</html>
You are assembling the id, in the for loop above your foreach, then you are using that id to set the clicklistener, you need to assemble the correct id at every loop in the foreach or else you will only put a listener on the last button.
Change your forEach to this:
arrData.forEach((element, index) => {
var clickId = id + '_utt' + index;
$(document).on('click', '#' + clickId, () => {
this.openLink(element);
});
});
To put it into the html as an onclick="function()" you need to assign it in the first loop when you are creating the HTML. and move openlink outside myBox()
function myBox() {
this.create = (id, id3, arrData) => {
var html = "<div id='box1' class='col-12'></div>";
$("#box").append(html);
var html1 = "<div id='box2' class='col-12'></div>";
$("#box").append(html1);
this.createList(id, id3, arrData)
}
this.createList = (id, id3, arrData) => {
var html = '';
html += '<ul id="' + id + '_List" class="col-12 rmpm" style="overflow-x:scroll;overflow-y:hidden;list-style- type:none;white-space:nowrap;font-size:0;padding: 0px 0px 10px 0px;">';
for (var i = 0; i < arrData.length; i++) {
var iD = id + '_utt' + i;
html += '<li ' + 'onclick="openLink(\'' + arrData[i] + '\')" id="' + iD + '" class="col-12 rmpm" style="display:inline;width:auto;border:1px solid #ccc;display:inline-block;font-size:14px;padding: 5px;border-radius: 5px;margin: 10px 10px 10px 0px; cursor: pointer;">';
html += arrData[i];
html += '</li>';
}
html += '</ul>';
$(id3).append(html);
}
}
openLink = (message) => {
alert(message); //a,b,c,as,bqsq,csqs <--- alert expecting here
}
function abc() {
var arrData = ['a', 'b', 'c'];
var arrData2 = ['as', 'bqsq', 'csqs'];
var bx = new myBox();
bx.create('arrData', "#box1", arrData);
bx.create('arrData2', "#box2", arrData2);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<body>
<button onclick="abc()">Clcik</button>
<div id="box" style=""></div>
</body>
' + 'onclick="openLink(\'' + arrData[i] + '\')" . How does this worked. Can you please explain or provide some link so that I can understand
The line renders as onclick="openLink('a')" onclick="openLink( renders to the DOM as written. the \' renders a ' in the DOM and javascript sees it as a character that way i dont break the string, but it renders as a ' in the DOM. Then i add arrData[i] that is the n'th (or i'th) index in the array. then i use the same trick to close the onclick function off.
class Storedata {
constructor(name, desc, price, qty) {
this.name = name;
this.desc = desc;
this.price = price;
this.qty = qty;
}
}
var arr = [];
var btnform = document.getElementById('clicktoadd');
var btnlist = document.getElementById('clicktoshow');
var rem = document.getElementById('main');
var cancelform;
var submit;
function addData() {
var proname = document.getElementById("inpname");
var prodesc = document.getElementById("inpdesc");
var propric = document.getElementById("inpprice");
var proqty = document.getElementById("inpqty");
arr.push(new Storedata(proname.value, prodesc.value, propric.value, proqty.value));
}
function showlist() {
var data = document.createElement('table');
data.setAttribute("id", "data");
data.innerHTML += "<tr><th>Product Name</th><th>Description</th><th>Price</th><th>Quantity</th><th></th></tr>";
for (let i = 0; i < arr.length; i++) {
data.innerHTML += ("<tr><td>" + arr[i].name + "</td><td>" + arr[i].desc + "</td><td>" + arr[i].price + "</td><td>" + arr[i].qty + "</td><td><button id=\"delete" + i + "\">Delete</button></tr>");
};
document.getElementById('listing').appendChild(data);
document.getElementById('showbutton').removeAttribute("hidden", false);
}
function removelist() {
var data = document.getElementById("data");
data.parentNode.removeChild(data);
}
function addformtopage() {
var form = document.createElement('div');
form.setAttribute("id", "remform");
form.innerHTML += "<div id=\"lblname\">Product Name:</div><input id=\"inpname\" type=\"text\"><div id=\"chkname\" hidden=\"true\">Enter a Product Name</div><div id=\"lbldesc\">Description:</div><textarea id=\"inpdesc\" rows=\"10\" cols=\"35\"></textarea><div id=\"chkdesc\" hidden=\"true\">Enter a Product Desciption</div><div id=\"lblprice\">Price in INR:</div><input id=\"inpprice\" type=\"number\"><div id=\"chkprice\" hidden=\"true\">Enter a Product Price</div><div id=\"lblqty\">Quantity:</div><input id=\"inpqty\" type=\"number\"><div id=\"chkqty\" hidden=\"true\">Enter a Product Quantity</div><br><br><button id=\"submitproduct\">Submit</button><button id=\"cancel\">Cancel</button>";
document.getElementById('panel').appendChild(form);
cancelform = document.getElementById('cancel');
submit = document.getElementById('submitproduct');
}
function validateform() {
var proname = document.getElementById("inpname");
var prodesc = document.getElementById("inpdesc");
var propric = document.getElementById("inpprice");
var proqty = document.getElementById("inpqty");
var errname = document.getElementById("chkname");
var errdesc = document.getElementById("chkdesc");
var errpric = document.getElementById("chkprice");
var errqty = document.getElementById("chkqty");
if ((proname.value) && (prodesc.value) && (propric.value) && (proqty.value)) {
errname.setAttribute("hidden", true);
errdesc.setAttribute("hidden", true);
errpric.setAttribute("hidden", true);
errqty.setAttribute("hidden", true);
return true;
}
if (proname.value) {
errname.setAttribute("hidden", true);
}
if (prodesc.value) {
errdesc.setAttribute("hidden", true);
}
if (propric.value) {
errpric.setAttribute("hidden", true);
}
if (proqty.value) {
errqty.setAttribute("hidden", true);
}
if (!proname.value) {
errname.removeAttribute("hidden", false);
}
if (!prodesc.value) {
errdesc.removeAttribute("hidden", false);
}
if (!propric.value) {
errpric.removeAttribute("hidden", false);
}
if (!proqty.value) {
errqty.removeAttribute("hidden", false);
}
return false;
}
function clearform() {
var proname = document.getElementById("inpname");
var prodesc = document.getElementById("inpdesc");
var propric = document.getElementById("inpprice");
var proqty = document.getElementById("inpqty");
proname.value = null;
prodesc.value = null;
propric.value = null;
proqty.value = null;
}
function removeform() {
var elem = document.getElementById("remform");
elem.parentNode.removeChild(elem);
}
function removebuttons() {
rem.setAttribute("hidden", true);
}
function showbuttons() {
rem.removeAttribute("hidden", false);
}
btnform.addEventListener('click', function() {
addformtopage();
removebuttons();
cancelform.addEventListener('click', function() {
showbuttons();
removeform();
});
submit.addEventListener('click', function() {
if (validateform()) {
alert("Values Added");
addData();
clearform();
}
});
});
btnlist.addEventListener('click', function() {
showlist();
removebuttons();
document.getElementById('showbutton').addEventListener('click', function() {
showbuttons();
removelist();
document.getElementById('showbutton').setAttribute("hidden", "true");
});
});
#chkname,
#chkdesc,
#chkprice,
#chkqty {
color: red;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 70%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<!DOCTYPE HTML>
<html>
<head>
<link href="style.css" rel="stylesheet" />
<title>
JS Form
</title>
</head>
<body>
<div id="main">
<p><button id="clicktoadd">Add Product</button> <button id="clicktoshow">Show List</button></p>
</div>
<div id="panel">
</div>
<div id="listing">
</div>
<button id="showbutton" hidden="true">< Back</button>
<script src="script.js"></script>
</body>
</html>
I want to take input in form for description of the item as formatted text. And then output it in the same format as input, but right now I am getting text separated by space where should be there. Please help..
Steps to perform
1. Run this code snippet.
2. Click on 'Add Product' button.
3. Fill the form (For testing give a description of more than one line) and Submit.
4. Click on 'Cancel' button to return.
5. Click on 'Show List' button.
6. Observe Description column.
This is output I am getting separated by spaces
This is form input I am providing
Well, you have two options. Add a <pre> tag:
for (let i = 0; i < arr.length; i++) {
data.innerHTML += ("<tr><td>" + arr[i].name + "</td><td><pre>" + arr[i].desc + "</pre></td><td>" + arr[i].price + "</td><td>" + arr[i].qty + "</td><td><button id=\"delete" + i + "\">Delete</button></tr>");
};
This way it will display the new lines and you keep your string clean.
Or you can replace the new lines with <br> this way:
for (let i = 0; i < arr.length; i++) {
data.innerHTML += ("<tr><td>" + arr[i].name + "</td><td>" + arr[i].desc.replace(/\n/g, "<br>") + "</td><td>" + arr[i].price + "</td><td>" + arr[i].qty + "</td><td><button id=\"delete" + i + "\">Delete</button></tr>");
};
Remember that the new lines are not shown by default in HTML, if you want a new line put a <br>
Test it online
Hope it helps! :)
Add this into your code:
var text = arr[i].desc;
text = text.replace(/\n/g, '<br />');
JSfiddle
See JavaScript: How to add line breaks to an HTML textarea? too.
I have a ribbon button to execute custom workflow. this action a setup from JavaScript and it worked perfectly. In this case I wanna show progress loading when after click or during custom workflow execution.
I just followed the tutorial HERE. this my javascript function code:
function showLoadingMessage() {
try{
tdAreas.style.display = 'none';
var newdiv = document.createElement('div');
newdiv.setAttribute('id', "msgDiv");
newdiv.valign = "middle";
newdiv.align = "center";
var divInnerHTML = "<table height='100%' width='100%' style='cursor:wait'>";
divInnerHTML += "<tr>";
divInnerHTML += "<td valign='middle' align='center'>";
divInnerHTML += "<img alt='' src='/_imgs/AdvFind/progress.gif'/>";
divInnerHTML += "<div/><b>Working…</b>";
divInnerHTML += "</td></tr></table>";
newdiv.innerHTML = divInnerHTML;
newdiv.style.background = '#FFFFFF';
newdiv.style.fontSize = "15px";
newdiv.style.zIndex = "1010";
newdiv.style.width = document.body.clientWidth;
newdiv.style.height = document.body.clientHeight;
newdiv.style.position = 'absolute';
document.body.insertBefore(newdiv, document.body.firstChild);
document.all.msgDiv.style.visibility = 'visible';
}
catch(ex){
alert(ex.message);
}
}
and this one is to hide progress:
function hideLoadingMessage(){
document.all.msgDiv.style.visibility = 'hidden';
}
this is the function that I called in my ribbon button action for testing loading progress work or not:
function ribbonButton()
{
var guid = Xrm.Page.data.entity.getId();
if (guid != null)
{
showLoadingMessage(); //show progress
/*var workflowId = '04E84379-87E4-E711-814E-000C294D2FF8';
var workflowName = 'CloneReward';
ExecuteWorkflow(workflowId, workflowName, function ()
{
RefreshForm();
});*/
//hideLoadingMessage(); //hide progress
}
}
when I pressed the button I get the following error message:
Need any suggestions. Thanks.
There is new nice client API for exact this feature: https://learn.microsoft.com/en-us/dynamics365/customer-engagement/developer/clientapi/reference/xrm-utility/showprogressindicator
Here is example on how it looks in work: http://www.itaintboring.com/dynamics-crm/dynamics-365-v9-progress-indicator-api/
The only downside is that it's only applicable to Dynamics version 9.
just tried this THIS tutorial and it will fix the problem above.
show loading progress:
function _buildLoadingDiv(_entityName) {
var loadingDiv = "<div id='divLoading'style='width: 100%; height: 100%; display: block; position: fixed; top:0px; background:rgba(255,255,255,0.5);'><table style='width: 100%; height: 100%;'><tr><td align='center' style='vertical-align: middle;'>";
loadingDiv += "<img id='loading' alt='' src='/_imgs/AdvFind/progress.gif'/><br/>";
loadingDiv += "<label id='lblStatus'>Loading... " + _entityName + " Execute Workflow</label>";
loadingDiv += "</td></tr></table></div>";
$($('body', window.parent.document)).append(loadingDiv);
}
hide loading progress:
function _removeLoading() {
$($('body', window.parent.document)).find("#divLoading").remove();
}
I'm taking in a csv file, which includes the test value 'Iñtërnâtiônàlizætiøn' and outputting it to a simple HTML table using JavaScript.
The table displays the output as I�t�rn�ti�n�liz�ti�n. I've been looking on the web and have tried the suggestions of changing font & also charset (tried UTF-8, UTF-16, windows-1252, iso 8859-1 & iso 8859-5) but nothing works.
It's a drag and drop that takes in the csv and changes it into an HTML table on the webpage and uses xml to output a word document of the same table.
Sorry, I should have said:- There is no PHP on this page, it all takes place in the local browser, hence JavaScript. Also, I don't have control over the coding of the files being used or the settings in the user's browser. Most of my users are going to be making this file in excel, I suspect.
Here is the code:
<div id="drop_zone">Drop files here</div>
<output id="list"></output>
<script type="text/javascript" >
var URLadd = "My url here";
var OutString = [];
var TestFunc = [];
function handleFileSelect(evt) { // function 1 bracket
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files; // FileList object.
// files is a FileList of File objects. List some properties.
var output = [];
oForm = document.forms[0];
oText = oForm.elements["Inst"];
var InstCode = oText.value;
if (InstCode == "")
{
InstCode = "<b>Please enter your institution code</b>";
}
for (var i = 0, f; f = files[i]; i++) { // loop 1
if (f.name.match('\.csv')) { // if 1
// this part is for when a csv file is drag n dropped
var Filename = decodeURI(escape(f.name));
var reader = new FileReader();
// when the file loads, the function beneath is run
reader.onload = (function(theFile) { // function 2
// this function is executed before it is returned, by the last parenthesis (f)
return function(e) { //function 3
var contents = e.target.result;
var FileLines = contents.split( "\n" );
var LineCount = FileLines.length;
OutString = '<table id="mytab" border="1" width="100%"><tr>';
var ColCount = 1;
for (var i=1; i<LineCount; ++i)
{ // loop 2
if (ColCount>4)
{ColCount=0;}
if(ColCount==0)
{ // if 2
OutString += '</tr><tr>';
ColCount = 1;
} // close if 2
OutString += '<td width=25%>';
var CommaSplit = FileLines[i].split(",");
var CommaCount = CommaSplit.length;
if (CommaCount == 5)
{ // if 3
OutString += "<strong> " + CommaSplit[0] + " " + CommaSplit[1] + "</strong><br>";
OutString += "Username: " + CommaSplit[3] + "<br>Password: " + CommaSplit[3];
OutString += "<br>Institution Code: " + InstCode + "<br>" + URLadd;
ColCount += 1;
} else { // else of if 3
for (var j= 0; j<CommaCount; ++j)
{ // loop 3
OutString += CommaSplit[j] + '<br>';
ColCount += 1;
} // close loop 3
} //close if 3
OutString += '</td>';
} // close loop 2
OutString += '</tr></table>';
TestFunc = '<html xmlns:v="urn:schemas-microsoft-com:vml" ';
TestFunc += 'xmlns:o="urn:schemas-microsoft-com:office:office" ';
TestFunc += 'xmlns:w="urn:schemas-microsoft-com:office:word" ';
TestFunc += 'xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" ';
TestFunc += 'xmlns="http://www.w3.org/TR/REC-html40">';
TestFunc += '<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta><title>Passwords Doc</title>';
TestFunc += '<style>v\:* {behavior:url(#default#VML);}o\:* {behavior:url(#default#VML);}w\:* {behavior:url(#default#VML);}.shape behavior:url(#default#VML);}</style>';
TestFunc += '<style>#page{mso-page-orientation: landscape; size:29.7cm 21cm; margin:0cm 0cm 0cm 0cm;}';
TestFunc += '#page Section1 {mso-header-margin:0in; mso-footer-margin:0in; mso-header: h1; mso-footer: f1; }';
TestFunc += ' div.Section1 { page:Section1; }';
TestFunc += 'table#mytab{ margin: 0.2in 0.2in 0.2in 0.2in; width:0px; height:0px; overflow:hidden;}';
TestFunc += '</style><xml><w:WordDocument><w:View>Print</w:View><w:Zoom>100</w:Zoom><w:DoNotOptimizeForBrowser/>';
TestFunc += '</w:WordDocument></xml></head><body><div class="Section1">';
TestFunc += OutString;
TestFunc += '</div></body></html>';
var OutPutLine = "<a href='data:application/msword;charset=UTF-8, " + encodeURIComponent(TestFunc) + "' download='" + decodeURIComponent(escape('Login Slips.doc')) + "' ><input id='Button1' type='button' value='Open printable sheet' /></a>";
output.push(OutPutLine);
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
var span = document.createElement('span');
span.innerHTML = [OutString].join('');
document.getElementById('list').insertBefore(span, null);
}; // close function 3
})(f); // close function 2
reader.readAsText(f);
// this creates the button that opens the finished document
//var OutPutLine = "<a href='WordTemplate.doc' ><input id='Button1' type='button' value='Open printable sheet' /></a>";
output.push(OutPutLine);
} else { // else of if 1
// this triggers if its not a csv file that drag n drops
output.push('<strong>', escape(f.name), ' is not a comma seperated (.csv) file!!!!</strong>');
} // close if 1
} // close loop 1
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
} // close function 1
function handleDragOver(evt) { // function 4
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
} // close function 4
// Setup the dnd listeners.
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
</script>