What is the proper method to append elements in elements in javascript - javascript

I am using vanilla javascript for my tiny weather project.
I have a problem with appending elements(which are created in run-time) in element.
Following HTML structure is my goal structure.
<div>
Min Temp <span class="small-font"> °C </span>
Max Temp <span class="small-font"> °C </span>
</div>
const div = document.createElement('div');
const span = document.createElement('span');
div.append("Min Temp", span, "Max Temp", span);
and my result is this:
<div>
Min Temp
Max Temp <span class="small-font"> °C </span>
</div>
I think the problem occurs when element.append() method get duplicated reference. But I can't find the docs explain about it. It's stack overflow at my brain!!!
Thanks for reading my question and have a nice day :)

It seems that the issue is that you are using the same span element for both occurrences of that span. If you want to have a separate span for each, you would most likely need to create 2 spans, 1 for each temperature.
Here is a code example you might be able to use:
const div = document.createElement('div');
const span1 = document.createElement('span');
const span2 = document.createElement('span');
div.append("Min Temp", span1, "Max Temp", span2);

Maybe if you want to sort the spans according to the div textContent (Min/ Max Temp) you could have a workaround with two individual divs like that:
const div1 = document.createElement("div");
div1.textContent = "Min Temp";
const span = document.createElement("span");
span.classList.add("small-font");
span.textContent = "C°";
div1.append("span");
const div2 = document.createElement("div");
div2.textContent = "Max Temp";
div2.append("span");

Related

JavaScript create span element inside div

The following is the HTML that does what I want. It displays category: and beneath a value that I send in JavaScript.
<div id="category-order-id" class="additional-order-info">
<!-- <span class="additional-order-info-grey">category:</span>
Clothes -->
</div>
And here is my JavaScript
let orderCategory = document.getElementById("category-order-id");
orderCategory.textContent = `${order.category}`;
let categorySpan = document.createElement("span");
categorySpan.setAttribute("class", "additional-order-info-grey");
categorySpan.textContent = "category:";
orderCategory.appendChild(categorySpan);
What this code does, it that it first displays Clothes value that I send with JavaScript and beneath it display category.
Why I am creating a span element here is because if I set textContent of orderCategory it wil not display the span at all.
What am I doing wrong here?
textContent property replaces all the content in the element. If you want to keep order.category and "category:" as content, you need to use the appendChild function:
let orderCategory = document.getElementById("category-order-id");
const catTextContent = document.createElement("span");
catTextContent.textContent = order.category;
let categorySpan = document.createElement("span");
categorySpan.setAttribute("class", "additional-order-info-grey");
categorySpan.textContent = "category:";
orderCategory.appendChild(catTextContent);
orderCategory.appendChild(categorySpan);

How to append a span tag and give each id a new name

I have 3 inputs that are nestled inside a span tag (I'm using span and not li because I have many li's in my code). I have a javascript function that appends each span tag (which includes the 3 inputs). I need each input to have a specific id name. Not sure how to do this, I'm learning javascript right now so forgive me for I'm a noob.
In my function I have the appendchild working for the span tag. At the bottom of the code I have a for loop that I wrote to append an ul/li and that name works. But I can't get that same functionality to work for the span tags.
How can I append child and each time I appendchild that the inputs get a new id name?
Here is my code so far:
function budgetList(){
var elmnt = document.getElementsByTagName("SPAN")[0];
var cln = elmnt.cloneNode(true);
var budgetListing = document.getElementById("budget-listing");
var append = budgetListing.appendChild(cln);
var expenseName = document.getElementById('expenseName');
var expectedExpense = document.getElementById('expectedExpense');
var actualExpense = document.getElementById('actualExpense');
var ul = document.createElement("ul");
document.body.appendChild(li);
for(var i = 0; i <= 0; i++){
var li = document.createElement("li");
li.className = "budget-list" + i;
var a = document.createElement("a");
a.innerHTML = "<input type='text'>";
// a.innerHTML = "Subfile " + i;
var att = document.createAttribute("class");
att.value = "budgeting" + i;
li.appendChild(a);
ul.appendChild(li);
}
}
Here is the html
<button onclick="budgetList()">Add New Row</button>
<input type="button" value="save" onclick="save()" />
<ul id="budget-listing">
<span>
<input type="text" id="expenseName">
<input type="text" id="expectedExpense">
<input type="text" id="actualExpense">
</span>
</ul>
A few things...
1) <ul> stands for Unordered List and <ul> elements expect their children to be <li> elements (which you can remember as List Item). So, while some browsers may be forgiving of you appending spans to your <ul> tag, it's not considered good practice. And is technically a violation of the standard
2) Your loop will only run exactly once. You'll see it's starting with variable i initialized at 0 and will only run as long as i<=0 which will only ever be true on the first iteration because afterwards you increment (i++) which means the second time through i will equal 1 and 1 is NOT less than or equal to 0. So, in this case there's no need to use a loop at all.
3) Your code is a little disjointed from what you requested and what the page context is suggesting. It appears to me, when the user clicks the button you want to duplicate the span with 3 inputs. If this is indeed the case, then I offer the following solution...
function budgetList(){
// You get the span that will serve as a template, good
var elmnt = document.getElementsByTagName("SPAN")[0];
// you clone it, good
var cln = elmnt.cloneNode(true);
//next we want to modify the IDs of the child spans.
// A good way to do this is to use a unique number that will change with every step
// There a few ways to get a unique number each time
// I propose taking the number of span groups
var budgetListing = document.getElementById("budget-listing");
var uniqueNumber = budgetListing.childNodes.length;
// Now we update all the ids using the unique number
cln.getElementsByTagName('INPUT')[0].setAttribute('id', "expenseName_"+uniqueNumber);
cln.getElementsByTagName('INPUT')[1].setAttribute('id', "expectedExpense_"+uniqueNumber);
cln.getElementsByTagName('INPUT')[2].setAttribute('id', "actualExpense_"+uniqueNumber);
// and write our new span group into the container
budgetListing.appendChild(cln);
}
Let me know if I made any incorrect assumptions or if this is close to what you're requesting. JavaScript and its interaction with HTML can be confusing at first, but stick with it!
EDIT: Didn't realize getElementById wasn't a function... Replaced with getElementsByTagName

How do I create an element from html formatted text?

I'm using Angular 1.29 and Chrome.
I have some text like
<p>Text <strong> bold </strong> </p>
And I need to turn it into an element, because the library that I'm using, html2canvas, needs to be sent one.
So I've tried this, which I took from this answer
var div = document.createElement('div');
div.innerHTML = $scope.presData.text;
var element = div.firstChild;
html2canvas(element,{
onrendered:function(newCanvas){
document.getElementById("newPresentation").appendChild(newCanvas);
}
});
Where my text is in $scope.presData.text,
But that didn't work. This creates a canvas with a width and height of 0.
Using innerHTML of an HTML element should format them as document nodes.
var HTMLString = '<p>Text <strong> bold </strong> </p>';
var HTMLStringContainer = document.createElement('div');
HTMLStringContainer.innerHTML = HTMLString;
If you're having some issues with your canvas, I think your issue lies elsewhere.
Try this to set up your strings as html nodes... it is robust and will handle alot of different situation (multiple sibling nodes at the highest level for example). jsfiddle Demo
// HTML string
var s = '<p>Text <strong> bold </strong> </p>';
var div = document.createElement('div');
div.innerHTML = s;
var elements = div.childNodes;
//using your above canvas code
var element = elements[0];
html2canvas(element,{
onrendered:function(newCanvas){
document.getElementById("newPresentation").appendChild(newCanvas);
}
});
//multiple elements
//for(var i=0; i < elements.length; i++){
//html2canvas(elements[i],{
//onrendered:function(newCanvas){
//document.getElementById("newPresentation").appendChild(newCanvas);
//}
//});
//}

How do you use Javascript to add or remove HTML/CSS code?

If I have a bunch of HTML code, similar to the following:
<div id='test0div'>
<p id='test0'></p>
</div>
How do I use JavaScript to add or remove more of those - i.e.
<div id='test1div'>
<p id='test1'></p>
</div>
<div id='test2div'>
<p id='test2'></p>
</div>
...etc.?
var container = document.createElement("div");
for(var i=0; i<5; i++) { // change i <5 as per your data source
var div = document.createElement("div");
var p = document.createElement("p");
p.id = "test"+i;
div.id = "test"+i+"div";
div.appendChild(p);
container.appendChild(div); // you can event append to particular id or body
}
// document.getElementById("divId").appendChild(container);
container, will have all the divs & p as you wish
This will give you the output you want. Just change the number of times the loop will execute based on your wish.
To remove you could use
$('#id').remove();
To add you could use
$("<div id='new'></div>").appendTo('#id');

How can I append new "p" element with formatted text

I have a javascript function designed to dynamically append text to my document (and slides it down with JQuery). I create a new "p" element, and then I want to add text to it, but I need this text to have several formats. For example, I need the first part to be italicized, second part to be underlined, and third part to be white. As of now, I managed to get three different "div" elements with their own text nodes, each with their own style, but this makes it on three separate lines. I need it all on one line. Is there any way I can insert HTML tags into a text node, or somehow split the internal string up so I can style each part separately?
This code demonstrates the closest I got, but this puts each styled text node on different lines, and I need it all on one line in that p element:
function append_announcement(time_string, user_by, text){
newp = document.createElement("p");
head = document.createElement("span");
headt = document.createTextNode("You wrote: ");
head.appendChild(headt);
body = document.createElement("div");
bodyt = document.createTextNode(text);
body.appendChild(bodyt);
body.setAttribute("style", "color: white");
foot = document.createElement("div");
foott = document.createTextNode("Done.");
foot.appendChild(foott);
newp.appendChild(head);
newp.appendChild(body);
newp.appendChild(foot);
newp.setAttribute("align", "center");
newp.style.display = "none";
document.getElementById("announcement_posts").insertBefore(newp,
document.getElementById("announcement_posts").firstChild);
$("p").slideDown("slow");
}
Change the <div>s for <span>s, they're displayed inline by default.
Alternatively you could apply a class to the <div> elements you create and set that class to display: inline-block; using CSS.
Example
function append_announcement(time_string, user_by, text){
newp = document.createElement("p");
var i = document.createElement("i");
i.textContent = ("You wrote ");
var span = document.createElement("span");
span.textContent = text;
span.style.color = "white";
var u = document.createElement("u");
u.textContent = " Done.";
newp.appendChild(i);
newp.appendChild(span);
newp.appendChild(u);
newp.setAttribute("align", "center");
newp.style.display = "none";
document.getElementById("announcement_posts").insertBefore(newp,
document.getElementById("announcement_posts").firstChild);
$("p").slideDown("slow");
}
You want to create elements that display inline like <i>, <u> or <span>

Categories