Javascript function not looping properly over items - javascript

This is my JS that adds evenet listeners to every ideanode:
var ideanodes = [...document.querySelectorAll('.ideanode')];
ideaNodesListRefresh();
function ideaNodesListRefresh(){
ideanodes = [...document.querySelectorAll('.ideanode')];
console.log("refreshed")
ideanodes.forEach(ideanode => {
var maintxt = ideanode.querySelector(".maintext");
var titleArrow = ideanode.querySelector(".title-arrow");
var mainArrow = ideanode.querySelector(".maintxt-arrow");
var comments = ideanode.querySelector(".comments");
titleArrow.addEventListener('click', function() {
maintxt.classList.toggle("hidden");
mainArrow.classList.toggle("hidden");
if (comments.classList.contains("hidden")) {;
} else {
comments.classList.toggle("hidden");
};
});
mainArrow.addEventListener("click", function() {
comments.classList.toggle("hidden");
});
});
};
the function gets fired at the end of the creation of a new ideanode:
function createNeed(user) {
if (user==user1) {
var newNeed = document.createElement('div');
newNeed.className = "ideanode";
var newNeedHeader = document.createElement('div');
newNeedHeader.className = "ideanodeheader";
var newNeedHeaderText = document.createTextNode('Need');
newNeedHeader.appendChild(newNeedHeaderText);
newNeed.appendChild(newNeedHeader);
var newNeedContent = document.createElement('div');
newNeedContent.className = "content";
newNeed.appendChild(newNeedContent);
var needTitle = document.createElement('div');
needTitle.className="title";
var needTitleH3 = document.createElement('h2');
var titleText = document.createTextNode('Title');
needTitleH3.appendChild(titleText);
needTitleH3.setAttribute('onclick', 'this.focus();');
needTitleH3.setAttribute('contenteditable', 'True');
newNeedContent.appendChild(needTitleH3);
var downArrow0 = document.createElement('i');
downArrow0.classList = 'fas fa-sort-down title-arrow';
newNeedContent.appendChild(downArrow0);
var maintext = document.createElement('div');
maintext.classList = 'maintext hidden';
textareaMain = document.createElement("textarea");
textareaMain.className = "maintextinput";
textareaMain.setAttribute('placeholder', 'Text');
maintext.appendChild(textareaMain);
newNeedContent.appendChild(maintext);
var downArrow1 = document.createElement('i');
downArrow1.classList = 'fas fa-sort-down maintxt-arrow hidden';
newNeedContent.appendChild(downArrow1);
var comments = document.createElement('div');
comments.classList = "comments hidden";
textareaComments = document.createElement("textarea");
textareaComments.className = "commentsinput";
textareaComments.setAttribute('placeholder', 'Comments');
comments.appendChild(textareaComments);
newNeedContent.appendChild(comments);
newNeed.appendChild(newNeedContent);
var container = document.querySelector('#needsuser1');
var lastNeed = document.querySelector(".ideanode:last-child");
lastNeed.parentNode.insertBefore(newNeed, lastNeed.nextSibling);
ideaNodesListRefresh();
} else {
console.log("user2")
}
}
But when I add a new ideanode the function doesn't work properly and the eventlisteners only work for the newest ideanode.
This is a codepen of what I'm doing: https://codepen.io/ricodon1000/pen/PoPeXJL
I would like to simply add eventlisteners to the arrows of the new ideanode and have all of the arrows of all of the ideanodes work.

Related

how to make div on html on js?

I try create a modal box for my Extention.
I have a html5 code
<dialog>
<p>Window</p>
<button id="close">Close</button>
</dialog>
<button id="show">Open Modal Box</button>
and JS code
var dialog = document.querySelector('dialog');
document.querySelector('#show').onclick = function() {
dialog.show();
};
document.querySelector('#close').onclick = function() {
dialog.close();
};
But in my Extention not run my code
function Window_app(){
var myDiv = document.createElement('dialog');
var myP = document.createElement ('p')
var myPText = document.createTextNode("Это окно, которое сделано на html5 и javascript");
var buttonClose = document.createElement('button');
buttonClose.id = ('close');
var buttonShow = document.createElement('button');
buttonShow.id = ('show');
var dialog = document.querySelector('dialog');
document.querySelector('#show').onclick = function() {
dialog.show();
};
document.querySelector('#close').onclick = function() {
dialog.close();
};
}
How make html code in js ?
add a html container to store everything, and then create elements and append them accordingly by referencing them
function Window_app() {
var dialog = document.createElement('dialog');
var myP = document.createElement('p')
var myPText = document.createTextNode("Это окно, которое сделано на html5 и javascript");
var buttonClose = document.createElement('button');
buttonClose.id = ('close');
buttonClose.appendChild(document.createTextNode("закрыть"));
var buttonShow = document.createElement('button');
buttonShow.appendChild(document.createTextNode("открыть"));
buttonShow.id = ('show');
myP.appendChild(myPText);
var container = document.querySelector('#dialog-container');
dialog.appendChild(myP);
container.appendChild(dialog);
dialog.appendChild(buttonClose);
container.appendChild(buttonShow);
buttonShow.onclick = function() {
dialog.show();
};
buttonClose.onclick = function() {
dialog.close();
};
}
Window_app()
<div id="dialog-container"></div>

DOM elements Javascript

I have append
cardBodyButton.addEventListener('click', function(){
listGroup.append(addTodo());
})
and I have a function
var addTodo = function(){
var todoList = document.createElement('li');
todoList.className = "list-group-item d-flex justify-content-between";
todoList.appendChild(document.createTextNode('Todo 5'));
var todoList_a = document.createElement('a');
todoList_a.className = "delete-item";
todoList_a.setAttribute('href','#');
var todoList_a_i = document.createElement('i');
todoList_a_i.className = "fa fa-remove";
todoList_a.append(todoList_a_i);
todoList.append(todoList_a);
};
I am trying to call function in append but it says undefined. What is wrong here?

Access parent object property of image element

I have a list of cats. Each cat object has a property cat.clicks that record the number of times the cat image has been clicked. The cat image's onclick calls the method cat.clickCat.
But of course 'this' in the clickCat method refers to the image element and not the cat object which contains the property 'clicks'.
How do I display and update the number of clicks on the image?
function Cat(src, name) {
this.src = src;
this.name = name;
this.clicks = 0; //property recording no. of clicks
}
Cat.prototype.createCatItem = function() {
let catDisplay = document.createElement("div");
catDisplay.id = "catDisplay"
let catName = document.createElement("h2");
let catImg = document.createElement("img");
let catCounter = document.createElement("div");
catCounter.id = "clicker";
catName.innerHTML = this.name;
catImg.src = this.src;
catImg.onclick = this.clickCat; //call the clickCat method
catDisplay.appendChild(catName);
catDisplay.appendChild(catImg);
catDisplay.appendChild(catCounter);
return catDisplay;
}
Cat.prototype.clickCat = function() {
this.clicks += 1; //how to access the object property clicks from this method?
let clickerDiv = document.getElementById("clicker")
clickerDiv.innerHTML = ''
clickerDiv.innerHTML = 'clicks = ' + this.clicks;
}
function App() {
this.cats = [];
}
App.prototype.add = function(cat) {
this.cats.push(cat)
}
App.prototype.listCats = function() {
let container = document.getElementById("container");
let ul = document.createElement("ul");
for (let i=0; i<this.cats.length; i++){
let li = document.createElement("li");
li.innerHTML = this.cats[i].name;
li.onclick = this.displayCat;
ul.appendChild(li);
}
container.appendChild(ul);
}
App.prototype.displayCat = function() {
let container = document.getElementById("container");
let catDisplay = document.getElementById("catDisplay")
let cats = app.cats;
let chosenCat = cats.filter(cat => cat.name === this.innerHTML);
let chosenCatItem = chosenCat[0].createCatItem();
container.removeChild(catDisplay);
container.appendChild(chosenCatItem);
console.log(chosenCat);
}
App.prototype.showFirstCat = function() {
let container = document.getElementById("container");
let catDisplay = document.getElementById("catDisplay")
let firstCat = app.cats[0].createCatItem();
container.appendChild(firstCat);
}
let app = new App;
let tea = new Cat("http://placehold.it/350x150", "tea");
let snowball = new Cat("http://placehold.it/350x200", "snowball");
let triksy = new Cat("http://placehold.it/350x300", "triksy");
let vera = new Cat("http://placehold.it/350x350", "vera");
let jon = new Cat("http://placehold.it/350x400", "jon");
app.add(tea)
app.add(snowball)
app.add(triksy)
app.add(vera)
app.add(jon)
app.listCats();
app.showFirstCat();
<div id="container">
<h1>My Cat Clicker</h1>
</div>
First of all .. beware of using this ... this always refer the object currently responsible to execute the scripts in browser ... so in your case the image is responsible for executing the click event and it has no property called clicks .. and that's why clicks is NaN
A good practice is preserve this into a variable to avoid the system replacement when executing (that=this)
Cat.prototype.createCatItem = function() {
let that=this; //preserving this value
let catDisplay = document.createElement("div");
catDisplay.id = "catDisplay"
let catName = document.createElement("h2");
let catImg = document.createElement("img");
let catCounter = document.createElement("div");
catCounter.id = "clicker";
catName.innerHTML = this.name;
catImg.src = this.src;
catImg.onclick = function() {
//alert(this);
that.clicks += 1; //how to access the object property clicks from this method?
let clickerDiv = document.getElementById("clicker")
clickerDiv.innerHTML = ''
clickerDiv.innerHTML = 'clicks = ' + that.clicks;
}
catDisplay.appendChild(catName);
catDisplay.appendChild(catImg);
catDisplay.appendChild(catCounter);
return catDisplay;
}
//Cat.prototype.clickCat = function() {
// this.clicks += 1; //how to access the object property clicks from this method?
// let clickerDiv = document.getElementById("clicker")
// clickerDiv.innerHTML = ''
// clickerDiv.innerHTML = 'clicks = ' + this.clicks;
//}

How can I remove unwanted piece of HTML markup on the page?

I have trouble with this piece of code. When I click it once, all is good and the behavior is as designed , but when I click it more than once, then there is all bunch of HTML that appears in the div (text area). How should I revise my JS to make it not happen?
HTML :
<div id="transcriptText">Lorem ipsum dolor sit amet </div>
<br>
<div id="divideTranscript" class="button"> Transform the Transcript! </div>
JS :
window.onload = function() {
var transcriptText = document.getElementById("transcriptText");
var newTranscript = document.createElement("div");
var divideTranscript = document.getElementById("divideTranscript");
divideTranscript.onclick = EventHandler;
function EventHandler() {
changeText();
}
function changeText() {
var sArr = transcriptText.innerHTML.split(" ");
transcriptText.innerHTML = "";
console.log(sArr);
var count = 0;
for (var i = 0; i < sArr.length; i++) {
var item = sArr[i];
var newSpan = document.createElement("span");
var newText = document.createTextNode(item);
var dotNode = document.createTextNode(" ");
newSpan.id = "word" + i;
var mouseOverFunction = function () {
this.style.backgroundColor = 'yellow';
};
newSpan.onmouseover = mouseOverFunction;
var mouseOutFunction = function () {
this.style.backgroundColor = '';
};
newSpan.onmouseout = mouseOutFunction;
newSpan.appendChild(newText);
newSpan.appendChild(dotNode);
transcriptText.appendChild(newSpan);
count++;
};
}
};
Here is it live http://jsfiddle.net/b94DG/1/
The main problem is that you use the innerHTML property instead of the .textContent property each time.
Here is an improved version of changeText() that doesn't matter how many times you run it:
function changeText() {
var sArr = transcriptText.textContent.split(/\s+/g); // changed
transcriptText.innerHTML = "";
var count = 0;
for (var i = 0; i < sArr.length; i++) {
var item = sArr[i];
if (!item) continue; // changed: don't add spans for empty strings
var newSpan = document.createElement("span");
var newText = document.createTextNode(item);
var dotNode = document.createTextNode(" ");
newSpan.id = "word" + i;
var mouseOverFunction = function () {
this.style.backgroundColor = 'yellow';
};
newSpan.onmouseover = mouseOverFunction;
var mouseOutFunction = function () {
this.style.backgroundColor = '';
};
newSpan.onmouseout = mouseOutFunction;
newSpan.appendChild(newText);
newSpan.appendChild(dotNode);
transcriptText.appendChild(newSpan);
count++;
};
}

How to run a nested javascript function?

I am new to object orientated programming in javascript and am trying to understand some functions in a project I am working on.
How would I call/run the internal function (the one listed 'this.getFieldset = function() {') to execute?
function Fieldset() {
this.id = "";
this.content = document.createElement("DIV");
this.content.id = "content";
this.title = "Title";
this.getFieldset = function() {
var div = document.createElement("DIV");
div.id = this.id;
var span = document.createElement("SPAN");
var fieldset = document.createElement("DIV");
fieldset.id = "fieldset";
var header = document.createElement("DIV");
header.id = "header";
span.appendChild(document.createTextNode(this.title));
header.appendChild(span);
div.appendChild(header);
div.appendChild(this.content);
div.appendChild(fieldset);
return div;
}
}
var myFieldset = new Fieldset();
myFieldset.getFieldset();
First you should create an instance of Fieldset, then you'll be able to call its functions (called methods):
var myFieldset = new Fieldset();
myFieldset.getFieldset();
function Fieldset() {
this.id = "";
this.content = document.createElement("DIV");
this.content.id = "content";
this.title = "Title";
this.getFieldset = function() {
var div = document.createElement("DIV");
div.id = this.id;
var span = document.createElement("SPAN");
//var fieldset = document.createElement("DIV");
//fieldset.id = "fieldset";
var header = document.createElement("DIV");
header.id = "header";
span.appendChild(document.createTextNode(this.title));
header.appendChild(span);
div.appendChild(header);
div.appendChild(this.content);
div.appendChild(fieldset);
window.alert("test");
return div;
}
//add call to run function
this.getFieldset();
}

Categories

Resources