Retrieving the hidden input value of an automatically generated parents child? - javascript

I am trying to retrieve the input value of a child element from automatically generated elements in my document in order to use its values but i am having trouble accessing the child, How can i go about doing this? (im very new to JS)
var createCard = function (num, x) {
var div = document.createElement('div');
var classN = "card" + num;
var classX = "card" + x;
div.className += classX;
div.className += " card ";
div.className += classN;
div.style.opacity ="1"
div.addEventListener("click", function (e) {
var div = $(e.target);
var n = div.firstElementChild.value; //here lies the suspected problem
if (div.css('opacity') == "0.3") {
div.css('opacity', "1");
aNum(n);
}
else {
div.css('opacity', "0.3");
mNum(n);
}
});
var worth = document.createElement('input')
worth.setAttribute('type', 'hidden');
worth.setAttribute('value', num);
div.appendChild(worth);
document.getElementById('gameArea').appendChild(div);
};

You can use Jquery to select an element's child.
There's multiple ways to go about this, but I'd suggest checking out Jquery Selectors.
I believe the selector for a child of an element is .children(":first")
So you'd do
var child = $("MyDivSelector").children(":first");

Set the id for the input
worth.setAttribute('id', 'hidworth');
Get the input
var hidWorth=document.getElementById('hidWorth');

Related

Create element until condition is true

I want to create elements inside another element until condition is true.
I have tried this code but it's not working.
// calculate span size and it's parent
var homeHeight = $(".home").height();
var homeWidth = $(".home").width();
var homeSize = (homeHeight + homeWidth) * 2;
var spanHeight = $(".back-animation span").height();
var spanWidth = $(".back-animation span").width();
var spanSize = (spanHeight + spanWidth) * 2;
// create span elements to fill it's parent.
var createSpan = function() {
var span = document.createElement("span");
while (spanSize <= homeSize) {
$(".animation-hide-overflow").append(span);
spanSize = spanSize + spanSize;
}
};
createSpan();
Note: It's combined with JQuery and I recieve no errors in console.
Note 2: I tried for loop like the bottom but it's not working either.
for (spanSize; spanSize <= homeSize; spanSize = spanSize + spanSize) {
$(".animation-hide-overflow").append(span);
}
EDIT:
Thanks for mentioning, I forgot to call createSpan function! now it's working but it create span just once. Any solutions?
jsfiddle for better demonstration:
http://jsfiddle.net/pooria_h/vqmgmyj0/1/
(It should keep creating span elements until it fills up parent element.)
The problem was this section
// create span elements to fill it's parent.
var createSpan = function() {
var span = document.createElement("span");
while (spanSize <= homeSize) {
$(".animation-hide-overflow").append(span);
spanSize = spanSize + spanSize;
}
}
If you pay more attention you can see I've created span variable outside of the loop, So this is what happens: Loop works correctly and it increases spanSize variable until it equals to homeSize variable which is bigger in the start point but the big problem is there isn't a element creation! span element is created before the loop.
So this is the correct way:
// create span elements to fill it's parent.
var createSpan = function() {
while (spanSize <= homeSize) {
var span = document.createElement("span");
$(".animation-hide-overflow").append(span);
spanSize = spanSize + spanSize;
}
}

Div's are being generated dynamically and even the (obj.search) fetches the data but nothing is being displayed in it. How do i display the data?

JS doesn't display the output
for (var i = 0; i < obj.Search.length; i++){
var divTag = document.createElement("div");
divTag.id = "div"+i;
divTag.className = "list";
document.getElementById('div'+i).innerHTML+=obj.Search[i].Title+obj.Search[i].Year;
}
Image here
You missed adding the newly created element to the DOM. Example:
document.getElementById("yourDivContainer").appendChild(divTag);
Fiddle:
http://jsfiddle.net/mbpfgm49/
You need to append your div tags to some element (e.g: body), to make text appear on page
// Let's create some sample data
var obj = {
Search: []
}
var currentYear = (new Date).getFullYear();
for (var i = currentYear - 10; i <= currentYear; i++) {
obj.Search.push({
Title: 'Test',
Year: i
})
}
// Here goes your code fixed
for (var i = 0; i < obj.Search.length; i++) {
var divTag = document.createElement("div");
divTag.id = "div" + i;
divTag.className = "list";
divTag.innerHTML = obj.Search[i].Title + ' ' + obj.Search[i].Year;
document.body.appendChild(divTag);
}
Yes, you have to add the element to the DOM.
More basically, it is an anti-pattern to construct IDs for elements and use those as the primary means for referring to elements, by means of calling getElementById at every turn. I guess this approach is one of the many lingering after-effects of the jQuery epidemic.
Instead, keep references to elements directly in JS where possible, and use them directly:
for (var i = 0; i < obj.Search.length; i++){
var divTag = document.createElement("div");
divTag.className = "list";
parent.appendChild(divTag);
^^^^^^^^^^^^^^^^^^^^^^^^^^ INSERT ELEMENT
divTag.innerHTML+=obj.Search[i].Title+obj.Search[i].Year;
^^^^^^ REFER TO ELEMENT DIRECTLY
}
To be absolutely pedantically correct, what you are creating is not a "tag", it's an "element". The element is the DOM object. The "tag" is the div which characterizes the element type.

How to change text content in DIV (with DOM) to add SPANs elements instead?

I'm confused on how to change text content of div with the DOM. When event is triggered, I see that the new text replace the old but it is in a new div. I want to keep it in "transcriptText" to keep all attributes.`How can I do that?
This is my old div with text inside:
var transcriptText = document.getElementById("transcriptText");
these are my new text SPAN elements
var newTranscript = document.createElement("div");
This is how I handle the event
function EventHandler() {
transcriptText.parentNode.replaceChild(newTranscript, transcriptText);
}
Here is the JSFiddle on how it currently works:
http://jsfiddle.net/b94DG/
What you're doing now is creating a new div, newTranscript, which you create by appending a bunch of spans based on the old text. Then in your event handler you replace the old one with the new one. Instead of that, you could still copy the text from the old one, but then clear it and append the children on the old div, replacing line 36 with:
transcriptText.appendChild(newSpan);
To clear the old element, it might work to just set innerHTML to "", or if necessary you could remove all the children with removeChild as described at https://developer.mozilla.org/en-US/docs/Web/API/Node.removeChild
EDIT:
I modified your fiddle to reflect this:
http://jsfiddle.net/b94DG/1/
You can change the innerHTML of transcriptText instead of creating a new div.
var transcriptText = document.getElementById("transcriptText");
var divideTranscript = document.getElementById("divideTranscript");
divideTranscript.onclick = function() {
var sArr = transcriptText.innerHTML.split(" ");
var newInnerHTML = "";
for (var i = 0; i < sArr.length; i++) {
var item = sArr[i];
var newText = "<span class='highlight' id='word" + i + "'>" + item + " </span>";
newInnerHTML += newText;
}
transcriptText.innerHTML = newInnerHTML;
var mouseOverFunction = function () {
this.style.backgroundColor = 'yellow';
};
var mouseOutFunction = function () {
this.style.backgroundColor = '';
};
var highlight = document.getElementsByClassName("highlight");
for (i = 0; i < highlight.length; i++) {
highlight[i].onmouseover = mouseOverFunction;
highlight[i].onmouseout = mouseOutFunction;
}
};
Here's the fiddle: http://jsfiddle.net/khnGN/

Dynamic div elements and associating events with these div

I am creating dynamically multiple div elements using JavaScript. Below is the code I have used:
for(i=0;i<3;i++)
{
var d1 = document.createElement('div');
d1.id = "div" + i;
var l1 = document.createElement('label');
l1.innerHtml = "Hello";
d1.appendChild(l1);
var line1 = document.createElement('hr');
d1.appendChild(line1);
document.body.appendChild(d1);
}
Output:
Hello
Hello
Hello
Now I want to dynamically append event say onmouseover and onmouseout so that whenever I move cursor over a particular div element say div1, div2 or div3, that respective div section should change color (say blue) and when cursor moves out it should return to its original color.
I have tried working out but I am unable to retrieve the div id's which I have created dynamically.
You don't need to select by ID. You already have the element, so go ahead and add handlers to it.
for(i=0;i<3;i++) {
var d1 = document.createElement('div');
d1.id = "div" + i;
var l1 = document.createElement('label');
l1.innerHtml = "Hello";
d1.appendChild(l1);
var line1 = document.createElement('hr');
d1.appendChild(line1);
document.body.appendChild(d1);
d1.onmouseover = function() {
this.style.color = "#00F";
};
d1.onmouseout = function() {
this.style.color = "";
};
}
Just build your handlers and then assign them in the loop:
var mouseover = function() {
this.style.backgroundColor = '#AAF';
},
mouseout = function() {
this.style.backgroundColor = '';
};
for (i = 0; i < 3; i++) {
var d1 = document.createElement('div'),
l1 = document.createElement('label'),
line1 = document.createElement('hr');
d1.id = "div" + i;
l1.innerHtml = "Hello";
d1.appendChild(l1);
d1.appendChild(line1);
d1.onmouseover = mouseover;
d1.onmouseout = mouseout;
document.body.appendChild(d1);
}​
Demo at: http://jsfiddle.net/vfVCm/
If your elements are created dynamically it may be better to use event delegation and attach the event listener to the parent element instead of every element that you're dynamically creating. This way your listener will work even for elements created after it's attached. DOM events bubble, and an actual target of an event is available as event.target. Here is an example:
<div id="parent">
<p id="event1">A</p>
<p id="event2">B</p>
<p id="event3">C</p>
</div>
// call on DOMContentLoaded
document.getElementById("parent").addEventListener("click", function(e) {
if(e.target && e.target.nodeName.toLowerCase() == "p") {
alert("Clicked element " + e.target.id);
}
});
​
See jsfiddle.

Javascript Replace Child/Loop issue

I have this really bizarre issue where I have a forloop that is supposed to replace all divs with the class of "original" to text inputs with a class of "new". When I run the loop, it only replaces every-other div with an input, but if I run the loop to just replace the class of the div and not change the tag to input, it does every single div, and doesn't only do every-other.
Here is my loop code, and a link to the live version: live version here
function divChange() {
var divs = document.getElementsByTagName("div");
for (var i=0; i<divs.length; i++) {
if (divs[i].className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = divs[i].innerHTML;
var parent = divs[i].parentNode;
parent.replaceChild(textInput, divs[i]);
}
}
}
Because the divs collection is updated when one of its div elements is removed from the DOM, you end up skipping over divs because your i isn't updated with the reindexing of the collection.
A common solution is to iterate in reverse instead.
function divChange() {
var divs = document.getElementsByTagName("div");
for (var i=divs.length - 1; i > -1; i--) {
if (divs[i].className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = divs[i].innerHTML;
divs[i].parentNode.replaceChild(textInput, divs[i]);
}
}
}
Another solution you could use is to copy the live HTMLCollection to an inert array, and use your original logic:
function divChange() {
var divs = document.getElementsByTagName("div");
divs = Array.prototype.slice.call( divs ); //convert to array
for (var i = 0; i < divs.length; i++) {
if (divs[i].className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = divs[i].innerHTML;
var parent = divs[i].parentNode;
parent.replaceChild(textInput, divs[i]);
}
}
}
divChange();
http://jsfiddle.net/2UCZa/1/
Yet another solution is to create an Array from an array-like object, and iterate over this. For example:
var divs = document.getElementsByTagName("div");
Array.from(divs).forEach(function(el) {
if (el.className == 'original') {
var textInput = document.createElement('input');
textInput.className = 'new';
textInput.type = 'text';
textInput.value = el.innerHTML;
var parent = el.parentNode;
parent.replaceChild(textInput, el);
}
});
I like this one the best, as it produces the least amount of code, and is very clear!
I don't know why, but this one seemed to work in the end:
ModalBody.insertAdjacentHTML('afterbegin', loader.outerHTML);
my loader is basically just a new div, but inside of the div there is this loading symbol, which appears when the content is loaded.
var loader = document.createElement('div');
loader.classList.add('loader');
loader.classList.add('is-loading');
loader.classList.add('mt-5');
So with just this line
ModalBody.insertAdjacentHTML('afterbegin', loader);
...while the content was loaded a got [object HTMLDivElement] shown shortly, after 3 sec more or less the right content appeared. As soon as I added this ".outerHTML" things got right. I am still a super beginner. So, maybe someone could also explaine why this worked?

Categories