Add an img src to html from JavaScript correctly - javascript

I have created a script that creates an inner element in a HTML div element.
It works fine, but I think the way I did it using a string is not the most suitable in JavaScript.
HTML
<body>
<div class="chart-container">
<div class="chartlyrics">...</div><div class="chartlyrics box" id="powered_by"></div>
</div>
</body>
Where the "..." are is where I created the element.
Javascript
document.getElementsByClassName('chartlyrics')[0].innerHTML = '<img src="img/103-logo.jpg" class="" /><br />Powered by '
HTML Result:
<body>
<div class="chart-container">
<div class="chartlyrics"><img src="img/103-logo.jpg" class="" /><br />Powered by </div><div class="chartlyrics box" id="powered_by"></div>
</div>
</body>
How can I do this but without using a string when creating the element in JavaScript?
I tried this but it gives me a syntax error:
document.getElementsByClassName('chartlyrics')[0].innerHTML = ''
var img = document.getElementsByClassName('chartlyrics')
.appendChild(document.createElement("img"));
img.src = "img/103-logo.jpg"
img.class = ""
img.textContent = 'Powered by '
console.log(document.getElementsByClassName('chartlyrics')[0].innerHTML);
Result:
document.getElementsByClassName (...). appendChild is not a function

You need to access the first element of the HTMLCollection and append the <img> element to that. Furthermore, store the newly created element in a variable first so you can set properties before appending. To add a line break and text after the image, you can append a newly created <br> element and use .append to add text.
const parent = document.getElementsByClassName('chartlyrics')[0];
parent.innerHTML = '';
var img = document.createElement("img");
img.src = "img/103-logo.jpg"
img.setAttribute('class', "")
parent.appendChild(img);
parent.appendChild(document.createElement('br'));
parent.append('Powered by ');
However, finding every single element with a specificied class to obtain only one element is extremely wasteful. You should use document.querySelector to obtain the first element matching a selector.
const parent = document.querySelector('.chartlyrics');
parent.innerHTML = '';
var img = document.createElement("img");
img.src = "img/103-logo.jpg"
img.setAttribute('class', "")
parent.appendChild(img);
parent.appendChild(document.createElement('br'));
parent.append('Powered by ');

Related

JavaScript: Dynamically created html-like string won't tun into html

in DOM I already have a wrapper
<div id="wrapper"></div>
which I need to fill with bunch of divs, where each will represent new category.
Each category will be then filled with various cards representing items of that category. Like this:
<div id="wrapper">
<div data-category="puppy">
Dynamically created category wrapper
<div class="puppy1">...</div>
<div class="puppy2">...</div>
</div>
<div data-category="cat">
...
</div>
</div>
I use following code to create and fill category, but I always end up either having empty category or having a string inside reprenting the html.
var categoryWrapper = document.createElement("div");
categoryWrapper.setAttribute("data-category", key);
categoryWrapper.innerHtml = htmlString;
Here is a fiddle demo of my issue.
https://jsfiddle.net/uuqj4ad5/
I'll be grateful for a help.
There is a typo, innerHml should be innerHTML(Javascript object properties are case sensitive) otherwise it simply add an additional property and nothing gets happened.
categoryWrapper.innerHTML = htmlString;
var htmlString = "<div class='card'><div class='cardImg'><img src='http://cdn.cutestpaw.com/wp-content/uploads/2012/07/l-Wittle-puppy-yawning.jpg' alt='Puppy'></div><div class='cardContent'><div class='cardInfo'><p>Puppy Yawning</p></div><div class='cardDesc'><p>Awww!</p></div></div></div>";
var outerWrapper = $("#wrapper");
var categoryWrapper = document.createElement("div");
categoryWrapper.innerHTML = htmlString;
outerWrapper.append(categoryWrapper);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h3>
Under this title various categories should be dynamically created
</h3>
<div id="wrapper">outerWrapper waiting for dynamic data...</div>
</div>
FYI : If you want to remove the existing content then use html() method instead of append() method.
innerHtml
should be
innerHTML
Javascript is case sensitive
If you are using jQuery why do you want to mix jQuery and Vanilla JS.
var outerWrapper = $("#wrapper");
// I created new categoryWrapper object
var categoryWrapper = $('<div/>', {
html: htmlString
});
debugger;
// WHen I have the category filled with inner data, I will append it into outerwrapper
outerWrapper.append(categoryWrapper);
jsFiddle
Checkout my fiddle:-
https://jsfiddle.net/dhruv1992/1xg18a3f/1/
your js code should look like this
// This is dynamically filled html template. The data comes from some JSON.
var htmlString = "<div class='card'><div class='cardImg'><img src='http://cdn.cutestpaw.com/wp-content/uploads/2012/07/l-Wittle-puppy-yawning.jpg' alt='Puppy'></div><div class='cardContent'><div class='cardInfo'><p>Puppy Yawning</p></div><div class='cardDesc'><p>Awww!</p></div></div></div>";
// This outer wrapper will in the end contain few categories
var outerWrapper = $("#wrapper");
outerWrapper.append('<div>'+htmlString+'</div>')

appending CSS file into javascript into single .js file

i tried to append all my CSS code into my javaScript and then load it trough js file,i do this,where is the problem?here is the first lines of my js file:
var innerstyle = '#container{width:800px;background:silver;margin:20px auto;padding:10px;color:gray;border-radius:5px}input{padding:3px}input[name="jsvar"]{width:250px;font-family:courier}#display{border:2px gray solid;border-radius:5px;color:white;margin:10px 0}#display #dtitle{background:gray;border-radius:2px 0;padding:10px 5px}#display #dmsg{min-height:20px}#clear{float:right;cursor:pointer;text-decoration:none;color:white;background:red;padding:2px 10px;border-radius:5px}#clear:hover{background:gold}.rtitle{padding:8px;background:pink;text-align:center}.rtitle input{border:1px solid red;float:right}.rtext{max-height:200px;overflow:auto;margin-bottom:5px}.rtext td{min-width:100px}.secfilter{margin-left:5px}';
var styletag = document.createElement('style');
var inst = document.createTextNode(innerstyle);
styletag.appendChild(inst);
var headref = document.getElementsByName('head');
headref.appendChild(styletag);
and here is the chrome console message:
Uncaught TypeError: undefined is not a function
Line 6;
var innerstyle = '#container{width:800px;background:silver;margin:20px auto;padding:10px;color:gray;border-radius:5px}input{padding:3px}input[name="jsvar"]{width:250px;font-family:courier}#display{border:2px gray solid;border-radius:5px;color:white;margin:10px 0}#display #dtitle{background:gray;border-radius:2px 0;padding:10px 5px}#display #dmsg{min-height:20px}#clear{float:right;cursor:pointer;text-decoration:none;color:white;background:red;padding:2px 10px;border-radius:5px}#clear:hover{background:gold}.rtitle{padding:8px;background:pink;text-align:center}.rtitle input{border:1px solid red;float:right}.rtext{max-height:200px;overflow:auto;margin-bottom:5px}.rtext td{min-width:100px}.secfilter{margin-left:5px}';
var styletag = document.createElement('style');
var inst = document.createTextNode(innerstyle);
styletag.appendChild(inst);
//var headref = document.getElementsByName('head'); // Wrong!
var headref = document.getElementsByTagName('head')[0];
headref.appendChild(styletag);
HTML DOM getElementsByName
returns a collection of all elements in the document with the specified name (the value of the name attribute)
("name" attribute deprecated in HTML5 and replaced by "id" attribute for many elements. You should use getElementById thanks #t.niese)
like
<input name="somename" />
document.getElementsByName("somename");
instead you could use the ID of the tag like
<input name="somename" id="theId" />
and query the element with:
document.getElementById('theId')
getElementById returns the element that has the ID attribute with the specified value
HTML DOM getElementsByTagName(tag) find all elements with the tag name "tag" and return an array, if you find by the tag name 'head' the first position in the array, would be the head element.
This function document.getElementsByName('head'); returns array. Try maybe something like this
document.getElementsByName('head')[0]
Its would give you first finded element with name head

A HTML tag to store "javascript's data"?

I need to write some html with placeholder used for javascript.
ex:
<span><placeholder data-id="42" data-value="abc"/><span>
Later on, a script will access those placeholders and put content in (next to?) them.
<span><placeholder data-id="42" data-value="abc"><div class="Google"><input type="text" value="abc"/></div><span>
But the placeholder tag doesn't exist. What tag can be used? Using < input type="hidden" .../> all over feels wrong.
Creating Custom tag
var xFoo = document.createElement('placeholder');
xFoo.innerHTML = "TEST";
document.body.appendChild(xFoo);
Output:
<placeholder>TEST</placeholder>
DEMO
Note: However creating hidden input fields with unique ID is good practice.
give your span element an id like,
<span id="placeToAddItem"><span>
and then in jQuery,
$('#placeToAddItem').html('<div class="Google"><input type="text" value="abc"/></div>');
or else
var cloneDiv = $('.Google');
$('#placeToAddItem').html(cloneDiv);
Example
The best way to do this, is using <input type='hidden' id="someId" value=""> tags.
Then you can easily access them by using jQuery, and recall the variable or change it.
var value = $("#someId").val(); to get variable or $("#someId").val(value) to change it.
This complete, no jQuery solution allows you to specify the placeholder/replacement html as a string within the element that will be replaced.
EG HTML:
<div data-placeholder="<div class='Google'><input type='text' value='abc'/></div>"></div>
<div data-placeholder="<div class='Boogle'><input type='text' value='def'/></div>"></div>
<div data-placeholder="<div class='Ooogle'><label>with label <input type='text' value='ghi'/></label></div>"></div>
<span data-placeholder="<em>Post JS</em>">Pre JS</span>
<br />
<button id="test">click me</button>
JS:
Use querySelectorAll to select all elements with the attribute 'data-placeholder' (returns a NodeList)
var placeholders = document.querySelectorAll('[data-placeholder]'); //or by ids, classnames, element type etc
Extend the NodeList prototype with a simple 'each' method that allows us to iterate over the list.
NodeList.prototype.each = function(func) {
for (var i = 0; i < this.length; i++) {
func(this[i]);
}
return this;//return self to maintain chainability
};
Extend the Object prototype with a 'replaceWith' method that replaces the element with a new one created from a html string:
Object.prototype.replaceWith = function(htmlString) {
var temp = document.createElement('div');//create a temporary element
temp.innerHTML = htmlString;//set its innerHTML to htmlString
var newChild = temp.childNodes[0];//(or temp.firstChild) get the inner nodes
this.parentNode.replaceChild(newChild, this);//replace old node with new
return this;//return self to maintain chainability
};
Put it all together:
placeholders.each(function(self){
self.replaceWith(self.dataset.placeholder);//the 'data-placeholder' string
});
Another example but here we only replace one specific element with some hard-coded html on click:
document.getElementById("test").addEventListener('click', function() {
this.replaceWith("<strong>i was a button before</strong>");
}, false);
DEMO: http://jsfiddle.net/sjbnn68e/
use the code below :
var x = document.createElement('placeholder');
x.innerHTML = "example";
document.body.appendChild(x);

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

Javascript parse html, modify anchor tags that contain images

I have a vague idea on howto do this but I hoped more experienced devs might have a simpler solution.
I have a sting of HTML code from a JSON feed and where an "a" tag exists with an images inside the "a" tag I want to modify and add attributes. example:
<a style="color:000;" href="images/image.jpg">
<img width="100" height="20" src="images/image_thumb.jpg" />
</a>
I would like to change it to be:
<a style="color:000;" href="images/image.jpg" rel="lightbox" >
<img width="100" height="20" decoy="images/image_thumb.jpg" />
</a>
So adding an attribute to the "a" tag and modifying an attribute in the "img" tag. There maybe multiple links within the HTML code some with and without images and other HTML code surrounding them.
To be clear this is NOT modifying HTML already rendered on the page, this is modifying a string of code before it gets rendered.
To be extremely clear here is the JSON feed in question: http://nicekiwi.blogspot.com/feeds/posts/default?alt=json
The HTML code that contains the tags are found at "feed > entry > content > $t"
Am currently working with Mootools 1.3
Any ideas? Thanks.
First, put it in a new element that does not exist on the page, then modify it as usual:
var container = new Element("div", { html: yourHTML });
container.getElements("a img").forEach(function(img){
var link = img.getParent("a");
img.decoy = img.src;
img.removeAttribute("src");
link.rel = "lightbox";
});
Demo here: http://jsfiddle.net/XDacQ/1/
In straight JS
var a = document.createElement('div');
// put your content in the innerHTML like so
a.innerHTML = '<a style="color:000;" href="images/image.jpg"><img width="100" height="20" src="images/image_thumb.jpg" /></a>';
var b = a.firstChild;
b.rel = 'lightbox';
var c = b.firstChild;
c.setAttribute('decoy', c.src);
c.src = null;
// now you have your a tag
var newA = a.innerHTML;
Dumbest regexp
var string = '<a style="color:000;" href="images/image.jpg">="images/image_thumb.jpg" /></a>',
text = '';
text = string.replace('href', 'rel="lightbox" href');
text = text.replace('src', 'decoy');

Categories