Using a for loop in javascript to create multiple html div's.
for(var i = 0; i < lines.length; i++){
document.getElementById("rotate").innerHTML+="<div><div><a href='' id='idWithIndex_i'>";
document.getElementById("idWithIndex_i").innerHTML+=lines[i];
document.getElementById("rotate").innerHTML+="</a></div></div>";
}
The html should look like this for index 0:
<div>
<div>
<a href='' id='idWithIndex_0'>
line1
</a>
</div>
</div>
I want to define the index in the id of the anchor. How can I change the javascript? Thanks.
The problem is in this line:
for(var i = 0; i < lines.lenght; i++){
lenght does not exists in javascript. Use length instead.
Also, for concatenation, use this:
document.getElementById("rotate").innerHTML+='<div><div><a href="" id="idWithIndex_'+i+'">';
or using string templates from ES6 in order to obtain a cleaner solution.
document.getElementById("rotate").innerHTML+=`<div><div><a href="" id="idWithIndex_${i}">`;
Right now your i is just a part of a string, here's what you want:
for(var i = 0; i < lines.length; i++){
document.getElementById("rotate").innerHTML+="<div><div><a href='' id='idWithIndex_" + i + ">";
document.getElementById("idWithIndex_" + i).innerHTML+=lines[i];
document.getElementById("rotate").innerHTML+="</a></div></div>";
}
id='idWithIndex_"+i+"'
You need to break out of the string and then concatenate with + the variable.
In steps:
"idWithIndex_" is the first part of your fixed string
with + you append something to the former part
we append the variable i
after the variable we append the rest of the fixed string using another +.
Also type in your for loop: length instead of lenght
There is a way nicer way to do this:
var counter = 0;
//method 1 - createElement
document.querySelector("#add_method1").addEventListener("click", function(){
//add a click event to the add button
var node = document.createElement("div"); //create a new element
var innernode = document.createElement("div"); //create second node
var linknode = document.createElement("a");
linknode.setAttribute("href", '');
linknode.setAttribute("id", "idWithIndex_" + counter) //set id
linknode.innerHTML += "test"+counter; //lines[i] in your code;
counter++;
//time to append
innernode.appendChild(linknode);
node.appendChild(innernode);
document.getElementById("rotate").appendChild(node);
},true);
//method 2 - cloneNode
document.querySelector("#add_method2").addEventListener("click", function(){
//add a click event to the add button
var cloned = document.querySelector(".copynode").cloneNode(true); //true for deep cloning
cloned.removeAttribute("class"); //remove class
var a = cloned.querySelector("div > a"); //select link
a.setAttribute("id", "idWithIndex_" + counter) //set id
a.innerHTML += "test"+counter; //lines[i] in your code;
counter++;
//time to append
document.getElementById("rotate").appendChild(cloned);
},true);
/*css for method 2 */
.hidden {
display: hidden;
}
<div id="rotate"></div>
<button id="add_method1">add using document.createElement</button>
<button id="add_method2">add using element.cloneNode</button>
<!-- html for method 2 -->
<div class="copynode hidden">
<div>
</div>
</div>
for(var i = 0; i < lines.length; i++){
document.getElementById("rotate").innerHTML+="<div><div><a href='' id='idWithIndex_"+i+"'>";
document.getElementById("idWithIndex_"+i).innerHTML+=lines[i];
document.getElementById("rotate").innerHTML+="</a></div></div>";
}
First off, you have a type at .lenght.
Also, The "i" is not a part of the string, its a variable, so you need to add the value of i as the id od the div, not the string "i".
Try this
for(var i = 0; i < lines.lenght; i++){
document.getElementById("rotate").innerHTML+="<div><div><a href='' id='idWithIndex_"+i+"'>";var id = "idWithIndex_"+i;
document.getElementById(id).innerHTML+=lines[i];
document.getElementById("rotate").innerHTML+="</a></div></div>";
}
var lines = [1,2,3,4]
var i;
for(i = 0; i < lines.length; i++){
document.getElementById("rotate").innerHTML+="<div><div><a href='' id='idWithIndex_"+i+"'> " + lines[i]+"</a></div></div>";
}
<div id="rotate">Hi</div>
As others have mentioned you need to either concatenate the values into the string or use a template string to inject them into the string.
I wanted to suggest a little refactoring. DOM access is relatively expensive, with 3 getElementById queries and 3 changes to the DOM via innerHTML per loop, that creates a lot of unnecessary overhead. In most cases it probably doesn't matter, but if there were a lot of items in lines, it could bring the browser to its knees. It would be better to build a string of the HTML you are injecting and just inject once:
let lines = ['a', 'b', 'c'];
let linesHtml = ''; // buffer for the HTML we are building
for(let i = 0; i < lines.length; i++) {
// there is no need to create the link and then inject content into it,
// we can just inject the content right into the element in the HTML
linesHtml += `<div>
<div>
<a href='' id='idWithIndex_${i}'>
${lines[i]}
</a>
</div>
</div>`;
}
// now that we know what we are injecting, make a single DOM update
document.getElementById("rotate").innerHTML += linesHtml;
div {
border: 1px solid #000;
padding: 3px;
}
<div id="rotate"></div>
I used a template literal instead of a normal string because it allows you to easily create multi-line strings, for easily readable embedded HTML. This can help a lot with the maintainability of your code. Any recent browser supports them (IE isn't recent; if you have to support it, you have my condolences).
Related
I have the following HTML string:
<div><p>Hello <b>how are</b> you?</div>
I would like to loop the HTML string DOM and wrap each word with a span tag and the word number as id so result will be like this:
<div><p><span id="word-1">Hello</span> <b><span id="word-2">how</span> <span id="word-3">are</span></b> <span id="word-4">you?</span></div>
I've tried to use the JQuery method $.parseHTML but no luck to count the words because DOM node value can contain more than one word in it..
In addition, if inside the word there is inline tags such <b> / <i> so from DOM point of view each tag has a different node value even when its the same word)
Any idea how to solve this issue? how to count words inside a HTML DOM string?
Thanks
Try this.
HTML
<div id="content">
<div><p>Hello <b>how are</b> you?</div>
</div>
Script
var textNodes = $("#content *").contents().filter(function() {
return this.nodeType === 3;
});
var counter = 1;
for(var i = 0;i<textNodes.length;i++)
{
var val = $(textNodes).eq(i).text();
var words = val.split(" ");
var final = "";
for(var j = 0;j<words.length;j++)
{
if(words[j].trim() != "")
{
final += "<span id='"+ counter +"'>"+ words[j] +" </span>";
counter++;
}
}
$($(textNodes)[i]).replaceWith(final);
}
Jsfiddle Link
As of my understanding of your question this should work.
var allText = $("body").text().replace(/<[^>]*>/g, "");
var words = allText.split(' ');
for(var i=0;i<words.length;i++)
{
$(div).append("<span id = 'word-'"+i+">"+words[i]+"</span>")
}
I'm working on a Blogger widget, trying to rid it of any deprecated or bad practices (based what I read on Stack Overflow), such as document.write
This was working:
<script type="text/javascript">
function introductory(json) {
document.write('<div id="intro-wrapper">');
var i;
for (i = 0; i < json.feed.entry.length; i++) {
var introTitle = json.feed.entry[i].title.$t;
var introContent = json.feed.entry[i].content.$t;
var item = '<h2>' + introTitle + '</h2><p>' + introContent + '</p>';
document.write(item);
}
document.write('</div>');
}
</script>
<script src="https://MYBLOG.blogspot.com/feeds/posts/default/-/intro?max-results=1&alt=json-in-script&callback=introductory"></script>
It displays the title and content (wrapped up within h2 and p tags, respectively) of one single post ( ...max-results=1... ), labeled "intro" ( .../-/intro?... ) by means of Blogger labels.
I've tested various alternatives, lining up my html elements prior to the js, then using getElementById, followed by either innerHTML or appendChild, or even lining up the elements inside the js, by means of createElement, but to no avail, really. Would it be possible for anyone to point me to the right direction?
P.S. I can hardly copy and paste all of my attempts in this question. There have been dozens of them, as I'm more or less clueless when it comes to javascript and I'm just experimenting my way forwards, so I've opted for merely posting the code that is actually working and asking for an alternative that does not utilize document.write, if that's indeed "bad practice".
I greet you at the beginning about trying to rid document.write
Create an element with a unique id before your JS code in the document, then select this element by its id getElementById and add your content to it using innerHTML
<div id="intro-wrapper"></div>
<script type="text/javascript">
function introductory(json) {
var item="";
for (var i = 0; i < json.feed.entry.length; i++) {
var introTitle = json.feed.entry[i].title.$t;
var introContent = json.feed.entry[i].content.$t;
item += '<h2>' + introTitle + '</h2><p>' + introContent + '</p>';
}
document.getElementById('intro-wrapper').innerHTML=item;
}
</script>
<script src="https://MYBLOG.blogspot.com/feeds/posts/default/-/intro?max-results=1&alt=json-in-script&callback=introductory"></script>
You can also use document.createElement instead of document.write.
Here is working example -
<script>
function introductory(json) {
var RecentPostContainer = document.createElement('div');
RecentPostContainer.className = 'RecentPostContainer';
for(i = 0; i < json.feed.entry.length; i++) {
var PostContainer = document.createElement('div');
PostContainer.className = 'PostContainer';
var PostTitle = document.createElement('h2');
PostTitle.className = 'PostTitle';
var PostTitleText = document.createTextNode(json.feed.entry[i].title.$t);
PostTitle.appendChild(PostTitleText);
PostContainer.appendChild(PostTitle);
var PostContent = document.createElement('div');
PostContent.className = 'PostContent';
PostContent.innerHTML = json.feed.entry[i].content.$t;
PostContainer.appendChild(PostContent);
RecentPostContainer.appendChild(PostContainer);
}
document.getElementById('RecentPostContainer').insertAdjacentHTML('afterend', RecentPostContainer.outerHTML);
}
</script>
<script id='RecentPostContainer' src="https://blogger.googleblog.com/feeds/posts/default/?max-results=1&alt=json-in-script&callback=introductory"></script>
I have to add an id to an element. An engine generates the HTML... I have no access to it. It generates random IDs as such:
<input id="5352Adkdie4929888a">
I want to grab the first instance of "<input id=" and replace the ID it has with
the ID it has + DatePicker.
Example:
<input id="5352Adkdie4929888a DatePicker">
How would I go about doing this?
My code so far:
function addID(){
var html= document.documentElement.innerHTML;
var start= '<input id="';
var end= '"'
var htmlIWant=html.substring(html.indexOf(start) + start.length), html.indexOf(end)-1 + 'DatePicker';
}
Am I on the right track? How do I actually replace the HTML? Thanks!
This is a pure javascript solution as per your requirements.
Assuming that your page will have many input tags and some of them will be without ID attribute below is a solution you can try.
var elements = document.getElementsByTagName("input");
for (var i = 0; i < elements.length; i++)
{
if (elements[i].type == "text" && elements[i].hasAttribute("id"))
{
var id = elements[i].getAttribute("id");
elements[i].setAttribute("id", id + "10");
break;
}
}
Grab the first input inside the element using
$('input:first-child').attr('id','whateverIdName');
If you have to catch first input box that has id attribute, you should do :
$("input[id]")[0]
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Trying to add the text dynamically to the same span. Have generated an index to the id so that based on index thought to add the text.
This is what i have tried.
Expected output is I need to create one more span with same id but different index and append my array values to the span with index values.
Expected Output Example:
<span id="test-0">test</span>
<span id="test-1">Demo</span>
HTML:
<span id="test-{{$index}}"></span>
JS:
var arr = [{"Name":"test"},{"Name":"Demo"}];
for(var i=0; i<arr.length;i++){
txt = arr[i].Name;
$('#test-'+i).text(txt);
}
Tried Demo:
Demo Link
Try this:
$('#test-'+i).text(txt);
Assign value in text() function
$('#test-'+i).text();
to
$('#test-'+i).text(txt);
You can use string builder, such as:
var arr = [{ "Name": "test" }, { "Name": "Demo" }];
for (var i = 0; i < arr.length; i++) {
txt = arr[i].Name;
document.write("<span id=test-" + i + ">" + txt + "</span>");
}
Try this : You can have a div to add span which will have dynamic id and text from array.
HTML-
<div id="test"></div>
javascript: -
var arr = [{"Name":"test"},{"Name":"Demo"}];
var $text = $('#test');
for(var i=0; i<arr.length;i++){
$text.append('<span id="test-'+i+'">'+arr[i].Name+'</span>');
}
JSFiddle DEMO
The fiddle you had given is wrong. which has been edited as follows.
check fiddle here
var arr = [{"Name":"test"},{"Name":"Demo"}];
for(var i=0; i<arr.length;i++){
//append existing text to new value from array
var txt = $('#test'+i).text() + arr[i].Name;
$('#test'+i).text(txt);
}
If you actually want to use angular, you are going about it all wrong. Angular doesn't play well with html elements added elsewhere, they have to be compiled first so angular can bind to them. In this instance you could use ng-repeat to bind a list to a series of spans:
<span ng-repeat="item in [100, 200, 300, 400]" id="test-{{$index}}">
Index is {{$index}}<br/>
</span>
You also need to include angular in your fiddle and have an element with the ng-app tag (fiddle). Using angular you would also have a named controller and set a property on the scope to your array, but that is outside the bounds if this question.
What I'm trying to do is pretty simple: Add a 1x20 table of input cells inside a div.
I created a JavaScript function
var tableHTML = function(attributes, rows, columns)
{
var retHTML = "<table " + attributes + ">";
for (var i = 0; i < rows; ++i)
{
retHTML += "<tr>";
for (var j = 0; j < columns; ++j)
retHTML += "<td> </td>";
retHTML += "</tr>";
}
return (retHTML + "</table>retHTML");
}
to give me the HTML for a table with a specified dimensions and attributes. Then, in the body of my HTML, I put
<div class="inner_div" id="input_table">
<!-- div to house the table -->
</div>
<script type="text/javascript">
document.getElementById("input_table").innerHTML += tableHTML("id=\"input_table\" type=\"input\"", 1, 20);
</script>
which I thought would accomplish the task, but hasn't. I think this is because I'm trying to assign a string object to an HTML object. I kinda assumed that an implicit cast would be made. Anyways, I'm wondering if anyone has a "quick fix" to my problem. I would prefer not to redo my entire approach to the problem, but I also wouldn't mind someone informing me of the proper way to do the type of thing I'm trying to do -- using JavaScript to fill in page HTML on load.
Here's my take on this. I'm learning functional programming, so I do a bunch things here that might seem like their a waste of coding, but here's the concept:
Get the dimensions
Create a single row
Copy that row to make the table
After that return the table.
If you want to add id's, class's, etc... work with the DOM element returned by makeTable.
// Makes a single row
var makeRow = function(_columns) {
var row = document.createElement('tr');
var cell = document.createElement('td');
var cols = _columns;
while (cols) {
row.appendChild(cell.cloneNode(true));
cols--;
}
return row;
}
// Makes a table
var makeTable = function(_rows, _columns) {
var table = document.createElement('table');
var row = makeRow(_columns);
var rows = _rows;
while (rows) {
table.appendChild(row.cloneNode(true));
rows--;
}
return table;
}
I tried your code and it works: the table is generated and obviously empty
But be carrefull: if you do this, you will have two elements with the same ID (input_table)