How can I add a span to h3 Element with javascript - javascript

I'm making a chat and I want to add an avatar pics feature so I figured it might work well with span, but the problem is I don't know how to add the span to the element.
let avatar = document.createElement("span");
let userMessage = document.createElement("H3");
avatar.setAttribute(userMessage);
userMessage.innerHTML = username + ": " + message;
//document.getElementById("chat").appendChild(avatar);
document.getElementById("chat").appendChild(userMessage);
userMessage.style.background = color;
userMessage.style.textAlign = "left";
document.getElementById("msg").value = "";

I am assuming that you have div with id="chat" and you want to append an h3 tag in a span and then append the chat div so your code will look like this
var username="zulqarnain jalil";
var message ="welcome back, have a nice day";
var color='lightgrey';
var avatar = document.createElement("span");
var userMessage = document.createElement("h3");
userMessage.innerHTML = username + ": " + message;
userMessage.style.background = color;
userMessage.style.textAlign = "left";
avatar.appendChild(userMessage);
document.getElementById("chat").appendChild(avatar);
//document.getElementById("msg").value = "";
<div id="chat">
</div>
I have created a chatbot snippet for you, here you can test it
var username="zulqarnain jalil";
function sendMessage()
{
var message =document.getElementById('messagebox').value;
if(message)
{
document.getElementById('messagebox').value='';
var color='lightgrey';
var avatar = document.createElement("span");
var userMessage = document.createElement("h3");
userMessage.innerHTML = username + ": " + message;
userMessage.style.background = color;
userMessage.style.textAlign = "left";
avatar.appendChild(userMessage);
document.getElementById("chat").appendChild(avatar);
}
else
{
// message empty
}
}
//document.getElementById("msg").value = "";
<div id="chatBox">
<div id="chat">
</div>
<div>
<input type="text" id="messagebox" />
<input type="button" onclick="sendMessage()" value="Send" />
</div>
</div>

First you need to add the span as a child of the H3 element.
I think the best approach to this problem is creating a class Message. Initializing that class creates h3 and span with unique ids stored in a variable id for future use. The class will also add the h3 as a child of it's parent element ( what ever it is ), and the span as a child of the h3 element.
var counterText = 0;
var counterAvatar = 0;
class UserMessage {
constructor(msgTxt, avatar){
// This block initializes the text message of the user
// It will also add an id to the tag for future use
let msgTxt = document.createTextNode(msgTxt);
this.messageID = 'text' + counterText;
this.message = document.createElement('h3');
this.message.appendChild(msgTxt);
this.message.setAttribute('id', this.messageID);
counterText++;
// This block creates an img element with the attributes src and id
this.avatarID = 'avatar' + counterAvatar;
this.avatar = document.createElement('img');
this.avatar.setAttribute('src', avatar);
this.avatar.setAttribute('id', this.avatarID);
counterAvatar++;
// This block appends the avatar element to the text and the text to the
// chat div.
let chat = document.getElementById('chat');
this.message.appendChild(this.avatar);
chat.appendChild(this.message);
}
}
to initialize a new instance:
var message = new UserMessage("Hello, this is a text message!",'<path/to/avatar>')
this is an object oriented aproach.
you could also just append the avatar to the message and the message to the chat.
But I think aproaching the problem in an object oriented way is much better since it will save time in the future when you're updating your app.

Markdown works fine in here.
Block-level HTML elements have a few restrictions:
They must be separated from surrounding text by blank lines.
The begin and end tags of the outermost block element must not be indented.
Markdown can't be used within HTML blocks.

Related

How to add break tags after inserting a paragraph into html using javascript's createElement

I've successfully inserted a paragraph element into html page using javascript but the 2nd consecutive paragraph comes side by side and I wish to add a break tag to print them in another line, how do I do that?
Here is a screenshot of my output:
Here is my javascript code:
function newtask(){
let ask = prompt("Enter the description of task");
const para = document.createElement("p");
const Textnode = document.createTextNode(ask);
para.appendChild(Textnode);
let text= document.getElementById("new")
text.appendChild(Textnode);
}
Here is the relevant html
<script src="index.js"></script>
<h1>To do List</h1>
<button onclick="newtask()">New Task</button>
<div id="new">
<p>test</p>
</div>
You were appending Textnode to your parent element, not your new <p> element. Here's a quick rewrite that should give you your desired results.
Firstly, create the new <p> element, then modify its innerText property. After that, just append your new <p>.
function newtask() {
const text = document.getElementById("new");
const ask = prompt("Enter the description of task");
const para = document.createElement("p");
para.innerText = ask;
text.appendChild(para);
}
You can wrap your p inside a div and add a display: flex configuration.
const paraDiv = document.createElement("div");
// Add your style configuration to your paraDiv
function newtask(){
let ask = prompt("Enter the description of task");
const para = document.createElement("p");
paraDiv.appendChild(para)
const Textnode = document.createTextNode(ask);
para.appendChild(Textnode);
let text= document.getElementById("new")
text.appendChild(Textnode);
}

Can't append nodes to empty div

<div id = "first"></div>
<div id = "second"></div>
<div id = "third"></div>
Trying to dynamically append to these divs within a javascript function
if (condition??) variable = "first"
else if (condition) variable = "second"
else variable = "third"
let div = document.getElementById(variable);
Variable above could be first, second, or third depending on some condition.
div.appendChild(img)
div.appendChild(text)
However since div ends up being null I wont be able to append anything to it cuz of the following error.
Cannot read property 'appendChild' of null.
So any idea how to go around this?
Edit: Added the actual code snip below
// my html
<div id = "list" class = "center"> Listing <br><br>
<div id = "first"></div>
<div id = "second"></div>
<div id = "third"></div>
</div>
//my js
$.ajax({
async: true,
type: 'GET',
url: "rankings/" + boss + ".txt",
boss : boss,
success: function(sData){
let temp = this.boss
let div = document.getElementById(temp);
//console.log(temp) logs "first" on the console
let img = document.createElement("img");
let text = document.createElement('td1');
img.src = "images/" + temp + ".jpg";
img.alt = temp
div.appendChild(img)
div.appendChild(text)
Edit 2: Image of code exection
https://imgur.com/a/WkYTn
Your code looks correct! However, I think the problem is, you are loading the Javascript before the DOM is being rendered (Eg. you are loading the script in <head>). So javascript is not able to find the divs..
var variable= "second";
var boss = "boss_baby";
let div = document.getElementById(variable);
console.log(variable) //logs "first" on the console
let img = document.createElement("img");
let text = document.createElement('td1');
img.src = "images/" + boss + ".jpg";
img.alt = boss
div.appendChild(img)
div.appendChild(text)
#first, #second, #third {
display:block;
border: 1px solid blue;
height: 50px;
width: 200px;
margin : 10px;
}
<div id = "list" class = "center"> Listing <br><br>
<div id = "first"></div>
<div id = "second"></div>
<div id = "third"></div>
</div>
To solve this issue you can either load the <script> right before the body tag ends </body>
or add all your script in onload methods
window.onload = function() {
// all your JS code goes here
}
OR
document.onload = function() {
// all your JS code goes here
}
After question EDIT:
Your code looks correct! However, Now i suspect the element you are trying to access might have been removed by the time you get your response from ajax.
Try this Code Pen Example . I think your problem is with the "variable" and how your assigning value to it.
<div id = "first" style="border:1px red solid"></div>
<div id = "second" style="border:blue"></div>
<div id = "third" style="border:green"></div>
<script>
//try changing the value of condtion
var condition=3;
var variable="";
var img = document.createElement("img");
//var text = document.createElement('td1');
img.src = "https://www.w3schools.com/w3images/fjords.jpg";
img.alt = "boss"
//div.appendChild(img)
if (condition==1) variable = "first"
else if (condition==2) variable = "second"
else variable = "third"
console.log(img)
document.getElementById(variable).appendChild(img);
<script>

Deleting the last Element in a Div [JavaScript]

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.

How to remove objects within a todo?

Here is my code for my current todo list.
<html>
<head>
<title>ToDo</title>
</head>
<body>
<script>
function addText(){
var input = document.getElementById('input').value;
var node = document.createElement("P");
var textnode = document.createTextNode(input);
node.appendChild(textnode);
document.getElementById('do').appendChild(node);
}
</script>
<p id="do"> </p>
<input type='text' id='input'/>
<input type='button' onclick='addText()' value='Add To List'/>
</body>
</html>
It works to add objects but I have no idea what the javascript is to remove objects?
I wonder if someone could help me with a remove script like a X mark on the side of a new added object or something just to remove 1 after you add it,
Cheers
I think I found a solution to your problem. Check my fiddle:
http://jsfiddle.net/Kq4NF/
var c = 1;
function addText(){
var input = document.getElementById('input').value;
var node = document.createElement("P");
node.setAttribute('id', 'anchor'+c);
var textnode = document.createTextNode(input);
node.appendChild(textnode);
var removenode = document.createElement("input");
removenode.setAttribute('type', 'button');
removenode.setAttribute('value', 'X');
removenode.setAttribute("onclick", "removeText('anchor"+c+"')");
node.appendChild(removenode);
c++;
document.getElementById('do').appendChild(node);
}
function removeText(item){
var child=document.getElementById(item);
document.getElementById('do').removeChild(child);
}
Good luck!
var list = document.getElementById("do");
list.removeChild(list.childNodes[0]);
list - represents the p tag with ID do
list.ChildNodes - list of child elements appended to your p tag with ID as do.
list.ChildNodes[0] - represents the first child appended to the list, where 0 is the index.
To remove a specific element, either represent the is as index or point directly the element like
var list = document.getElementById("do");
var node = document.createElement("P");
var textnode = document.createTextNode(input);
textnode.id = "do1"; // Add id to the child element
node.appendChild(textnode);
document.getElementById('do').appendChild(node);
// This is to remove it using ID
list.removeChild(document.getElementById("do1"));
Hope you can understand.

Appending new container on click

I'm trying to learn HTML and Javascript/jQuery. If I have a container which holds a title, an image, a description and a number, then I want to create a new container with the exact same format (except the values will be different), how is this commonly done?
This is an example of the format I'm looking for in each item.
<li>
<div>
<div>
Image Name
</div>
<div>
<a href=URL>
<img src='image_url'>
</a>
</div>
<div>
Description
</div>
<div>
num_comment Comments
</div>
</div>
</li>
Do I just create a string and concatenate with the actual values for the image, then add that string to some variable I've saved called html_content, and then set the html value to html_content? Is that the common way of doing this or is there a better way?
EDIT
To give a better idea of what I'm currently doing, here's the javascript:
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
};
$('pics').html(html);
}
In jQuery you just have to use the append() function to add on to something.
You could do something like...
$('select element').append('<li><div>....etc.');
and where you want a different value you can use a variable.
You can use .clone() and create a copy of this, then iterate through the cloned object and change what you need:
var $objClone = $("li").clone(true);
$objClone.find("*").each(function() {
//iterates over every element. customize this to find elements you need.
});
To change the image source you can do:
$objClone.find("img").attr("src", "new/img/here.jpg");
Fiddle demoing the concept: http://jsfiddle.net/H9DnA/1/
You may find it useful to explore some of the JavaScript templating libraries. The essential idea is that you create a template of your markup:
<li>
<div>
<div>
{{name}}
</div>
<div>
<a href="{{url}}">
<img src="{{imageUrl}}">
</a>
</div>
<div>
{{description}}
</div>
<div>
{{comments}}
</div>
</div>
</li>
Then you merge it against some associated matching object and insert it into your document:
{ name: 'Image Name',
url: 'http://example.com',
imageUrl: 'http://example.com/image.jpg',
description: 'Description',
comments [ { text: 'Comment' } ]
}
function render(pics)
{
var theList = document.getElementByid("LIST ID");
for (var i in pics){
var listItem = document.createElement('li'); // Create new list item
var nameDiv = document.createElement('div'); // Create name DIV element
nameDiv.innerHTML = pics[i].name; // Insert the name in the div
var img = document.createElement('img'); // Create Img element
img.setAttribute('src',pics[i].src); // Assign the src attribute of your img
var imgDiv = document.createElement('div'); // Create Img Div that contains your img
imgDiv.appendChild(img); // Puts img inside the img DIV container
var descDiv = document.createElement('div'); // Create Description DIV
descDiv.innerHTML = pics[i].description; // Insert your description
listItem.appendChild(nameDiv); // Insert all of you DIVs
listItem.appendChild(imgDiv); // inside your list item
listItem.appendChild(descDiv); // with appropriate order.
theList.appendChild(listItem); // Insert the list item inside your list.
}
}
I think this will work just fine:
$('#button').click(function () {
var html1 = '<li><div><div>';
var html2 = '</div><div><a href="';
var html3 = '"><img src="';
var html4 = '"></a></div><div>';
var html5 = '</div><div>';
var html6 = '</div></div></li>';
function render(pics){
for (var i in pics){
html = html + html1 + pics[i].name + html2 + pics[i].image_url + html3 + ...
$("ul").append(html);
}
}
// call render
});
I didn't do a test run on your code so there might be an error somewhere. My tweak adds this line $("ul").append(html); inside your loop

Categories