I'm having a strange problem. I'm trying to make a program that will add and delete div's inside another div called "body". To add divs, I use document.getElementById("body").innerHTML. Adding works fine. However, in the deleting function, I replace the "body" id with a variable with the id of the div that will be deleted. But when I run the code, I get the error "cannot set innerHTML of null". I tried to replace the id variable with a fixed local variable, and it worked fine. I also tried to add quotes to the variable but that didn't work either. Is there any reason why I can't set the id to a changing variable? Thanks.
Here is my code:
var i = 1;
function myFunction() {
var addDiv = document.getElementById("body2");
addDiv.innerHTML += "<div id = '" + i + "'><br><textarea id = '1' > foo < /textarea></div > ";
i++;
}
function myFunction2() {
var deleteDiv = document.getElementById(i);
deleteDiv.innerHTML = "";
i--;
}
<div id="body2">
<div id="0">
<textarea id="text">lol</textarea><button onclick="myFunction()">Add</button>
<button onclick="myFunction2()">Delete</button>
</div>
</div>
you are incrementing i after adding a div so you must use i-1 while deleting to get correct id.
var i = 1;
function myFunction() {
var addDiv = document.getElementById("body2");
addDiv.innerHTML += "<div id = '"+i+"'><br><textarea id = '1'>foo</textarea></div>";
i++;
}
function myFunction2() {
var deleteDiv = document.getElementById(i-1);
deleteDiv.remove();
i--;
}
<div id = "body2">
<div id = "0">
<textarea id = "text">lol</textarea><button onclick =
"myFunction()">Add</button>
<button onclick = "myFunction2()">Delete</button>
</div>
</div>
To remove last child, you can even use CSS selector last-child. You should also add specific class to newly added divs as you would want to remove only newly added divs.
This will also remove dependency of i.
As an addon, you can also use document.createElement + Node.appendChild instead of setting innerHTML. .innerHTMl will be expensive for highly nested structure.
function myFunction() {
document.getElementById("body2").appendChild(getDiv());
}
function getDiv(i){
var div = document.createElement('div');
div.classList.add('inner')
var ta = document.createElement('textarea');
ta.textContent = 'foo';
div.appendChild(ta);
return div;
}
function myFunction2() {
var div = document.querySelector('#body2 div.inner:last-child')
div && div.remove()
}
<div id="body2">
<div id="0">
<textarea id="text">lol</textarea><button onclick="myFunction()">Add</button>
<button onclick="myFunction2()">Delete</button>
</div>
</div>
You can refer "innerHTML += ..." vs "appendChild(txtNode)" for more information.
Related
I was trying to append some dynamically created html. It throws an error while using getElementById. .audit-table-element is a div in DOM with that particular class.
<div class="audit-table-element"></div>
Javascript :
var elems = document.getElementsByClassName('audit-table-element');
for(var i = 0; i < elems.length; i++) {
elems[i].getElementById("always-audit-table" + category.id + "")
.getElementsByTagName("tbody")[0]
.insertAdjacentHTML("beforeend", auditTableRow);
}
Error - TypeError: elems[i].getElementById is not a function
When I remove the line getElementById("always-audit-table" + category.id + ""), appending is working, but gets appended at the wrong place. So i need to have that line for the HTML to be appended at the right place
You can use querySelector instead of getElementById. Your code should be like below.
elems[i].querySelector("[id = always-audit-table" + category.id + "]")
.getElementsByTagName("tbody")[0]
.insertAdjacentHTML("beforeend", auditTableRow);
querySelector : These are used to select HTML elements based on their id, classes, types, attributes, values of attributes, etc.
Click here to learn more about querySelector
I don't know how your code looks like, but i try to create one example here. have a look to this, your doubts will be cleared out
var testRow = "<tr><td>Data 1</td><td>Data 2</td></tr>";
var ele = document.getElementsByClassName('test');
for(var i = 0; i < ele.length; i++){ debugger;
ele[i].querySelector("[id = id"+i+"]").getElementsByTagName("tbody")[0].insertAdjacentHTML("beforeend", testRow);
}
<div class='test'>
<div id='id0'>
<table><tbody></tbody></table>
</div>
</div>
<div class='test'>
<div id='id1'>
<table><tbody></tbody></table>
</div>
</div>
I need your help to solve a problem I have.
I have this code:
<div id="div1" >
<div id="edit1">
hello
<input type="button" id="b1" onclick="aaa()"/>
</div>
</div>
I want to use insert into the internal div (id=edit1) another new div I generated.
I tried alike code but it's not running:
js:
function aaa()
{
var elem = createDivLine();
var el1 = document.getElementById("div1");
var el2 = el1.getElementById("edit1");
el2.appendChild(elem);
}
function createDivLine()
{
var tempDiv1 = document.createElement("div");
tempDiv1.innerHTML = "Sam";
return tempDiv1;
}
The result should looks like this:
<div id="div1" >
<div id="edit1">
hello
<input type="button" id="b1" onclick="createDivTable()"/>
<div>"Sam"</div>
</div>
</div>
JSFiddle: http://jsfiddle.net/KknXF/
Since IDs are unique, it is not valid to attempt to get an element's children by ID.
Remove this line:
var el1 = document.getElementById('div1');
And change the following line to:
var el2 = document.getElementById('edit1');
In the event that you have some irrepairably (I can never spell that word...) broken HTML that you can't possibly change, try this:
var el2 = document.querySelector("#div1 #edit1");
It should be
function aaa() {
var elem = createDivLine();
var el2 = document.getElementById("edit1");
el2.appendChild(elem);
}
Demo: Fiddle
Goal:
If there are any html syntax code or data inside of
<div id="feedEntries"></div>
Then everything should be removed and be contained empty only.
Problem:
What syntax do I need in order to remove every code and data inside of
<div id="feedEntries"></div>
Please remember that i don't want to add any class or id inside of "feedEntries"
<h3>Search</h3>
<div class="content">
<form>
<input type="text" width="15" value="searchword" id="searchTermTextField"><input type="button" name="some_name" value="Sök" id="searchButton">
</form>
<div id="feedEntries">
</div>
</div>
function fetchSearchResults(json) {
var feedEntriesDivElement = document.getElementById('feedEntries');
var ulElement = document.createElement('ul');
if (feedEntriesDivElement.children.length >= 0)
{
// Syntax code to remove the code/data
}
for (var i = 0; i < json.responseData.results.length; i++)
{
var liElement = document.createElement('li');
var personText = document.createTextNode(json.responseData.results[i].titleNoFormatting);
var newlink = document.createElement('a');
newlink.setAttribute('href', json.responseData.results[i].url );
newlink.appendChild(personText);
liElement.appendChild(newlink);
ulElement.appendChild(liElement);
}
feedEntriesDivElement.appendChild(ulElement);
}
Using pure DOM and Javascript (sometimes considered better than altering innerHTML):
if ( feedEntriesDivElement.hasChildNodes() )
{
while ( feedEntriesDivElement.childNodes.length >= 1 )
{
feedEntriesDivElement.removeChild( feedEntriesDivElement.firstChild );
}
}
feedEntriesDivElement.innerHTML = ''; should do the trick.
you can use jquery like this $('#feedEntries').empty()
to remove from javascript please check the post
document.getElementByIf('feedEntries').innerHTML = ''
I'm trying to get this JavaScript working:
I have an HTML email which links to this page which contains a variable in the link (index.html?content=email1). The JavaScript should replace the DIV content depending on what the variable for 'content' is.
<!-- ORIGINAL DIV -->
<div id="Email">
</div>
<!-- DIV replacement function -->
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
<!-- Email 1 Content -->
<script ="text/javascript">
var content = '<div class="test">Email 1 content</div>';
ReplaceContentInContainer('Email1',content);
}
</script>
<!-- Email 2 Content -->
<script ="text/javascript">
var content = '<div class="test">Email 2 content</div>';
ReplaceContentInContainer('Email2',content);
}
</script>
Any ideas what I've done wrong that is causing it not to work?
Rather than inserting the element as text into innerHTML create a DOM element, and append it manually like so:
var obj = document.createElement("div");
obj.innerText = "Email 2 content";
obj.className = "test"
document.getElementById("email").appendChild(obj);
See this working here: http://jsfiddle.net/BE8Xa/1/
EDIT
Interesting reading to help you decide if you want to use innerHTML or appendChild:
"innerHTML += ..." vs "appendChild(txtNode)"
The ReplaceContentInContainer calls specify ID's which are not present, the only ID is Email and also, how are the two scripts called, if they are in the same apge like in the example the second (with a corrected ID) would always overwrite the first and also you declare the content variable twice which is not permitted, multiple script blocks in a page share the same global namespace so any global variables has to be named uniquely.
David's on the money as to why your DOM script isn't working: there's only an 'Email' id out there, but you're referencing 'Email1' and 'Email2'.
As for grabbing the content parameter from the query string:
var content = (location.search.split(/&*content=/)[1] || '').split(/&/)[0];
I noticed you are putting a closing "}" after you call "ReplaceContentInContainer". I don't know if that is your complete problem but it would definitely cause the javascript not to parse correctly. Remove the closing "}".
With the closing "}", you are closing a block of code you never opened.
First of all, parse the query string data to find the desired content to show. To achieve this, add this function to your page:
<script type="text/javascript">
function ParseQueryString() {
var result = new Array();
var strQS = window.location.href;
var index = strQS.indexOf("?");
if (index > 0) {
var temp = strQS.split("?");
var arrData = temp[1].split("&");
for (var i = 0; i < arrData.length; i++) {
temp = arrData[i].split("=");
var key = temp[0];
var value = temp.length > 0 ? temp[1] : "";
result[key] = value;
}
}
return result;
}
</script>
Second step, have all possible DIV elements in the page, initially hidden using display: none; CSS, like this:
<div id="Email1" style="display: none;">Email 1 Content</div>
<div id="Email2" style="display: none;">Email 2 Content</div>
...
Third and final step, in the page load (after all DIV elements are loaded including the placeholder) read the query string, and if content is given, put the contents of the desired DIV into the "main" div.. here is the required code:
window.onload = function WindowLoad() {
var QS = ParseQueryString();
var contentId = QS["content"];
if (contentId) {
var source = document.getElementById(contentId);
if (source) {
var target = document.getElementById("Email");
target.innerHTML = source.innerHTML;
}
}
}
How about this? Hacky but works...
<!-- ORIGINAL DIV -->
<div id="Email"></div>
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
var txt = document.createTextNode(content);
container.appendChild(txt);
}
window.onload = function() {
var args = document.location.search.substr(1, document.location.search.length).split('&');
var key_value = args[0].split('=');
ReplaceContentInContainer('Email', key_value[1]);
}
</script>
I want my code to instead of creating two texts with my newly created span, i want it to say"Some text x2" and then x3 and so on.
Heres my code
<div>
<li id="myLi">
Some text (This is where i want my other text to be instead)
</li>
</div>
<td class="add" onmousedown="myFunction()">Add</td>
When i click the td, it adds to the li but when i click several times it just comes more text. I want it to say "Some text x2" instead.
function myFunction() {
var proc = document.createElement("SPAN");
var t = document.createTextNode("Some new text.");
proc.appendChild(t);
document.getElementById("myLi").appendChild(proc);
}
Thanks
As Mike said, you can do this with an innerHTML.
If I understand, what you want is :
var i =0;
function doStuff(){
var proc = "<span> my text instead x"+i + "</span>" ;
document.getElementById("myLi").innerHTML = proc;
i++;
}
<div>
<li id="myLi">
<p> something </p>
</li>
<div>
<button onclick="doStuff()"> CLICK ME </button>
How about this piece?
var globalCounter = 1;
function myFunction(){
var current = document.getElementById("myLi");
current.innerHTML = "Some Text x"+globalCounter;
globalCounter++;
}
http://jsbin.com/munukadama/edit?html,js,output
Note you will be using global counter. If you want to avoid global conflicts, either come up with unique variable name, or encapsulate within a class as a private variable (see below).
function MyClass(){
var counter = 1;
this.update = function(){
var current = document.getElementById("myLi");
current.innerHTML = "Some Text x"+counter;
counter++;
};
}
var myInstance = new MyClass();
And then button will become:
<button onClick="myInstance.update()">Click me for Class!</button>
Here is a jQuery solution & a jsfiddle to test it out with:
HTML:
<ul>
<li id="myLi">
Some text (This is where i want my other text to be instead)
</li>
</ul>
Add
JavaScript:
function myFunction() {
$('#myLi').html('<span>Some new text.</span>');
}
$('.add').on('click', myFunction);