Appending htmlfragment to an element - javascript

I am loading json data and displaying them on site inside div.
I decided to store the data inside an htmlfragment using
var docFragment = new DocumentFragment();
function createFullList(){
var aside = document.getElementsByClassName("one")[0];
for( x in obj ){
createInfoElement( docFragment , obj[x].general , obj[x].job );
}
var div = document.createElement("div");
div.appendChild(docFragment);
aside.innerHTML += div;
}
crateInfoElement just creates div and append it to docFragment.
What is troublling me is when i want to append an documentFragment into its supposed holder ( aside variable ).
It does not display all divs inside it instead of it just
[object HTMLDivElement]
I do not have much experience with fragments , but using example from MDN
var ul = document.getElementsByTagName("ul")[0]; // assuming it exists
var docfrag = document.createDocumentFragment();
var browserList = ["Internet Explorer", "Mozilla Firefox", "Safari", "Chrome", "Opera"];
browserList.forEach(function(e) {
var li = document.createElement("li");
li.textContent = e;
docfrag.appendChild(li);
});
ul.appendChild(docfrag);
it does display ul and li elements inside it not just
[object HTMLDivElement]
as in my case. What is causing this behavior?
createInfoElement looks like this
function createInfoElement( parent , name , job ){
var div = document.createElement("div");
div.setAttribute("class","left_info");
var p = document.createElement("p");
p.setAttribute("class","name");
p.innerHTML = name.firstName + " " + name.lasName;
var p_two = document.createElement("p");
p_two.setAttribute("class","job");
p_two.innerHTML = job.title;
div.appendChild(p);
div.appendChild(p_two);
parent.appendChild(div);
}

Related

Create hyperlink with js dom

I'm trying to create a wikipedia viewer, get json data and then show it with a hyperlink that take you to the article. The problem is when I want to give the href attribute to a specific element.
$.getJSON(url1 + search + url2, function(data) {
for(i=0; i<data[1].length; i++) {
var p = document.createElement("P");
var id = p.setAttribute("id", i);
var t = document.createTextNode(data[1][i] + ': ');
var text = document.createTextNode(data[2][i]);
var a = document.getElementById(i);
var link = a.setAttribute("href", data[3][i]);
p.appendChild(t);
p.appendChild(text);
p.appendChild(link);
document.body.appendChild(p);
}
});
So, I'm calling the specific "p" element by Id(i value) and then I append to it the specific url. What am I missing?
It actually doesn't make much sense trying to correct parts of your code. The following is a cleaned up and corrected version of yours. Although it is untested, it should produce a format like <p>data[1][i]: data[2][i]</p>.
$.getJSON(url1 + search + url2, function(data)
{
for(var i = 0; i < data[1].length; ++i)
{
//main element
var p = document.createElement("p");
p.id = "element" + i; //you should not use just numbers as IDs
//preceding description
var t = document.createTextNode(data[1][i] + ': ');
//actual link
var text = document.createTextNode(data[2][i]);
var a = document.createElement("a");
a.href = data[3][i];
a.appendChild(text);
//merge all of them together
p.appendChild(t);
p.appendChild(a);
document.body.appendChild(p);
}
});
You are using
p.appendChild(link);
You should be using:
p.appendChild(link);
I think that's not the only thing wrong, your var a = document.getElementById(i); assumes you have an element in the DOM with ids looking like "1" 'var a = document.createElement(a);
$.getJSON(url1 + search + url2, function(data){
for(i=0; i<data[1].length; i++){
var p = document.createElement("p");
var t = document.createTextNode(data[1][i] + ': ');
var text = document.createTextNode(data[2][i]);
var a = document.getElementById(i);
var link = a.setAttribute("href", data[3][i]);
a.appendChild(t);//put text inside the clickable link
a.appendChild(text);//put additional text inside the clickable link
p.appendChild(a);//put the link inside the <p> element
document.body.appendChild(p);//add the link into the DOM at the end of the body
});
//now your element is a <p>data[1][i]: data[2][i]</p>

refactor a functionwich makes a form

I got a working function, but i think it should become a lot smaller and better but i aint seeing it. can someone help me improve this function make it better:
I am making a new li-item in a unordered list. in there there is omse info in 3 divisions who get a class making them float left to eachother.
this is the code i used, its all listed out, it can probly be make a lot better, and i hope to learn to refactor my code more, so help is apriciated.
// making new li item inn <ul>
function addproduction(){
// getting info from form
var startdatum_form = document.getElementById('startdatum').value;
var uren_form = document.getElementById('uren').value;
var ordernummer_form = document.getElementById('ordernummer').value;
// new li element
var newli = document.createElement('li');
newli.setAttribute('class', 'ui-state-default');
var div1 = document.createElement('div');
div1.setAttribute('class', 'div1');
var sortableicon = document.createElement('span');
sortableicon.setAttribute('class', 'ui-icon ui-icon-arrowthick-2-n-s');
// count current li elements in UL:
var number = 0;
var ullist = document.getElementById('sortable');
for(i=0;i< ullist.childNodes.length;i++){
if(ullist.childNodes[i].nodeName=='LI'){
number++;
}
}
newli.setAttribute('id', 'p'+(number+1));
// text node (item x)
var nrText = document.createTextNode('Item ' + (number+1));
div1.appendChild(sortableicon)
div1.appendChild(nrText);
var div2 = document.createElement('div');
div2.setAttribute('class', 'div1');
var indiv1 = document.createElement('div');
indiv1.appendChild(document.createTextNode('Title'));
var indiv2 = document.createElement('div');
indiv2.appendChild(document.createTextNode('Start'));
var indiv3 = document.createElement('div');
indiv3.appendChild(document.createTextNode('End'));
var indiv4 = document.createElement('div');
indiv4.appendChild(document.createTextNode('Uren'));
div2.appendChild(indiv1);
div2.appendChild(indiv2);
div2.appendChild(indiv3);
div2.appendChild(indiv4);
var div3 = document.createElement('div');
div3.setAttribute('class', 'div3');
var indiv5 = document.createElement('div');
indiv5.appendChild(document.createTextNode(ordernummer_form));
var indiv6 = document.createElement('div');
indiv6.appendChild(document.createTextNode(startdatum_form));
var indiv7 = document.createElement('div');
indiv7.appendChild(document.createTextNode('end'));
var indiv8 = document.createElement('div');
indiv8.appendChild(document.createTextNode(uren_form));
div3.appendChild(indiv5);
div3.appendChild(indiv6);
div3.appendChild(indiv7);
div3.appendChild(indiv8);
newli.appendChild(div1);
newli.appendChild(div2);
newli.appendChild(div3);
// add new production to list
document.getElementById('sortable').appendChild(newli);
saveNewEntry( (number+1), ordernummer_form, startdatum_form, uren_form );
}
A small example which could be applied to other parts of your code as well
var startdatum_form = document.getElementById('startdatum').value;
var uren_form = document.getElementById('uren').value;
var ordernummer_form = document.getElementById('ordernummer').value;
could be
var startdatum_form = get_value('startdatum');
var uren_form = get_value('uren');
var ordernummer_form = get_value('ordernummer');
function get_value( field ) {
return document.getElementById(field).value;
}

After concatenating html elements the result variable return 0

here is my code it return 0 when i call result variable i want to add elements in html without DOM, means i want to re-create this whole html in JS using this code.
var div = document.createElement("div");
div.setAttribute("id", "old");
var newDiv = document.createElement("div");
newDiv.setAttribute("id", "new");
var p = document.createElement("p");
p.setAttribute("id", "paragraph")
var domDiv = document.getElementById("old");
var domNewDiv = document.getElementById("new");
var domP = document.getElementById("paragraph");
var result = domDiv + domNewDiv + domP;
result;
Code in console
document.getElementById returns a Javascript Object. You cannot simply concatenate objects. But you can concatenate the html content of those objects for example:
var result = domDiv.innerHTML + domNewDiv.innerHTML + domP.innerHTML;

Created span in javascript is showing as [object HTMLSpanElement] in webpage

I created a span tag in javascript and using .innerHTML i'm trying to append it into another tag. but in webpage it is showing as [object HTMLSpanElement].
var text = "Accessor Properties Example";
var enteredText = 'Prop';
var data = text.split(enteredText);
var pTag = document.getElementById('ab');
var newSpan = document.createElement('span');
newSpan.setAttribute('class','highlight');
newSpan.innerHTML=enteredText;
console.log(newSpan)
var plainText = data[0]+newSpan+data[1];
pTag.innerHTML = plainText;
.highlight {color:#1a0dab;font-weight:bold}
<p id="ab"></p>
You're trying to insert an object reference into a string. You can get the HTML that represents the span and add the 3 pieces of information together before setting the innerHTML of your target.
var text = "Accessor Properties Example";
var enteredText = 'Prop';
var data = text.split(enteredText);
var pTag = document.getElementById('ab');
var newSpan = document.createElement('span');
newSpan.setAttribute('class','highlight');
newSpan.innerHTML=enteredText;
console.log(newSpan)
var plainText = data[0]+ newSpan.outerHTML +data[1]; // <- Change made here
pTag.innerHTML = plainText;
.highlight {color:#1a0dab;font-weight:bold}
<p id="ab"></p>
That's because you are concatenating strings with a DOM element, which is coerced into a string too.
Instead, you should use appendChild:
pTag.innerHTML = ''; // Remove existing contents
pTag.appendChild(document.createTextNode(data[0]));
pTag.appendChild(newSpan);
pTag.appendChild(document.createTextNode(data[1]));
var text = "Accessor Properties Example",
enteredText = 'Prop',
data = text.split(enteredText),
pTag = document.getElementById('ab'),
newSpan = document.createElement('span');
newSpan.className = 'highlight';
newSpan.textContent = enteredText;
pTag.innerHTML = '';
pTag.appendChild(document.createTextNode(data[0]));
pTag.appendChild(newSpan);
pTag.appendChild(document.createTextNode(data[1]));
.highlight {color:#1a0dab;font-weight:bold}
<p id="ab"></p>

Passing html nodes to a javascript function

I'm new to JavaScript and am trying to create a recursive function that checks if two DOM nodes are equivalent. This function seems to be returning true for everything and isn't checking the DOM the way I want it to for some reason. Only nodes 1 & 4 are equivalent.
var htmlStrings = ['<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>', '<div id="two">Some<span>node contents for</span>comparison</div>', '<div id="one">Some<span>node <strong>contents</strong> for</span>comparison</div>', '<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>'];
var div1 = document.createElement('div');
div1.innerHTML = htmlStrings[0];
document.body.appendChild(div1);
var div2 = document.createElement('div');
div2.innerHTML = htmlStrings[1];
document.body.appendChild(div2);
var div3 = document.createElement('div');
div3.innerHTML = htmlStrings[2];
document.body.appendChild(div3);
var div4 = document.createElement('div');
div4.innerHTML = htmlStrings[3];
document.body.appendChild(div4);
function nodeEquivalence(node1, node2) {
var passed = false;
if (node1.nodeType === node2.nodeType) {
if ((node1.tagName === node2.tagName && node1.nodeValue === node2.nodeValue)) {
passed = true;
}
}
node1 = node1.firstChild;
node2 = node2.firstChild;
while (node1 && node2) {
nodeEquivalence(node1, node2);
node1 = node1.nextSibling;
node2 = node2.nextSibling;
}
return passed;
}
console.log(nodeEquivalence(div1, div2));
console.log(nodeEquivalence(div1, div4));
You're passing strings, not DOM elements. You need to convert the HTML to DOM elements. There are many solutions described at
Creating a new DOM element from an HTML string using built-in DOM methods or prototype
So you can do:
var html1 = '<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>';
var html2 = '<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>';
var html3 = '<div id="one">Some<span>node <b>contents</b> for</span>comparison</div>';
var div1 = document.createElement('div');
div1.innerHTML = html1;
var div2 = document.createElement('div');
div2.innerHTML = html2;
var div3 = document.createElement('div');
div3.innerHTML = html3;
alert(nodeEquivalence(div1.firstChild, div2.firstChild));
alert(nodeEquivalence(div1.firstChild, div3.firstChild));
function nodeEquivalence (node1, node2) {
var passed = true;
function test(node1, node2) {
if ((node1.nodeType === node2.nodeType) && (node1.tagName === node2.tagName || node1.nodeValue === node2.nodeValue) && (node1.childNodes.length === node2.childNodes.length)) {
passed = true;
} else {
passed = false;
}
}
node1 = node1.firstChild;
node2 = node2.firstChild;
while (passed && node1 && node2) {
test(node1, node2);
node1 = node1.nextSibling;
node2 = node2.nextSibling;
}
//test(document.body);
return passed;
};
Use document.createElement(*tagName*)
Here is some documentation.
For example, you'll want to create two elements, pass them both in and see if they're equivalent. And then you can base the same one in twice.
var newDiv = document.createElement("div");
var newSpan = document.createElement("span");
yes, instead of comparing 2 html elements, you are simply comparing 2 strings. And your node1, node2 will always be undefined.
by the way, this following has some nice examples as to how to compare 2 html elements.
How to compare two HTML elements
Most of the relevant part is innerHTML. Most of the information is in there. If the innerHTML of the two HTML nodes are the same, than nearly everything is the same. Than the tagName and for <input> tags the type attribute:
function nodeEquivalence(node1, node2) {
var equal = false;
if (node1.innerHTML === node2.innerHTML) {
if (node1.tagName === node2.tagName) {
if (node1.type === node2.type) {
equal = true;
}
}
}
return equal;
}
I think, this function will catch nearly all cases.
Note that there is a little difference, if you access the node via id or class name:
var el = document.getElementById(id);
el.innerHTML
var el2 = document.getElementsByClassName(className);
el[0].innerHTML;
Also, you can compare by outerHTML. When you give each HTML node the same class name, you will have the exact same thing.
Example
Create a HTML element:
var div = document.createElement("div");
var text = document.createTextNode("some text");
div.appendChild(text);
document.body.appendChild(div);

Categories