jQuery $.post and searching in the resulting HTML - javascript

I have the following code:
$.post(
url,
send_to,
function(data) {
console.log($(data).find("img");
}
);
I'm getting some result from server and want to find the src value of img tag in that result HTML code, but it's not working.
How I can search for the img tag in the received data?

Your code should work fine. The jQuery function ($(data)) will turn a valid HTML string into a (decoupled) Node tree.
Be aware, though, that find() searches through the descendants of the element or collection of elements on which it is called. If your <img> is in the top level of the HTML, use filter() instead. For example:
<!-- Returned HTML: -->
<p>Here's a nice image of a kitten:</p>
<img src="demonic_kitten.png" />
<p>Muhahahaha!</p>
/* JavaScript (callback function): */
var success = function(data) {
console.log($(data).filter("img");
};
If the <img> is not in the top level, make sure the data that is returned is valid HTML and contains an <img> in the first place.

It's difficult to see where you might be going wrong without some idea of what the data variable contains in terms of HTML. If you're sure it's just an IMG tag that's being returned from the AJAX request, using find will attempt to search through your IMG tag for another IMG altogether, and should be adjusted to this:
console.log($(data).attr("src"));
If it's not just an IMG tag being returned in your HTML, and is a bunch of different tags, I would suggest wrapping your HTML in something like a DIV tag before it's sent back to the Javascript, for example if you're returning something like:
<p>Something</p>
<p>Something else</p>
<img src="something" />
<p>Something</p>
...rather return something like this:
<div>
<p>Something</p>
<p>Something else</p>
<img src="something" />
<p>Something</p>
</div>
...which would also make your original code work. I would also think about adding the dataType option to your jQuery AJAX request:
$.post(
url,
send_to,
function(data) {
console.log($(data).find("img");
},
"html"
);
Hope this helps! :)

Related

Remove HTML Elements from JQuery AJAX load() Response

Is there a possibility to remove specific HTML Elements from a AJAX (load) Response before placing in to the container? In this case I want to remove the "#containerTop", including content, from the response.
Response (HTML):
<html>
<head></head>
<body>
<div id="containerMain">
<div>...</div>
<div id="containerTop">Content-to-remove-including-container-div...</div>
</div>
</body>
</html>
I've tried this, without success.
<div id="middle"></div>
<script>
$( "#middle" ).load( "http://<URL>",
function(response, status, xhr){
$response.remove('#containerTop');
});
</script>
Any ideas?
.load() inserts the content directly for you. It does not give you an opportunity to modify it before it is inserted. As such you have two options:
You can modify the content after it is inserted, but before it is painted in the .load() completion handler.
You can switch to .get() to get the content as data, then put it into a jQuery object, then modify it using jQuery methods, then insert the modified content into your page yourself.
Here's an example of the second option:
$.get("http://<URL>", function(data) {
var temp = $(data);
temp.find('#containerTop').remove();
$('#middle').empty().append(temp);
});
response.find(element).remove()
This works with me

Load HTML within AJAX call

I'm having some difficulty with a Javascript function I am writing. The basic function of the script is that when a specific AJAX function is called and returns successful, it loads some HTML from a file and inserts that HTML into a on the main page and then (once loaded), fades in the parent div.
jQuery.ajax({
type: "POST",
url: "fns/authenticate.php",
data: dataString,
success: function (data) {
if (data=='1') {
jQuery("#authlogin").fadeOut(500, function(){
$(this).remove();
jQuery("#result").load("fns/logic.html", function() {
jQuery('#authtrue').fadeIn(1000);
});
});
} else {
jQuery('#details-error').fadeIn(200);
}
}
});
return false;
Now the AJAX seems to function properly, in that it will execute under the correct conditions and fade out and in the correct divs, the problem seems to be that the content isn't being loaded from logic.html or it is not being bound to the #result div correctly.
The main page's html looks like:
<div id="authlogin">
<!-- HTML form -->
</div>
<div id="authtrue" style="display: none;">
<div id="result"></div>
</div>
Any help would be much appreciated.
This is one of those things that you must troubleshoot yourself, because we do not have access to your fns/logic.html and therefore cannot test fully.
However, some thoughts:
(1) The basic logic of your .load() success function seems correct. Here is a jsFiddle that approximates the AJAX success function's logic. I substituted .html() for .load() because jsFiddle cannot do ajax. Anyway, assuming that .load() is doing what it should, that part should be working.
(2) You may already know this, but note that .load() is shorthand for $.ajax() -- as are .post() and .get(). You might find $.ajax() easier to troubleshoot as the code block is more structured. As a general rule, troubleshooting the shorthand constructions is slightly more abstract/difficult than troubleshooting $.ajax()
(3) Use developer tools in Chrome (press F12 key) to verify that the contents of logic.html have been inserted into the #result div. You might find, as I did in playing with my jsFiddle, that the contents were injected but the #authtrue div remained hidden. At least you will know that the logic.html document has been found and contents inserted. Knowing exactly where the problem is, finding/fixing the rest might now be trivial.
(4) Does your logic.html file include unnecessary header information? If so, you can strip it out by only inserting the BODY of the document, or a top-level containing div. See this section of the jQuery docs:
jQuery("#result").load("fns/logic.html #container", function() {//CALLBACK IN HERE});
(5) It would be a smart idea to create a test document that just and only loads the logic.html document, using various methods:
Method A: Using PHP (or whatever server-side language you use)
<div id="authlogin">
<!-- HTML form -->
<input type="button" id="mybutt" value="Click Me to Start" />
</div>
<div id="authtrue" style="display:none;">
<div id="result"><?php include 'logic.html'; ?></div>
</div>
Method B: Using load()
HTML:
<div id="authlogin">
<!-- HTML form -->
<input type="button" id="mybutt" value="Click Me to Start" />
</div>
<div id="authtrue" style="display:none;">
<div id="result"></div>
</div>
jQuery:
jQuery('#authtrue').show();
jQuery("#result").load("fns/logic.html");
(6) Ensure you do not have a typo in the destination element jquery selector: If no element is matched by the selector — in this case, if the document does not contain an element with id="result" — the Ajax request will not be sent. (from the docs)
I managed to fix this myself, thanks to the help of everyone here. It ended up being a browser caching problem. As soon as I cleared the cache everything magically worked.

Using chance.js to place a random word into html

Im sure this is probably a stupid question...
Im using chance.js because I want the main <h1> on my site to display something different each time you reload the page.
So if i put the following into my functions.js file:
$(window).load(function() {
document.write(chance.pick(['hello', 'GDay']));
});
how to I get the word to appear inside my <h1> </h1> tags in my html file ?
The document.write method will output that text where it is called. If you call it between the tags, it will output that text between the tags.
Give the <h1> tags an ID, like this:
<h1 id="title">text here</h1>
Then, instead of document.write, do something like this:
$("#title").html(chance.pick(['hello', 'GDay']));

Extract all classes from body element of AJAX-ed page and replace current page's body classes

I am in the process of AJAX-ing a WordPress theme with a persistent music player. Wordpress uses dynamic classes on the <body> tag. The basic structure is as follows:
<html>
<head>
</head>
<body class="unique-class-1 unique-class-2 unique-class-3">
<div id="site-container">
<nav class="nav-primary">
Other Page 01
Other Page 02
</nav>
<div class="site-inner">
<p>Site Content Here</p>
</div>
</div>
<div id="music-player"></div>
</body>
</html>
I am currently successfully loading the content of /other-page-01/, /other-page-02/, etc, using load('/other-page-01/ #site-container'). However, I need to extract all <body> classes from the AJAX loaded page and replace the current page's <body> classes with them dynamically.
Note: Replacing the entire <body> element is not an option due to the persistent <div id="music-player">. I've tried jQuery.get(), but couldn't get it to work.
How do I extract the <body> classes from the AJAX requested page and replace the current page's <body> classes with them?
I am not very familiar with jQuery or Javascript, so the exact code would be extremely helpful. Any help is greatly appreciated.
Thanks,
Aaron
My typical solution would have been to tell you to throw the AJAX code in to a jQuery object and then read it out like normal:
$(ajaxResult).attr('class');
Interestingly though, it appears you can't do this with a <body> element.
I'd say the easiest solution (if you have control over the resulting HTML) is to just use some good ol' regex:
var matches = ajaxResult.match(/<body.*class=["']([^"']*)["'].*>/),
classes = matches && matches[1];
I say "if you have control over the resulting HTML", because this relies on the HTML being reasonably well formed.
The other method would involve parsing it as a DOMDocument and then extracting what you need, but this would take a lot more and is usually overkill in simple cases like this.
Convert the body within your returned html to a div with a specific ID, then target that id to get the classes of the body (which is now a div.)
modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div id="re_body"')
.replace(/<\/body/i,'</div');
$(modifiedAjaxResult).filter("#re_body").attr("class");
Of course, if the body has an id, this will conflict with it, so an arbitrary data attribute might be less likely to break.
modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div data-re-id="re_body"')
.replace(/<\/body/i,'</div');
$(modifiedAjaxResult).filter("[data-re-id=re_body]").attr("class");
http://jsfiddle.net/N68St/
Of course, to use this method, you'll have to switch to using $.get instead.
$.get("/other-page-01/",function(ajaxResult){
var modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div data-re-id="re_body"')
.replace(/<\/body/i,'</div');
alert($(modifiedAjaxResult).filter("[data-re-id=re_body]").attr("class"));
// the following line replicates what `.load` was doing.
$(someElement).append( $("<div>").html(ajaxResult).find("#site-container") );
});

How do I write the following as a regular expression to replace multiple occurances?

Background:
I have string of html with about 10 image tags that passes through some JavaScript as a string at runtime before being injected into a containing element. The data-thumb tag of each image is slightly incorrect and needs to be altered before making it into the DOM. Here is an example:
<img src="foo_lg_db.jpg" data-large="foo_lg_db.jpg" />
<img src="bar_lg_db.jpg" data-large="bar_lg_db.jpg" />
<img src="fizz_lg_db.jpg" data-large="fizz_lg_db.jpg" />
Needs to become:
<img src="foo_tn_db.jpg" data-large="foo_lg_db.jpg" />
<img src="bar_tn_db.jpg" data-large="bar_lg_db.jpg" />
<img src="fizz_tn_db.jpg" data-large="fizz_lg_db.jpg" />
Question:
In JavaScript (jQuery is OK), how do I achieve this search and replace?
THE ANSWER:
Thanks to Mark's answer I learned that it is possible to instantiate a jQuery object before it hits the DOM so, rather than using regex, I did something like this:
var stringHtml = "<img . . .";
var div = $("<div>").html(stringHtml );
$.each(div.find('img[src]'), function () {
$(this).attr('src', $(this).attr('src').replace('_lg', ''));
});
return div.html();
$('img[data-thumb]').each(function() {
$(this).attr('data-thumb', $(this).attr('data-thumb').replace('_lg_','_tn_'));
});
Something like that in jQuery.
Sounds like a problem you should be fixing server-side if possible though.
If you give jQuery an HTML element like $('<div>') it will essentially create the HTML element for you and then you can manipulate it before inserting it into your DOM. I don't know if it will handle multiple elements, but you can create a container first (like above) and then set the content like so
$('<div>').html(yourHtml).find('img[data-thumb'])./* code above */

Categories