I have a drop down which builds a form based of the selections that are selected. So, if someone selects 'foobar', it displays a text field, if they choose 'cheese', it displays radio buttons. The user can then enter data into these forms as they go along. The only problem is that when they add a new form element, all the rest of the information is erased. Im currently using the following to do add to the form:
document.getElementById('theform_div').innerHTML =
document.getElementById('theform_div').innerHTML + 'this is the new stuff';
How can I get it to keep whatever has be enetered in the form and also add the new field to the end?
Setting innerHTML destroys the contents of the element and rebuilds it from the HTML.
You need to build a separate DOM tree and add it by calling appendChild.
For example:
var container = document.createElement("div");
container.innerHTML = "...";
document.getElementById("theform_div").appendChild(container);
This is much easier to do using jQuery.
Step One:
Add jQuery to your headers:
<script type=”text/javascript” src=”http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js”></script>
Step Two:
Append, don't replace, data to your DIV like this:
$("#theform_div").append("your_new_html_goes_here");
Don't use innerHTML to create the form elements. With innerHTML you're overwriting the old HTML with new HTML which will recreate all the elements. Instead you need to use the DOM to create and append the elements.
EXAMPLE
function addRadioElement()
{
var frm = document.getElementById("form_container");
var newEl = document.createElement("input");
newEl.type = "radio";
newEl.name = "foo";
newEl.value = "bar";
frm.appendChild(newEl);
}
The most correct way to do it without using a framework (like jQuery, Dojo, YUI) is:
var text = document.createTextNode('The text you want to write');
var div = document.createElement('div');
div.appendChild(text);
document.getElementById('theform_div').appendChild(div);
innerHTML, although supported by most browsers, is not standard compliant and - therefore, not guaranteed to work.
I would suggest using jQuery and its append function.
Related
I found some JQuery solutions, but I am limited by school task restrictions to use pure Javascript, and I need to use specific early appended element that is still not in DOM for replacing by my CKEDITOR.
Code:
function newOption(){
...
mainUL = document.getElementById("myUL");
var inputA = document.createElement("input");
inputA.type ="text";
inputA.style = "margin-right: 45px";
inputA.name = "option[]";
inputA.id = inputID;
mainUL.appendChild(inputA );
CKEDITOR.replace(inputID).setData('Type anything you want ...');
...
}
By replacing my input with CKEDITOR will JS fail, because input, commonly, is still not in DOM. I tried to use
mainUL.innerHTML += "all elements like html text";
and this is working and will immediately insert elements into DOM, but I can't to use innerHTML, because it will remove old listeners (for example checked checkboxes that JS will set from checked to unchecked, what is my main problem due to I have to try using append DOM function).
Try changing the code to wrap the call to CKEDITOR.replace in a setTimeout:
setTimeout(function() {
CKEDITOR.replace(inputID).setData('Type anything you want ...');
},0).
This will allow the browser time to insert the element before trying to replace it.
And I assume that inputID has a valid value in it...
Example:
var buttonHTML = "<button>MyButton</button>";
document.getElementById("myDiv").append(buttonHTML);
In this case, the function ends up appending the text into the div.
However, if I do the same with JQ:
$("#myDiv").append(buttonHTML);
In this case it will actually append the button.
Now, for various reasons, I have to use plain JS (not JQ).
Anyone have any ideas?
I am not sure how it worked with you and appended the element as text here, because there is no .append function in pure JS
But I agree with what #Sam Judge said in his answer,and also want to mention that you can do it using javascript without creating nodes one by one using javascript function Element.insertAdjacentHTML()
insertAdjacentHTML() parses the specified text as HTML or XML and
inserts the resulting nodes into the DOM tree at a specified position.
It does not reparse the element it is being used on and thus it does
not corrupt the existing elements inside the element. This avoiding
the extra step of serialization make it much faster than direct
innerHTML manipulation.
And there is another option to do the same using the .innerHTML but for sure you will need to save what's already inside to do the append effect.
This is because your var buttonHTML is just a string of text, if you append it as a child, it will create a DOM textNode, rather than an elementNode. What you want to do instead is something along the lines of the following :
var buttonHTML = document.createElement("button");
var buttonText = document.createTextNode("MyButton");
buttonHTML.appendChild(buttonText);
document.getElementById("myDiv").appendChild(buttonHTML)
you can try this code
function myFunction() {
var myButton= document.createElement("button");
myButton.style.width = "100px";
myButton.style.height = "30px";
myButton.style.background = "grey";
myButton.style.color = "white";
myButton.innerHTML = "MyButton";
document.getElementById("demo1").appendChild(myButton);
}
<button type="button" onclick="myFunction()">create another button</button>
<p id="demo1"></p>
I'm trying to add a search link to an online form with a userscript using jQuery. I don't work too much in firefox and I feel like things that would normally work in chrome don't in ff 9/10 times for me. But anyway... this needs to be with ff.
I'm taking the text from a <p> element and creating a search url out of it (or trying to). Right now this is the function I'm trying that should be doing it... but it's doing nothing, not even any errors in console
$(function() {
var companyName = $('p')[7]; // Element that contains the name text
var companyText = companyName.text(); // Retrieve the text from element
var mixRankUrl = $("<a></a>").innerHTML("Search Mixrank"); // Create an <a> element
mixRankUrl.href = 'https://mixrank.com/appstore/sdks?search=' + companyText; // Define the href of the a element
var sdkPara = $('label.control-label')[10]; // Where I want it to go
sdkPara.append(mixRankUrl); // Append the element
});
Also, whoever wrote the html uses hardly any ids, and most classes are assigned to 10 or more elements... so unless there's a better way, I'm sort of stuck using node selectors (which stay the same form to form).
The problem is that you try to use jQuery method on DOM element. Don't understand why you don't have any errors with your code.
For exemple : $('p')[7] return a DOM element while $('p').eq(7) return a JQuery object. So you can't use a jQuery method like text() on your DOM element. You need to deal with jQuery object.
For the same reason, you had a problem with the declaration of your label object and with the modification of the href attribute of your link.
Try like this :
$(function() {
var companyName = $('p').eq(7); // Element that contains the name text
var companyText = companyName.text(); // Retrieve the text from element
var sdkPara = $('label.control-label').eq(10); // Where I want it to go
var mixRankUrl = $('<a>',{
text: 'Search Mixrank',
href: 'https://mixrank.com/appstore/sdks?search=' + companyText
}).appendTo(sdkPara); // Append the element
});
I’m using AJAX to append data to a <div> element, where I fill the <div> from JavaScript. How can I append new data to the <div> without losing the previous data found in it?
Try this:
var div = document.getElementById('divID');
div.innerHTML += 'Extra stuff';
Using appendChild:
var theDiv = document.getElementById("<ID_OF_THE_DIV>");
var content = document.createTextNode("<YOUR_CONTENT>");
theDiv.appendChild(content);
Using innerHTML:
This approach will remove all the listeners to the existing elements as mentioned by #BiAiB. So use caution if you are planning to use this version.
var theDiv = document.getElementById("<ID_OF_THE_DIV>");
theDiv.innerHTML += "<YOUR_CONTENT>";
Beware of innerHTML, you sort of lose something when you use it:
theDiv.innerHTML += 'content';
Is equivalent to:
theDiv.innerHTML = theDiv.innerHTML + 'content';
Which will destroy all nodes inside your div and recreate new ones. All references and listeners to elements inside it will be lost.
If you need to keep them (when you have attached a click handler, for example), you have to append the new contents with the DOM functions(appendChild,insertAfter,insertBefore):
var newNode = document.createElement('div');
newNode.innerHTML = data;
theDiv.appendChild(newNode);
If you want to do it fast and don't want to lose references and listeners use: .insertAdjacentHTML();
"It does not reparse the element it is being used on and thus it does not corrupt the existing elements inside the element. This, and avoiding the extra step of serialization make it much faster than direct innerHTML manipulation."
Supported on all mainline browsers (IE6+, FF8+,All Others and Mobile): http://caniuse.com/#feat=insertadjacenthtml
Example from https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
// <div id="one">one</div>
var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');
// At this point, the new structure is:
// <div id="one">one</div><div id="two">two</div>
If you are using jQuery you can use $('#mydiv').append('html content') and it will keep the existing content.
http://api.jquery.com/append/
IE9+ (Vista+) solution, without creating new text nodes:
var div = document.getElementById("divID");
div.textContent += data + " ";
However, this didn't quite do the trick for me since I needed a new line after each message, so my DIV turned into a styled UL with this code:
var li = document.createElement("li");
var text = document.createTextNode(data);
li.appendChild(text);
ul.appendChild(li);
From https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent :
Differences from innerHTML
innerHTML returns the HTML as its name indicates. Quite often, in order to retrieve or write text within an element, people use innerHTML. textContent should be used instead. Because the text is not parsed as HTML, it's likely to have better performance. Moreover, this avoids an XSS attack vector.
Even this will work:
var div = document.getElementById('divID');
div.innerHTML += 'Text to append';
An option that I think is better than any of the ones mentioned so far is Element.insertAdjacentText().
// Example listener on a child element
// Included in this snippet to show that the listener does not get corrupted
document.querySelector('button').addEventListener('click', () => {
console.log('click');
});
// to actually insert the text:
document.querySelector('div').insertAdjacentText('beforeend', 'more text');
<div>
<button>click</button>
</div>
Advantages to this approach include:
Does not modify the existing nodes in the DOM; does not corrupt event listeners
Inserts text, not HTML (Best to only use .insertAdjacentHTML when deliberately inserting HTML - using it unnecessarily is less semantically appropriate and can increase the risk of XSS)
Flexible; the first argument to .insertAdjacentText may be beforebegin, beforeend, afterbegin, afterend, depending on where you'd like the text to be inserted
you can use jQuery. which make it very simple.
just download the jQuery file add jQuery into your HTML
or you can user online link:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
and try this:
$("#divID").append(data);
The following method is less general than others however it's great when you are sure that your last child node of the div is already a text node. In this way you won't create a new text node using appendData MDN Reference AppendData
let mydiv = document.getElementById("divId");
let lastChild = mydiv.lastChild;
if(lastChild && lastChild.nodeType === Node.TEXT_NODE ) //test if there is at least a node and the last is a text node
lastChild.appendData("YOUR TEXT CONTENT");
java script
document.getElementById("divID").html("this text will be added to div");
jquery
$("#divID").html("this text will be added to div");
Use .html() without any arguments to see that you have entered.
You can use the browser console to quickly test these functions before using them in your code.
Why not just use setAttribute ?
thisDiv.setAttribute('attrName','data you wish to append');
Then you can get this data by :
thisDiv.attrName;
I have a drop down which builds a form based of the selections that are selected. So, if someone selects 'foobar', it displays a text field, if they choose 'cheese', it displays radio buttons. The user can then enter data into these forms as they go along. The only problem is that when they add a new form element, all the rest of the information is erased. Im currently using the following to do add to the form:
document.getElementById('theform_div').innerHTML =
document.getElementById('theform_div').innerHTML + 'this is the new stuff';
How can I get it to keep whatever has be enetered in the form and also add the new field to the end?
Setting innerHTML destroys the contents of the element and rebuilds it from the HTML.
You need to build a separate DOM tree and add it by calling appendChild.
For example:
var container = document.createElement("div");
container.innerHTML = "...";
document.getElementById("theform_div").appendChild(container);
This is much easier to do using jQuery.
Step One:
Add jQuery to your headers:
<script type=”text/javascript” src=”http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js”></script>
Step Two:
Append, don't replace, data to your DIV like this:
$("#theform_div").append("your_new_html_goes_here");
Don't use innerHTML to create the form elements. With innerHTML you're overwriting the old HTML with new HTML which will recreate all the elements. Instead you need to use the DOM to create and append the elements.
EXAMPLE
function addRadioElement()
{
var frm = document.getElementById("form_container");
var newEl = document.createElement("input");
newEl.type = "radio";
newEl.name = "foo";
newEl.value = "bar";
frm.appendChild(newEl);
}
The most correct way to do it without using a framework (like jQuery, Dojo, YUI) is:
var text = document.createTextNode('The text you want to write');
var div = document.createElement('div');
div.appendChild(text);
document.getElementById('theform_div').appendChild(div);
innerHTML, although supported by most browsers, is not standard compliant and - therefore, not guaranteed to work.
I would suggest using jQuery and its append function.