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>
Related
I know this has been asked a lot on here, but all the answers work only with jQuery and I need a solution without it.
So after I do something, my Servlet leads me to a JSP page. My JS function should populate a drop down list when the page is loaded. It only works properly when the page is refreshed tho.
As I understand this is happening because I want to populate, using innerHTML and the JS function gets called faster then my HTML page.
I also get this error in my Browser:
Uncaught TypeError: Cannot read property 'innerHTML' of null
at XMLHttpRequest.xmlHttpRequest.onreadystatechange
I had a soulution for debugging but I can't leave it in there. What I did was, every time I opened that page I automatically refreshed the whole page. But my browser asked me every time if I wanted to do this. So that is not a solution that's pretty to say the least.
Is there something I could do to prevent this?
Edit:
document.addEventListener("DOMContentLoaded", pupulateDropDown);
function pupulateDropDown() {
var servletURL = "./KategorienHolen"
let xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {
console.log(xmlHttpRequest.responseText);
let katGetter = JSON.parse(xmlHttpRequest.responseText);
JSON.stringify(katGetter);
var i;
for(i = 0; i <= katGetter.length -1; i++){
console.log(katGetter[i].id);
console.log(katGetter[i].kategorie);
console.log(katGetter[i].oberkategorie);
if (katGetter[i].oberkategorie === "B") {
document.getElementById("BKat").innerHTML += "" + katGetter[i].kategorie + "</br>";
} else if (katGetter[i].oberkategorie === "S") {
document.getElementById("SKat").innerHTML += "" + katGetter[i].kategorie + "</br>";
} else if (katGetter[i].oberkategorie ==="A") {
document.getElementById("ACat").innerHTML += "" + katGetter[i].kategorie + "</br>";
}
// document.getElementsByClassName("innerDiv").innerHTML = "" + katGetter.kategorie + "";
// document.getElementById("test123").innerHTML = "" + katGetter.kategorie + "";
}
}
};
xmlHttpRequest.open("GET", servletURL, true);
xmlHttpRequest.send();
}
It can depend on how + when you're executing the code.
<html>
<head>
<title>In Head Not Working</title>
<!-- WILL NOT WORK -->
<!--<script>
const p = document.querySelector('p');
p.innerHTML = 'Replaced!';
</script>-->
</head>
<body>
<p>Replace This</p>
<!-- Will work because the page has finished loading and this is the last thing to load on the page so it can find other elements -->
<script>
const p = document.querySelector('p');
p.innerHTML = 'Replaced!';
</script>
</body>
</html>
Additionally you could add an Event handler so when the window is fully loaded, you can then find the DOM element.
<html>
<head>
<title>In Head Working</title>
<script>
window.addEventListener('load', function () {
const p = document.querySelector('p');
p.innerHTML = 'Replaced!';
});
</script>
</head>
<body>
<p>Replace This</p>
</body>
</html>
Define your function and add an onload event to body:
<body onload="pupulateDropDown()">
<!-- ... -->
</body>
Script needs to be loaded again, I tried many options but <iframe/> works better in my case. You may try to npm import for library related to your script or you can use the following code.
<iframe
srcDoc={`
<!doctype html>
<html>
<head>
<style>[Style (If you want to)]</style>
</head>
<body>
<div>
[Your data]
<script type="text/javascript" src="[Script source]"></script>
</div>
</body>
</html>
`}
/>
Inside srcDoc, it's similar to normal HTML code.
You can load data by using ${[Your Data]} inside srcDoc.
It should work :
document.addEventListener("DOMContentLoaded", function(){
//....
});
You should be using the DOMContentLoaded event to run your code only when the document has been completely loaded and all elements have been parsed.
window.addEventListener("DOMContentLoaded", function(){
//your code here
});
Alternatively, place your script tag right before the ending body tag.
<body>
<!--body content...-->
<script>
//your code here
</script>
</body>
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>
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.
In an iframe when loading content dynamically, the sequence document.open, document.write, and document.close fails in IE 9, 10, and 11 but succeeds in other browsers. However, if I assign document to a temporary variable and then do open, write, close, IE succeeds. Why is this?
(Yes, I know that there are better options besides document.open/write/close, like jquery and DOM construction, but I am curious why this fails.)
The following files show the problem:
index.htm
<!DOCTYPE html>
<html>
<head>
<title>Top Window</title>
</head>
<body>
<p>Top Window</p>
<div id="testDiv" style="width: 100%;">
<iframe src="frame.htm" style="width: 100%;"></iframe>
</div>
</body>
</html>
frame.htm
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<p>Waiting...</p>
</body>
</html>
script.js
'use strict';
var getPage = function() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if( (this.readyState == 4) && (this.status == 200) ) {
writePage( this, "" + this.responseText );
}
};
xmlhttp.open("GET", "content.htm", true);
xmlhttp.send();
};
var writePage = function( xmlhttp, pageContent ) {
var tempDocument = document;
document.open( "text/html" );
document.write( pageContent );
document.close();
};
getPage();
content.htm
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>This is my written content.</h1>
</body>
</html>
In the writePage function, this sequence does not work (the document.open call does not return):
document.open( "text/html" );
document.write( pageContent );
document.close();
However, using the temporary reference like this:
tempDocument.open( "text/html" );
tempDocument.write( pageContent );
tempDocument.close();
works fine.
I am testing putting a text editor on my page and storing it as part of a JSON object.
HTML
<!DOCTYPE html>
<html>
<head>
<script src="http://tinymce.cachefly.net/4.0/tinymce.min.js" type="text/javascript"> </script>
<script type="text/javascript">
tinymce.init({
selector: "textarea"
});
</script>
<link rel="stylesheet" href="/jquery.mobile-1.3.2.min.css"/>
<script src="/jquery-1.9.1.min.js"></script>
<script src="/jquery.mobile-1.3.2.min.js"></script>
</head>
<body>
<form method="post" action="formSubmit.js">
<textarea name ="editor"></textarea>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
JS
$(document).ready(function () {
var text = $("editor").val();
var name = "project name";
var id = 5;
var item = new item(name, text, id);
var itemArray = localStorage.items;
if (itemArray == undefined) {
itemArray = [];
} else {
itemArray = JSON.parse(itemArray);
}
itemArray.push(item);
localStorage.items = JSON.stringify(itemArray);
});
I want to be able to store item in a JSON object. When I run this I receive a "not-well formed" error at line 1 of the Javascript. It's a very simple program I'm running and can't seem to pinpoint what is causing the error. Is the JSON done incorrectly or are scripts in my HTML header causing issues?
$("editor") is looking for an html tag called 'editor'. you probably want to attach an id attribute to your and do $('#editor')