I wrote a script and I want to change the language. I managed to do this using the .ajax() function in jQuery and fetching the new HTML.
Afterwards I want to replace the old HTML with the new HTML.
However, I do not want to exchange the whole HTML, but only part of it.
I know that the HTML returned includes a <div id="myDivId">...</div>, so I only want to get the content of that div from the HTML returned, and replace the content of my current div with the new content.
But, I can't seem to figure out how to fetch only that content from my new HTML. How can I do that? I tried using find, but no success.
$.ajax({
type: "GET",
url: "ajax.php",
data: "action=languagepack&subAction=box&newIso="+newIso+"&country="+country,
success: function(htmlCode){
var box = $(htmlCode).find('#myDivId').html();
alert(box);
}
});
Best regards,
Paul Peelen
Try jQuery.load()
This method is the simplest way to
fetch data from the server. It is
roughly equivalent to $.get(url, data,
success) except that it is a method
rather than global function and it has
an implicit callback function. When a
successful response is detected (i.e.
when textStatus is "success" or
"notmodified"), .load() sets the HTML
contents of the matched element to the
returned data. This means that most
uses of the method can be quite
simple:
$('#result').load('ajax/test.html');
Loading Page Fragments
The .load() method, unlike $.get(), allows us to specify a
portion of the remote document to be
inserted. This is achieved with a
special syntax for the url parameter.
If one or more space characters are
included in the string, the portion of
the string following the first space
is assumed to be a jQuery selector
that determines the content to be
loaded.
We could modify the example above to use only part of the document that
is fetched:
$('#result').load('ajax/test.html #container');
If you need HTML from only one container - then load is recommended way certainly. If you need some additional custom processing - are you sure that #myDivId inside blocks given from server and not one of these blocks? In the 2nd case you need filter inside of find (or wrap all HTML into some div to be sure that all elements will be inside it and won't be top level elements).
Shoot that through a php, run a explode change the contents, recreate the div, replace it where you want.
You can do all this with ajax too, but trigger the php file
try this with returned html:
var d = $("<div/>");
$(d).html(msg.d);
var box = $(d).find("#testDiv").html();
alert(box);
Related
When I console.log(data) from my ajax callback, it returns the entire html file which includes scripts, css etc which breaks my page. How can I get only the element block which I need? I only need the data within .container.
I think easiest way is to use jquery load function. There is possibility to take only fragment of loaded page.
http://api.jquery.com/load/
I would do this using regular expressions.
For example, if you wanted to get the content of all .container elements, you could try this regexp:
<[^>]+class="container"[^>]*>([^<]+)<\/[^>]+>
and then collect the captured groups.
See working example on Regex101.com.
Easiest way would be append in hidden tag. Then search for using $(".container")
it will return the whole div and you can get html .
Here is script code that can help you
(use jquery library)
var b= $(".container");
console.log(b[0].outerHTML);
PLEASE CHECK THIS BELOW FIDDLE
http://jsfiddle.net/oyvv9nL0/
Let's say you're retrieving a complete HTML page using Ajax. You now have a page of HTML in a variable.
Assuming you need to find and extract some data from that page, how do you do it?
Traditionally I've done this using regular expressions, but I'm wondering if there's a way to perform jQuery operations on that retrieved source code instead. It would simplify things tremendously, as jQuery is built for parsing HTML DOM trees.
I'm thinking maybe appending the retrieved source to the current page DOM in hidden form...? Is there a better way?
jQuerys parseHTML might be what you are looking for: http://api.jquery.com/jquery.parsehtml/
If I understand you well, you have the html code of the page loaded through ajax in a variable (let's call it data), and then you want to search through it using jquery operations.
You could create a container in your first html page, and then fill it with the content returned by Ajax. You can then handle it normally with jQuery
So:
<body>
<div id="first_page">
<h3>First page</h3>
<p>This the page that makes the Ajax call</p>
</div>
<div id="ajax_container"></div>
</body>
Now, after you Ajax call, you fill the container with data
$("#container").html(data);
Then, you can use .find(), or simply write an appropriate jquery selector.
var a = $("#container").find("#my_id").html;
var b = $("#container #my_id").html();
Now a and b should contain the content from the element with id my_id from the page loaded with Ajax
PS: I'm not sure if you want to append the data to you current page. You don't have to, if that's not what you are trying to achieve.
Here's the the form the Ajax code I am testing.
$('body').on('submit','#sign-in', function(e) {
e.preventDefault();
var data = $(this).serialize();
var url = $(this).attr('action');
$.ajax({
//this is the php file that processes the data and send mail
url : url,
type : "POST",
data : data,
dataType:"html",
//Do not cache the page
cache : false,
//success
success : function(response,status) {
console.log($(response).filter('#dashboard'));
console.log($(response).find('#dashboard').html());
}
});
});
Here is the response.
<!DOCTYPE html>
<%# taglib prefix="s" uri="/struts-tags"%>
<html>
<body>
<div id = "dashboard">
<div id = "dash2">
<h1>HELLO</h1>
</div>
</div>
</body>
</html>
Based from the code above upon, success jQuery filter was able to fetch the div with an id #dashboard however find return me an undefined.
Why is it working like that?
For your information, I am using JQuery 1.9
UPDATE
Using the suggestion of Bergi, I have removed the html,body and head tag of the returned html and this is the error I received.
Uncaught Error: Syntax error, unrecognized expression:
HELLO
HELLO FITCCHHH
jquery-1.9.0.min.js:2
jQuery sets your whole page as the innerHTML of a <div>, and therefore doctype, html, head and body elements are not parsed. You only get back a collection of the resulting elements, and since your #dashboard is one of these top-level elements you need to filter instead of find.
See also:
Parse complete html page with jquery
Scrape an HTML Document with jQuery, is it possible?
I'm not sure how to solve this, apparently there's much jQuery quirks around there. What I can think of:
try jQuery.parseXML
rely on filter getting the element in question out of the jQuery collection. Though, since browsers seem not to be consistent about what the parse you should do something like $response[$response.is("#dashboard") ? "filter" : "find"]("#dashboard")
Append the malformed collection to some element and find from there: $("<div/>").html(response).find("#dashboard")
wait for jQuery.parseHTML
do not send a whole HTML document, but only the #dashboard element you're interested in as a html string
If you are using jquery 1.9 , you should no-longer parse html like so:
var html = $(response);
Instead you should be using the following:
var html = $.parseHTML(response);
html = $(html).find('#dashboard').html();
From Jquery Docs 1.9:
HTML strings passed to jQuery() that start with something other than a less-than character will be interpreted as a selector. Since the string usually cannot be interpreted as a selector, the most likely result will be an "invalid selector syntax" error thrown by the Sizzle selector engine. Use jQuery.parseHTML() to parse arbitrary HTML.
You should use parseHTML as indicated above. The difference between filter and find appears to be where the element is in the returned HTML snippet. If you are looking for #foo then use .filter('#foo') if #foo is a top-level element in the returned HTML and .find('#foo') otherwise.
On my website I have a CKEDITOR to publish content. I have build an automatic save function when you switch pages that looks like this:
var oEditor = CKEDITOR.instances.text;
var content = oEditor.getData();
$('#form #text').html(content);
$.post("news/save/" + id + "/" + page, $("#form").serialize());
This gets the current content of the editor, places it in the textarea (it did not always do that automatically apparently). Then serializes the entire form and posts it to my website's save page.
This is works except for when I put youtube code inside the editor. Printing out the following works without any problems (after the content was set):
alert($('#form #text').html());
This would just prints the actual content with the youtube code. But when the .serialize() functions is called the content gets empty.
alert($('#form #text').serialize());
This would just print: "text=%0A".
Can anybody help me fix this problem or suggest another way to post the form's content to the save page?
Thank you.
Is #text is a textarea? if it is then you should probably using val() method to set the value instead of html(), because val() should be used to set/get form element's value.
You should call editor's synchronize procedure, that synchronizes editor contents with the value of the textarea.
After that, the value will be available for serialization as well.
So, I see so many people wondering how to execute JS code returned via ajax. I wish I had that problem. My JS executes, but I don't want it too!
Using jQuery 1.4.2, I'm making a GET request:
$.ajax({
url:'/myurl/',
type:'GET',
success:function(response){
$('body').html(response);
}
});
The response looks something like:
<p>Some content</p>
<script>alert("hi!");</script>
Whenever the success callback fires and the response is injected into the DOM, the alert code fires! I don't want that to happen. What can I do to prevent this?
If you can't modify the response, try to "replace" <script> tags:
"<script>alert('hi');</script>".replace(/<(\/?script)/gi, "<$1");
This should escape the tags, making they appear as plain text instead of executing.
Related links
jQuery: Parse/Manipulate HTML without executing scripts
XSS Cheat Sheet
did you try returning function() snippets like
<script>
function Hello(){
alert('Hello');
}
</script>
This way the your JS doesn't execute right away but can be called later when required. But, again it depends what you actually want to do.
Depends. Do you need the JavaScript, or can you just get rid of it? If you don't need it at all, you could do something like
response = response.replace(/<script.*?<\/script>/gi, "");
However, if you need it, you're going to need to figure out how to kill just the function call(s) that you don't want. Using your example of an alert:
response = response.replace(/alert\(.*?\)/gi, "alert");
By getting rid of the trailing parens, and whatever they contain, you stop the function call from happening. Obviously, what you'll need in your regex will depend on the actual code that's causing the problem.
$('body').html(response.replace(/(<script)[^\>]*/g,'$1 src="emptyfile.js"'));
where emptyfile.js exists but has no content.
The problem you have is that jQuery strips script tags from the html and creates a document fragment.
To elaborate
var e = $("<div>Hello</div><script>alert('hi')</script>")
e.html(); // will not display script tags as script tags are now in a document fragment
$("body").append(e); // will execute the script tags in the fragment
See John Resig's explanation and another forum post on this topic.
So, what you can do is
var e = $("<div>Hello</div><script>alert('hi')</script>")
e.filter("script").each(function(){this.text='';});
That would basically make all the scripts empty and now you can
$("body").append(e);
See this post for the fragment creating routine.