Convert a HTML Collection to Javascript Array? - javascript

I am a newbie, trying to learn w3c-dom, html-dom, just went through this DOM-Introduction
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DOM</title>
</head>
<body>
<script type="text/javascript">
var getByTag = function(selector) {
// FIXME: Do more conditions -- Come Up with more non-verbose regex condition
return /\w/i.test(selector) ? document.getElementsByTagName(selector) : null;
}
var isHTMLCollection = function(data) {
return data.toString() === '[object HTMLCollection]';
}
var toArray = function(c) {
return Array.prototype.slice.call(c);
}
var getAllPs = getByTag('p');
console.log(isHTMLCollection(getAllPs), 'isHTMLCollection');
console.log(Array.isArray(getAllPs), 'isArray-1');
console.log(getAllPs, 'getAllPs');
var _arrayLike = toArray(getAllPs);
console.log(Array.isArray(_arrayLike), 'isArray-2');
console.log(_arrayLike.length, 'Array.length');
</script>
<p id="p1">
First Para
</p>
<p id="p2">
Second Para
</p>
</body>
</html>
While logging this on console, i got just an empty array, when i tried to convert the HTMLCollection to Array.
Note: Tried using for-loop also.
Attached the console output,

Yes, adding
document.addEventListener('DOMContentLoaded', function() { //rest of the code });
fixes the issue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DOM</title>
</head>
<body>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var getByTag = function(selector) {
// FIXME: Do more conditions -- Come Up with more non-verbose regex condition
return /\w/i.test(selector) ? document.getElementsByTagName(selector) : null;
}
var isHTMLCollection = function(data) {
return data.toString() === '[object HTMLCollection]';
}
var toArray = function(c) {
return Array.prototype.slice.call(c);
}
var getAllPs = getByTag('p');
console.log(isHTMLCollection(getAllPs), 'isHTMLCollection');
console.log(Array.isArray(getAllPs), 'isArray-1');
console.log(getAllPs, 'getAllPs');
var _arrayLike = toArray(getAllPs);
console.log(Array.isArray(_arrayLike), 'isArray-2');
console.log(_arrayLike.length, 'Array.length');
});
</script>
<p id="p1">
First Para
</p>
<p id="p2">
Second Para
</p>
</body>
</html>
Note: Problem with chrome console is, array values are evaluated on asynchronously.
Thanks to #somethinghere & #trincot.

Related

JavaScript querySelector not working when .value is added to it

I am creating my program which takes the user input on an Enter key.
I use the userInput with .value in the if statement and it works perfectly. But when I try to use it as a variable, nothing is outputted and nothing is in the console.
I tried to do querySelector("input['name = "command"]') to see if it might work but again, nothing outputted and it showed nothing in the console
var userInput = document.querySelector("input[name = 'command']")
var theInput = userInput.value.toLowerCase();
var theConsole = document.querySelector("#console");
theConsole.scrollTop = theConsole.scrollHeight;
var myScroll = document.getElementById("scroll");
function doAThing(event) {
var theKeyCode = event.keyCode;
if(theKeyCode === 13) {
acceptCommand();
setInterval(scrollUpdate, 1000)
}
}
function scrollUpdate() {
myScroll.scrollTop = myScroll.scrollHeight;
}
function acceptCommand() {
var p = document.createElement("p");
if(theInput=== "help") theConsole.append("Help is given!", p);
//using the keywords
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body id = "scroll">
<div id="game">
<div id="console">
</div>
</div>
<div id = "command-box">
<div id = "cmd">
<input type = "text" name = "command" id = "command" onkeypress = "doAThing(event);">
</div>
</div>
</div>
</body>
</html>
Replace the div#console element:
<div id="console">
to this input:
<input type="text" id="console">
You will want to refer to userInput.value instead of theInput. Because theInput is set to the value at the time of setting the variable and it doesn't get updated even though the value of userInput changing.

How to replace entire HTML content with Javascript?

I tried to use $("html").html(this.responseText);. Which replaces the content but it does not replace the head and body tags.
So for example if i want replace this content:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>...</script>
<script>...</script>
</head>
<body>
<h1>This is a Heading</h1>
<script>...</script>
</body>
</html>
Then i check my HTML structure in inspector, and the result this:
<!DOCTYPE html>
<html>
<title>Page Title</title>
<script>...</script>
<script>...</script>
<h1>This is a Heading</h1>
<script>...</script>
</html>
And it messed my css so. I have tried without scripts, and it worked fine. What is the solution for this problem?
I have also tried with javascript approach
document.open();
document.write(this.responseText);
document.close();
But it confuses my javascripts. I am getting redeclaration syntax error.
My real code where i want to implement:
<script>
var frm = $('#frm');
var submitActors = frm.find('input[type=submit]');
var submitActor = null;
submitActors.click(function(event) {
submitActor = this;
});
frm.unbind('submit').submit(function () {
var formAction = document.getElementById("frm").getAttribute('action'); // Get the form action.
var data = "";
var pageUrl = "";
var test_uuid = "";
var test_number = "";
var qid = JSON.parse(sessionStorage.getItem('userChoice')).qid;
if(submitActor.name == "cmdSave"){
data = {
"cmdSave" : $("#cmdSave").val(),
"Answer": document.querySelector('input[name="Answer"]:checked').value,
"csrfmiddlewaretoken": document.querySelector('input[name=csrfmiddlewaretoken').value,
"qid": qid
}
}
else if(submitActor.name == "cmdNext"){
data = {
"cmdNext": document.querySelector('#cmdNext').value,
"csrfmiddlewaretoken":document.querySelector('input[name=csrfmiddlewaretoken').value,
"qid": qid
}
}
var httpRequest = new XMLHttpRequest();
var formData = new FormData();
Object.keys(data).forEach(function(key) {
console.log(key, data[key]);
formData.append(key, data[key]);
});
console.log(formData)
httpRequest.onreadystatechange = function(){
if ( this.readyState == 4 && this.status == 200 ) {
var response = this.responseText;
console.log(this.responseText) // Display the result inside result element.
// 1.Option
{% comment %} document.open();
document.write(this.responseText);
document.close(); {% endcomment %}
// 2.Option
{% comment %} document.documentElement.innerHTML = this.responseText; {% endcomment %}
// 3.Option
$(document).ready(function(){
$("html").html(response);
});
test_number = document.getElementById("lblNrCrt").textContent;
test_uuid = "{{test.uuid}}";
pageUrl = "/intro/" + test_uuid + "/" + test_number + "/";
window.history.pushState('', '', pageUrl);
}
};
httpRequest.open("post", formAction);
httpRequest.send(formData);
return false;
});
</script>
As I pointed out it can be done
document.querySelector('html').innerText = 'yolo';
But if you need to render HTML you should do
document.querySelector('html').innerHTML = '<div>yolo</div>';
Using Chrome browser I found that the response (or any innerHTML you want to use as the new page) has to start strictly with the <head> tag. Not <html> or <!DOCTYPE html> or anything else, otherwise replacing innerHTML or using document.write(response) always outputs the whole content inside <body>...</body> tag.
Here is the snippet/page I used locally to try all suggestions I saw (and didn't work), until I tried condensing the new page content/string to "<head>...</head><body>...</body>".
document.querySelector("#replace-content-btn").addEventListener('click', function() {
document.querySelector("html").innerHTML = `
<head>
<title>New Page Title</title>
</head>
<body>
<p>New body content.<br>Inspect the head element!</p>
</body>`;
});
<head>
<title>Some Page Title</title>
</head>
<body>
<p>Some body content.<br>Inspect the head element before and after button click.</p>
<button type="button" id="replace-content-btn">Replace entire HTML</button>
</body>
JS:
With innerHTML you can replaces all html content of element.
document.querySelector('html').innerHTML = '...'
Jquery:
$( document ).ready(function() {
$('html').html('...');
});
find tag content in your string :
function getByTag(tagname,htmlVal) {
var tagHtmValue = $(htmlVal).find(tagname).html();
return tagHtmValue;
}
replace head and and body content with the body and head in your response:
$("head").html(getByTag("head",this.responseTex));
$("body").html(getByTag("body",this.responseTex));
I have tested below code works !...
let responseTxt="<html> \
<head><title>changed hello</title></head><body><h1>Changed body</h1></body></html>"
$(document).ready(()=>{
$(".action").click(()=>{
$("html").html(responseTxt)
});
});
<html>
<head><title>hello</title></head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<h1>hello</h1>
<button class="action">Change HTML</button>
</body>
</html>

How to replace text in a html document using Javascript

I have written this code which I thought was correct, but although it runs without error, nothing is replaced.
Also I am not sure what event I should use to execute the code.
The test a simple template for a landing page. The tokens passed in on the url will be used to replace tags or tokens in the template.
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// gets passed variables frm the url
function getQueryVar(str) {
return 'Newtext'; // JUST SCAFFOLD FOR TESTING
}
function searchReplace() {
/**/
var t = 0;
var tags = Array('keyword', 'locale', 'advert_ID');
if (document.readyState === 'complete') {
var str = document.body.innerText;
for (t = 0; t < tags.length; t++) {
//replace in str every instance of the tag with the correct value
if (tags[t].length > 0) {
var sToken = '{ltoken=' + tags[t] + '}';
var sReplace = getQueryVar(tags[t]);
str.replace(sToken, sReplace);
} else {
var sToken = '{ltoken=' + tags[t] + '}'
var sReplace = '';
str.replace(sToken, sReplace);
//str.replace(/sToken/g,sReplace); //all instances
}
}
document.body.innerText = str;
}
}
</script>
</head>
<body>
<H1> THE HEADING ONE {ltoken=keyword}</H1>
<H2> THE HEADING TWO</H2>
<H3> THE HEADING THREE</H3>
<P>I AM A PARAGRAPH {ltoken=keyword}</P>
<div>TODO write content</div>
<input type="button" onclick="searchReplace('keyword')">
</body>
</html>
So when the documment has finished loading I want to execute this code and it will replace {ltoken=keyword} withe value for keyword returned by getQueryVar.
Currently it replaces nothing, but raises no errors
Your problem is the fact you don't reassign the replacement of the string back to it's parent.
str.replace(sToken,sReplace);
should be
str = str.replace(sToken,sReplace);
The .replace method returns the modified string, it does not perform action on the variable itself.
Use innerHTML instead innerText and instead your for-loop try
tags.forEach(t=> str=str.replace(new RegExp('{ltoken='+ t+'}','g'), getQueryVar(t)))
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// gets passed variables frm the url
function getQueryVar(str)
{
return'Newtext';// JUST SCAFFOLD FOR TESTING
}
function searchReplace() {
/**/
var t=0;
var tags =Array('keyword','locale','advert_ID');
if (document.readyState==='complete'){
var str = document.body.innerHTML;
tags.forEach(t=> str=str.replace(new RegExp('{ltoken='+ t+'}','g'), getQueryVar(t)));
//tags.forEach(t=> str=str.replace(new RegExp('{ltoken='+ tags[t]+'}', 'g'), getQueryVar(tags[t])));
document.body.innerHTML=str;
}
}
</script>
</head>
<body >
<H1> THE HEADING ONE {ltoken=keyword}</H1>
<H2> THE HEADING TWO</H2>
<H3> THE HEADING THREE</H3>
<P>I AM A PARAGRAPH {ltoken=keyword}</P>
<div>TODO write content</div>
<input type ="button" onclick="searchReplace('keyword')" value="Clicke ME">
</body>
</html>

Why the event doesn't execute?

Hey guys could anyone explain why the event doesn't execute?
The debugger doesn't give any error at all!
Thank you in advance
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<button class="boton">prueba</button>
<body>
<script type="text/javascript">
var elemento= document.getElementsByClassName("boton")
elemento.onclick=function(){
alert("hola");
};
debugger;
</script>
</body>
</html>
The DOM method document.getElementsByClassName() returns an array. You must loop through the array items before assigning the onclick handler:
var elemento = document.getElementsByClassName("boton")
for (var i = 0; i < elemento.length; i++) {
elemento[i].onclick = function() {
alert("hola");
};
}
debugger;
<button class="boton">prueba</button>
Alternatively, if you are selecting only one element, you can use document.querySelector():
var elemento = document.querySelector(".boton");
elemento.onclick = function() {
alert("hola");
};
debugger;
<button class="boton">prueba</button>

JavaScript function doesn't change the textarea in Chrome&Firefox but works in IE

I've a web page which include a JavaScript function to convert the multiple lines to a comma separated data. Here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add case</title>
<script type="text/javascript">
function replaceSeperator() {
var incident_box = document.getElementById("TextBoxIncidentID")
var content = incident_box.value;
//incident_box.innerHTML = content.replace(/\n/g, ",");
var ctt = content.replace(/\n/g, ",");
var lastchar = ctt.substr(ctt.length - 1);
if (lastchar != ",") {
incident_box.innerHTML = ctt;
} else {
incident_box.innerHTML = ctt.substr(0,ctt.length - 1);
}
}
</script>
</head>
<body>
<textarea name="TextBoxIncidentID" rows="2" cols="20" id="TextBoxIncidentID" textwrapping="Wrap" acceptreturn="true" onmouseout="replaceSeperator()" style="font-family:Calibri;font-size:Medium;height:60px;width:430px;margin-top: 5px;"></textarea>
</body>
</html>
It works fine in IE:
The line break replaced to comma
But it doesn't working as expected in Chrome and Firefox:
Line break replaced to comma at Dev Tool but it doesn't present on Chrome
Does any one know how to fix it?
Thanks
Use value property. innerHTML is for another purposes. Even textarea has the closing tag, the inner content is the textarea value:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add case</title>
<script type="text/javascript">
function replaceSeperator() {
var incident_box = document.getElementById("TextBoxIncidentID")
var content = incident_box.value;
//incident_box.innerHTML = content.replace(/\n/g, ",");
var ctt = content.replace(/\n/g, ",");
var lastchar = ctt.substr(ctt.length - 1);
if (lastchar != ",") {
incident_box.value = ctt;
} else {
incident_box.value = ctt.substr(0,ctt.length - 1);
}
}
</script>
</head>
<body>
<textarea name="TextBoxIncidentID" rows="2" cols="20" id="TextBoxIncidentID" textwrapping="Wrap" acceptreturn="true" onmouseout="replaceSeperator()" style="font-family:Calibri;font-size:Medium;height:60px;width:430px;margin-top: 5px;"></textarea>
</body>
</html>
You are missing a ; at the end of
var incident_box = document.getElementById("TextBoxIncidentID")
Some browsers are more forgiving to this than others.

Categories