I have written the code shown below. I am trying to position the element "h45" above the "age". Somehow, it does not work and I get the following error : "The new child element contains the parent." Does anybody know why this happens and how I could fix it? I am new to JavaScript and I dont understand what I am doing wrong. Thank you all in advance!`
var lastName=document.getElementById("lastName");
var firstName=document.getElementById("firstName");
var age= document.getElementById("alter")
age.addEventListener("blur",showage,false);
function showage()
{
if (/[^0-9]/.test(age.value)) {
var h45 = document.createElement("h4");
var txttt = document.createTextNode("Bitte geben Sie nur Nummern ein");
h45.appendChild(txttt);
age.parentNode.appendChild(h45);
h45.insertBefore(h45,age);
h45.style.color = "red";
return false;
}
else {
return true;
}
}
The problem is in this row
h45.insertBefore(h45,age);
You should do something like:
h45.parentNode.insertBefore(age, h45);
you are inserting h45 inside h45
h45.insertBefore(h45,age);
insertBefore Syntax:
var insertedElement = parentElement.insertBefore(newElement, referenceElement);
so your variable age is probably a div container representing an alert and you already have insert h45 inside age with this code line
age.parentNode.appendChild(h45);
The problem in h45.insertBefore(h45,age);
You cannot append the same element inside itself. It'll create cyclic dependency.
h45.parentNode.insertBefore(age, h45);
See Fixed
https://plnkr.co/edit/EDkvssWMAcDV0enT2hL2?p=preview
Related
I have written this code by using some basics. I simply wanted to remove the image that I have created by using the function Generate() by a button. I have written the following code to remove the image generated. Please help me.
Please note that I have linked my button with the function Reset1(). Can someone give me the code to do the following please.
function Generate()
{
var image=document.createElement('img');
var div=document.getElementById('flex-box-gen');
image.src="https://thecatapi.com/api/images/get?format=src&type=gif&size=small"
div.appendChild(image);
}
function Reset1()
{
document.getElementById('Generate').remove();
}
You could either assign an id to your image element and use that to remove in your second function:
function generate() {
var image=document.createElement("img");
image.id = "image-01";
...
}
function reset() {
var image = document.getElementById("image-01");
var parent = image.parentNode;
parent.removeChild(image);
}
Or if there is nothing else in your containing div element you could just empty all elements from it:
function reset() {
document.getElementById("flex-box-gen").innerHTML = "";
}
getElementById will query a DOM element, not a javascript element.
What you can do, supposing you have only one img in your flex-box-gen is:
var imgs = document.querySelectorAll('#flex-box-gen img')
if(imgs.length > 0){
imgs[0].remove();
}
With a null-check in case the image was already removed
image.setAttribute('id',"Generate");
Add this line in generate function.
i want to know why this error is occuring "Uncaught TypeError: Cannot read property 'value' of null"
and where i am going wrong?
function create()
{
var textbox=document.createElement("input");
var para=document.createElement("p");
para.setAttribute("id","p");
textbox.type='text';
textbox.value='asdf';
textbox.setAttribute("id","textbox");
textbox.setAttribute("onblur",document.getElementById('p').innerHTML=document.getElementById('textbox').value);
document.body.appendChild(textbox);
}
Before you've added an element to the DOM, you can't search for it with .getElementById(). That call returns null, and that's what the error is telling you.
It's pointless to do that anyway, since you've already got variables that refer directly to your newly-created elements. edit oh wait, I see what you're trying to do.
First, there's no reason to use .setAttribute() here. Just set properties directly on the DOM nodes you've created. You have to set the "onblur" property to a function:
function create() {
var textbox=document.createElement("input");
var para=document.createElement("p");
para.id = "p";
textbox.type='text';
textbox.value='asdf';
textbox.id = "textbox";
textbox.onblur = function() {
para.innerHTML = textbox.value;
};
document.body.appendChild(textbox);
document.body.appendChild(para);
}
I'll try to tackle some of the problems with your code (in hope that they magically match your HTML):
function create(){
var textbox = document.createElement("input");
var para = document.createElement("p");
para.setAttribute("id", "p");
textbox.type = 'text';
textbox.value='asdf';
textbox.setAttribute("id","textbox");
// The following is a valid way to attach an event handler:
textbox.onblur = function(){
para.innerHTML = document.getElementById('textbox').value);
}
document.body.appendChild(textbox);
}
I've encountered a similar problem before:
"Uncaught TypeError: Cannot read property 'value' of null"
Means that you're probably didn't set an id in order for the function to look for the value, so it can retrieve it.
Example:
<input type='text' />
<div onclick='myfunc()'></div>
function myfunc() {
text = document.getElementById('msg').value;
}
This will return the following error you get.
Correct approach:
<input type='text' id='msg'/>
<div onclick='myfunc()'></div>
function myfunc() {
text = document.getElementById('msg').value;
}
Hope that helps!
ok i was facing the same problem do one thing,the script tab for your javascript file put it at the bottom of the html so that any input in html page comes, can be recognized by the js file ,because javascript will come after the value you want to play with
You should modify the function like so, for it to work.
If you want to use setAttribute then you will have to wrap it in a function for the onBlur event
function create() {
var textbox = document.createElement("input");
var para = document.createElement("p");
para.setAttribute("id", "p");
textbox.type = 'text';
textbox.value = 'asdf';
textbox.setAttribute("id", "textbox");
textbox.setAttribute("onblur", function() {
para.innerHTML = textbox.value;
});
document.body.appendChild(textbox);
}
Or you can checkout the jsfiddle, to see how it works.
It was recommended to check in a previous answer, if the element is null, but in this case it's not needed as you are creating all the elements in the functions, so all elements will exist.
Also what do you plan to do with the paragraph element?
Maybe wrap the input in the paragraph?
If you want you can add the paragraph simply by adding
document.body.appendChild(para);
Edit: Thank you! It works perfectly now. I really appreciate the quick responses!
Relevant jfiddle here.
I have a list of spans, each with unique ids, that I want to be able to modify using a href or input (either will work). I'm only working on one right now trying to get it to work, but it doesn't seem to be getting anywhere. The relevant html is:
<ul>
<li>STR <span id="str">0</span></li>
<br>
<input type='button' onClick="abilUp()" value='increase by 1' />
And the relevant javascript is:
var statVal = 1;
function abilUp() {
var aV = +document.getElementById('str');
aV = aV + statVal;
console.log("str ="+ aV);
}
The button works, and the function is returning an increase in the console, but the actual value within the span isn't changing. I'm pretty sure it's not recognizing 0 as a number, so I've tried using the following:
+document.getElementById('str');
Number(document.getElementById('str'));
parseInt(document.getElementById('str'), 10);
I've also tried using a variable with innerHTML, and it isn't working. I know it's possible, I just don't know what I'm doing wrong. Thanks in advance for any help you can give.
(Edit to fix the parseInt example)
Problem is you are getting the element in variable aV not the value. So you have to get the content in that element and perform operation on that.
Try this
var statVal = 1;
function abilUp() {
var aV = document.getElementById('str');
aV.textContent = (+aV.textContent) + statVal;
console.log("str ="+ aV.textContent);
}
You need to get the actual text of the div by using innerHTML:
var statVal = 1;
function abilUp() {
var aV = +document.getElementById('str').innerHTML;
aV = aV + statVal;
document.getElementById('str').innerHTML= aV;
}
jsFiddle example
function abilUp() {
var aV = document.getElementById('str').innerHTML;
var aV = parseInt(aV);
document.getElementById('str').innerHTML = aV+1;
}
simple get the number by useing innerHTML,
then use parseInt to change from string to number
and return the inner HTML with the number.
here is the Fidder
http://jsfiddle.net/PjG84/8/
I figured I would get fancy and use vanilla JavaScript during a jQuery event. The idea is that on click of a heading, I want to slide up a div (which works) and replace the tag clicked on to a larger heading.
From what I've read around, this can be caused by the parentNode referencing an element that's not the actual parent, but after checking it appears to be selecting the element that's directly above it.
So... here's the code!
HTML (in Jade)
.policy-container
h6.policy-heading Policies
.policy-list
.content-we-are-hiding
.not-actually-important
jQuery
$('.policy-heading').click(function() {
var self = this;
if (this.classList.contains('closed')) {
$(this).next().slideDown(300);
this.parentNode.replaceChild(self, '<h6 class="policy-heading">Policies</h6>');
} else {
$(this).next().slideUp(300);
this.parentNode.replaceChild(self, '<h2 class="policy-heading closed">Policies</h2>');
}
});
Everything seems pretty standard. Luckily I can just take care of this with jQuery, however I'd rather be using vanilla JS here. Any ideas why this isn't working?
As has been pointed out, replaceChild takes two nodes.
The following will work with native JS wrapped inside jQuery, as you've specified:
$('.policy-heading').click(function () {
var self = this,
h2 = document.createElement('h2'),
h6 = document.createElement('h6');
h2.class = "policy-heading closed";
h2.innerHTML = "Policies";
h6.class = "policy-heading";
h6.innerHTML = "Policies";
if (this.classList.contains('closed')) {
$(this).next().slideDown(300);
this.parentNode.replaceChild(h6, self);
} else {
$(this).next().slideUp(300);
this.parentNode.replaceChild(h2, self);
}
});
replaceChild takes two nodes, you are giving it a node and a string.
It looks like you'd be much better off just sticking with jQuery and using toggle functions for the sliding and class change.
try this :
.click(function(this)
you also need some debugging to understand what is going on I would advice you to use :
console.log(this)
use this :
el = document.createElement('h6');
el.class = "policy-heading";
el.innerHTML = "Policies";
this.parentNode.replaceChild(self, el);
As everyone pointed out, .replaceChild accepts two DOM elements, rather than the string like I was using. I also had its arguments backwards, the first is for the new element, the second is the replaced element.
Example code that works
$('.policy-container').on('click', '.policy-heading', function() {
var self = this,
newElement;
if (this.classList.contains('closed')) {
newElement = document.createElement( 'h6' );
newElement.classList.add('policy-heading');
newElement.innerHTML = 'Policies';
} else {
newElement = document.createElement( 'h2' );
newElement.classList.add('policy-heading');
newElement.classList.add('closed');
newElement.innerHTML = 'Policies';
}
$(this).next().slideDown(300, function() {
self.parentNode.replaceChild( newElement, self );
});
});
I have been strugling with this for a while and I am sure there is a simple answer to this. What happens is I remove a div called "payment" then dynamicaly create it again so I can add to it. That then gets repeated as the infomation that needs to be added to it changes.
I have mangaged to get this so far.
function clearPage()
{
var d = document.getElementById("contain");
var d_nested = document.getElementById("payment");
var deleteNode = d.removeChild(d_nested);
}
function createPayment()
{
payment = document.createElement("div");
payment.id = "mine";
document.getElementById("contain").appendChild(payment);
}
function printOnPage()
{
var x = names.length;
for( var i = 0 ; i < x ; i++ )
{
var para = document.createElement("p");
var paymentDiv = document.getElementById("payment");
paymentDiv.appendChild(para);
var txtName = document.createTextNode("Item: ");
para.appendChild(txtName);
var txtNameArray = document.createTextNode(names[i]);
para.appendChild(txtNameArray);
var txtQty = document.createTextNode(" Qty: ");
para.appendChild(txtQty);
var txtQtyArray = document.createTextNode(qty[i]);
para.appendChild(txtQtyArray);
var txtCost = document.createTextNode(" Cost: ");
para.appendChild(txtCost);
var txtCostArray = document.createTextNode(prices[i]);
para.appendChild(txtCostArray);
}
}
Related HTML
<div id="contain">
<p>Payment</p>
<div id="payment">
<br />
</div>
</div>
It needs the ID of payment for both my CSS rules and for my creating the text that goes in it.
This is the error I get in FireFox
Error: paymentDiv is null Source File:
http://itsuite.it.brighton.ac.uk/ks339/sem2/javascript/js.js Line: 76
Hope someone can provide some insight in to this and please tell me if I am completly off!
Thanks
Edit: Is it easior to clear the div rather than delete it, how would I go about doing such a thing?
In create_payment(), you set the ID to 'mine'. Shouldn't it be 'payment'?
I do not understand your requirements very well, but anyway you cannot create multiple items in the page using the same id attribute, if you want to duplicate an item and still have control over it, you should be using class instead.
Try switching your code into jquery it will be cleaner and easier to understand for you & me.
Your problem is the fact that in createPayment() you're setting the id to 'mine':
payment.id = "mine";
while later on in printOnPage() you're looking for the element using id 'payment':
var paymentDiv = document.getElementById("payment");
As you mention in your edit, it is far easier just to clear the div than to remove it, specially if you still need it later.
To clear a DIV-block just set it's content to empty:
document.getElementById('payment').innerHTML = "";
I hope you find a solution! Good luck!