Search code examples
javascriptjqueryfilterfindjquery-filter

JQuery AJax Getting Page Fragments Find vs Filter


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


Solution

  • 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:

    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