jquery ajax parse response text - javascript

Ok this is really frusturating me because I've done this a hundred times before, and this time it isn't working. So I know I'm doing something wrong, I just can't figure it out.
I am using the jQuery .get routine to load html from another file. I don't want to use .load() because it always replaces the children of the element I'm loading content into.
Here is my .get request:
$(document).ready(function() {
$.get('info.html', {}, function(html) {
// debug code
console.log($(html).find('ul').html());
// end debug code
});
});
The file 'info.html' is a standard xhtml file with a proper doctype, and the only thing in the body is a series of ul's that I need to access. For some reason, the find function is giving me a null value.
In firebug, the GET request is showing the proper RESPONSE text and when I run
console.log(html);
Instead of the current console.log line, I get the whole info.html as output, like I would expect.
Any ideas?

You cannot pull in an entire XHTML document. You can only handle tags that exist within the <body> of an html document. Frustrating. Strip everything from info.html that isn't within your <body> tag and try it again.
There are other potential ways around this issue - check below "Stackoverflow Related Items" at the base of this response.
From the Doc: (http://docs.jquery.com/Core/jQuery#htmlownerDocument)
"HTML string cannot contain elements that are invalid within a div, such as
html, head, body, or title elements."
Stackoverflow Related Items:
Simple jQuery ajax example not finding elements in returned HTML
What is the best practice for parsing remote content with jQuery?

I know this is an old post but I've been having the EXACT same frustrating problem for a couple of hours and have found a solution. For me what actually worked was to have the html content wrapped with a form tag.
So having the following html source:
<html>
<head>
<body>
<form>
<div id="content">Some Stuff</div>
</form>
</body>
</head>
</html>
With this jquery snippet should work:
var callback = function (data) {
alert($("#content", $(data)).html());
};
$.get(url, null, callback, null);
Hope this helps...

I have found this being pretty clean solution:
var elementInResponse = $("<div>").html(responseText).find(selector);

Wanting to do the same thing and knowing that JQuery load(..) does it, I had a look in the code. While you can't turn a complete html response directly into a JQuery object, you can append it to one so:
function(data, textStatus, xhr) {
$(target).html(jQuery("<div>").append(data).find("#snippet"));
// Create a dummy div to hold the results,
// inject the contents of the document into it,
// Locate the specified elements
}
The response from the server that goes into data is like:
<! doctype ... >
<html>
<head>
...
</head>
<body>
<div id="snippet">
<p>Some content here that we are interested in</p>
</div>
</body>
</html>

Try including whole body within a <div> tag, e.g. <body><div>content</div></body>.

Related

How to get contents of HTML `object`?

Goal
I want to put a normal tag in my HTML page to grab text from file from a remote file from my own server. Then, javascript will manipulate the text, and display it on the webpage. So JS must be able to grab the contents of the remote file.
The remote file is called "records.html". It's not a complete webpage, just a fragment. It isn't json data.
I prefer a pure HTML solution for pulling the data into the page, if possible.
The remote file is on the same domain as the parent page. It's my html, my JS, my data.
Things i've tried:
object with text/html type
HTML:
<object id="records" type="text/html" data="records.html" ></object>
JS:
window.onload = function getRecords() {
const obj = document.querySelector("#records");
console.log(obj.contentDocument.documentElement.innerText)
};
It fails. I can see the external contents in the browser dev tools, but
the output is blank.
The external HTML file doesn't contain <html>, #document, or <body> tags, but the loaded object content has all those tags. It would be cool to prevent the extra tags, but not critical.
In case it's a race condition, I've read <object> tags don't support an onload event, so i can't get it's contents with a load event.
object with application/json type
This actually works. However, my remote data isn't json. So to use this method, it requires putting non-json data into a file with a .json extension. That seems like very bad form.
<object id="records" type="application/json" data="package.json"></object>
<script>
document.getElementById('records').addEventListener('load', function () {
console.log(this.contentDocument.documentElement.innerText)
})
</script>
link
<link type="text/html" href="records.html">
Doesn't work. I've read this method is deprecated.
iframe
I tried with iFrame but it failed. I may have done it wrong.
XMLHttpRequest + Filesystem API
I believe this has been superceded by JS fetch.
fetch
I haven't had any success wrapping a function around fetch. It's returning a Promise{}, instead of data.
async function fetchText(sURL) {
let response = await fetch(sURL);
let data = await response.text();
return data;
}
contentDocument
For example, this is working for me:
<body>
<object id="records" type="application/json" data="package.json"></object>
<script>
document.getElementById('records').addEventListener('load', function () {
console.log(this.contentDocument.documentElement.innerText)
})
</script>
</body>
If I were doing it, I'd reach for fetch()
<html>
<head>
<title>my neat page</title>
</head>
<body>
<div id="target"></div>
</body>
<script>
const output = document.getElementById("target");
fetch("./myResource.html")
.then((response)=>response.text())
.then((text)=>{/* This is where you manipulate the text response */})
.then((manipulatedText)=>{output.innerHtml=manipulatedText});
</script>
</html>
see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch and https://developer.mozilla.org/en-US/docs/Web/API/Response/text and https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML

jQuery AJAX dataType - HTML and Javascript [duplicate]

this is my page Test1.asp
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>New Page 1</title>
<script type="text/javascript">
function Alex()
{
var xmlHttp;
try
{
xmlHttp=new XMLHttpRequest(); }
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Your browser does not support AJAX!");
return false;
}
}
}
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
document.getElementById("Alex").innerHTML =xmlHttp.responseText;//Get Google Destination Map
}
}
xmlHttp.open("GET","Test2.asp" ,true);
xmlHttp.send(null);
}
</script>
</head>
<body>
<div id ="Alex"></div>
<label onclick="Alex()" >ssss</label>
</body>
</html>
This is requested page Test2.asp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>New Page 1</title>
</head>
<body>
<div id="Mathew"></div>
</body>
<script type="text/javascript" >
{
document.getElementById("Mathew").innerHTML='ajax is working';
}
</script>
</html>
In the page (Test2.asp) javascript is not working
How do i call test2.asp to my test1.asp using ajax
In HTML inserted by Javascript does not execute automatically (at least in IE for sure). The only solution to this is to gather each of the script blocks in the loaded HTML and evaluate them each.
EDIT
I am using YUI here... the Dom class can collect all script tags from within the given block.
var domElement = document.getElementById("Alex");
var scriptBlocks = YAHOO.util.Dom.getElementsBy(function() {return true;},'script',domElement);
for (var i = 0 ; i < scriptBlocks.length ; ++i){
eval(scriptBlocks[i].innerHTML);
}
Simple as that. Also becareful about Internet Explorer... if you load in HTML using ajax, and it comes back with the script block as one of the first elements, it will, for some odd reason, ignore the script block and not include it in the response. To fix it, put a div above the script block with text in it with a style attribute of display:none;
If this is the HTML returned to IE, it will not include the script block in the response
<div>
<script type="text/javascript">
/* Some javascript */
</script>
</div>
This will fix the issue
<div style="display:none;">some text</div>
<div>
<script type="text/javascript">
/* Some javascript */
</script>
</div>
Very weird, but thats how IE rolls.
By default JavaScript contained with AJAX responses is not executed.
There is no point in building an Ajax handler from scratch when this problem has already be solved in various libraries just as jQuery and Prototype.
Use an absolute URI instead of a relative URL.
Adding a <script> element into a document via innerHTML doesn't(*) execute its contents as a script.
You're also trying to insert the entire HTML document, including <html>, <head> and <body> inside a <div>, which is quite invalid.
If you need to return both HTML and some script to execute, better to return a JSON object, eg.:
{
"html": "<div id="Mathew"></div>",
"js": "document.getElementById(\"Mathew\").innerHTML='ajax is working';"
}
then parse the JSON object, set the innerHTML to obj.html and eval the js. (Though it's generally questionable to be returning and executing arbitrary, scripts, there can sometimes be a use for it.)
(*: Well, doesn't generally. Exactly when a <script> element's contents get executed is browser-dependent. For example Firefox executes script when you append/insert a DOM HTMLScriptElement or ancestor into an element that is part of the document, whereas IE executes it when you insert the element into any parent for the first time, whether inside the document or not. In general, avoid inserting JavaScript-in-HTML content into HTML.)
Your methodology is slightly amiss. Typically, AJAX is used to send and receive data in non-HTML formats, such as XML, JSON, or sometimes even CSV (however, HTML is sometimes returned to the client, but usually as pieces of a page, not entire pages as in your example).
Logic is rarely transmitted and is usually maintained on the respective sides of the transmission. In other words, the client/request side has all of its own logic and already knows what to do with the data returned from the server/response side (which also doesn't accept or require any logic generated from the client side). Further, the use of eval, which is usually necessary to consistently execute the logic found in the response, is generally frowned upon and considered a bad practice, thus the saying, "eval is evil."
In some cases, it may be necessary, advantageous or just plain easier to receive logic as part of the response from the server. In these situations however, it is still considered a best practice to separate your data from your logic.
All that to nicely say that you're doing it wrong. I encourage you to read up on how AJAX works and how best to use it: w3schools walk-through, Mozilla MDC intro, AJAX and XML processing, updating a page (similar to what I think you're trying to do), and finally, AJAX API docs for jQuery, Prototype and Dojo.
Prototype has a nice way of handling this. See their stripScripts, extractStrips, and evalScripts methods on the String object. If you just strip the scripts, put your text into a div and then evalScripts, that'll work across all brwosers so scripts get executed exactly once.

how is PHP distorting my HTML?

I've been running into some problems that seem to arise from making my questionnaire a .PHP file rather than an .HTML. The reason I had to do this is because I'm using a PHP script for working with an SQL database and I had to include them into the Questionnaire, which won't work as an HTML.
In the HTML version everything runs perfectly the way I coded it. When I saved it as a .php file my javascript stopped working properly and I tried linking the javascript at the bottom of the body tag instead of the head and that still didn't help.
After a lot of going back and forth trying to see what's different I decided to save the .php file as an html just for grins and giggles to see if I still got the same problems. Oddly enough, it runs just as smooth as the other HTML file.
here's links to all 3 versions so you can see what I mean.
HTML v1
PHP
HTML v2
In the JS Console I got this error
Uncaught TypeError: Cannot set property 'onClick' of null
which referred me to line 163 of my .js file which is referencing the "next" button of the first page of the Questionnaire (not intro page that loads up but the next page where you actually input data).
The way I have the Questionnaire structured in the .PHP file is
<?php ini_set('display_errors','on'); ?><?php include('extlib/vdaemon/vdaemon.php'); ?><!doctype html>
<html>
<head>
//links to files etc.//
</head>
<header>
</header>
<body>
<form action="core/process.php" method="post" id="CorpID" runat="vdaemon">
<input type="hidden" name="formID" value="Questionnaire" />
<input type="hidden" name="redirect_to" value="http://optiqvision.x10host.com/Corp_ID_&_Branding_Questionnaire.html" />
//all form inputs//
</form>
<?php VDEnd(); ?>
</body>
<footer>
</footer>
</html>
The entire Questionnaire has well over 100 individual inputs so I didn't want to put all of them in this snippet. I just wanted to show the over all structure, plus I figured you could get more details in the browser from clicking on them and looking at the debugger to see more of what's going on. Can anyone identify what I'm doing wrong with the PHP? I really don't understand why it's messing up the way it is.
In your html the code for the textarea is like this:
<textarea id="my_comp" class="tex_inp01" style="width:88%; height:100px; font-size:14pt;"></textarea>
In your php the
The textarea closing tag is misplaced; coming after a lot of div's including the element with the id=p1_next. SO the divs just become part of the textarea value instead of being part of the HTML page
Edit: Looks like the real problem is that the DOM is broken. In your PHP file, you have a self-closed textarea tag. textarea tags need a closing tag.
<!-- you have this, it's not syntactically correct -->
<textarea id="my_comp" class="tex_inp01" style="width:88%; height:100px; font-size:14pt;" />
<!-- the following is correct -->
<textarea id="my_comp" class="tex_inp01" style="width:88%; height:100px; font-size:14pt;"></textarea>
Put Corp_ID_&_Branding_Questionnaire.js right before the body tag and it will work. The reason the PHP file is throwing a javascript error is because the node "p1_next" doesn't exist at runtime since your JS is in the head tag.
The reason it's working in the HTML file is mainly thanks to luck. The static HTML is loading fast enough that the DOM is ready by the time your JS code is running. As a thumb of rule, generally include all your JS right before the body tag. There are of course some exceptions.
If you really need to include your script in the head, you can wait until the DOM is ready by wrapping all your code with this:
$(document).ready(function() {
console.log( "ready!" );
// your JS code here
});
Last, if you're going to be using jQuery as a library, then it is recommended to use jQuery syntax instead of native JS. Just make sure to include the jQuery JS before your code.
var p1a = document.getElementById("p1_next");
// becomes:
var p1a = $('#p1_next'); // jQuery node by CSS selector
Before the end of the body tag like this:
<html>
<head>
..your code ..
</head>
<body>
..your code ..
<script type="text/javascript" src="http://www.optiqvision.x10host.com/Files/Javascript/Corp_ID_&_Branding_Questionnaire.js"></script>
</body>
</html>

Best way to fire events when single elements in the document becomes ready

I'm developing a web application that because of performance concerns is heavily reliant on Ajax functionality. I'm attempting to make parts of each page available while longer running modules load.
The issue is that I want to kick off the Ajax requests as soon as possible (in the head of the document). This part works fine; the issue is on rare occasion, the Ajax call will come back before the area that I want to load the Ajax data into is present on the page. This causes the data to not be loaded.
To get around the issue I started using script tags below each of my containers that resolve a JQuery promise to let the code know that the area is available.
EDIT: I want to load the data into the area as soon as it becomes available (before full document load).
The current pseudo code looks like this:
<head>
<script>
var areaAvailablePromise = new $.Deferred();
$.when(areaAvailablePromise, myAjaxFunction()).then(function(){
// load data into the element.
});
</script>
</head>
<!-- much later in the document -->
<div class="divIWantToLoadAjaxContentInto"></div>
<script>
areaAvailablePromise.resolve();
</script>
My question is: is there ANY better way to handle this situation? Every one knows that inline scripts are blocking and are bad for performance. Also, I feel that this is going to lead to cluttered code with micro-script tags all over the place.
Put your (whole) <script> tag just after the element.
HTML is parsed from top to bottom, so the element will be loaded already.
No. There really is no better way to my knowledge.
<!doctype html>
<html>
<head>
<script src="jquery.min.js"></script>
<script src="q.min.js"></script>
<script>
var elD = Q.defer();
var dataP = Q($.ajax(…));
Q.spread([elD.promise, dataP], function (el, data) {
…
}).done();
</script>
</head>
<body>
…
<div id="foo"></div>
<script>elD.resolve($("#foo"));</script>
…
</body>
</html>
you can use:
$(document).ready( handler )
(recommended)and also has contracted form:
$(handler)
exemple:
$(function(){
alert("OK");
})
read more: http://api.jquery.com/ready/

JQuery JSON data not displaying

I am having trouble displaying some jason from a page.
The data is there but I think it might have to do with this line:
document.write(fbResults.cats[0].title);
Here is the full html source:
<!DOCTYPE HTML>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
$.getJSON('http://mydomain.com/api/get_cats', function(fbResults) {
document.write(fbResults.cats[0].title);
});
});
</script>
</head>
<body>
</body>
</html>
And here is the data that it's reading:
{"cats":[
{"id":"1","title":"mytitle1","colour":"#EE297C"},
{"id":"2","title":"mytitle2","colour":"#EE412F"},
{"id":"3","title":"mytitle3","colour":"#F5821F"},
{"id":"4","title":"mytitle4","colour":"#00AEEF"},
{"id":"5","title":"mytitle5","colour":"#00B495"},
{"id":"6","title":"mytitle6","colour":"#006476"}
]}
It is not displaying anything on the page.
On firebug console I get this error:
The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must to be declared in the document or in the transfer protocol.
No traces of the json data there
What I'm I doing whong?
You shouldn't document.write after the page has loaded (which is certainly the case here).
If you want to write it to the page, you'll need to create HTML and append it. Just replace the document.write:
$('body').append('<p>'+fbResults.cats[0].title+'</p>');
Update:
Your example makes a fully qualified URL call. Is that server the exact same one that you're running the page from? If it isn't the XHR will just eat the request (and sometime not tell you). If you need to go cross domain, you'll need to use JSONp. If you're attempting to run this locally while pulling data from the net, it'll break.
Try this
$.each(fbResults.cats,function(index,item){
document.write(item.title);
});
Working sample : http://jsfiddle.net/zWhEE/8/
its seems work for me please check this
http://jsfiddle.net/TxTCs/1/

Categories