1

Im loading a contact page using .load() which contains a script that looks like this:

<script type="text/javascript">

    $('#submit').click(function(e){
        e.preventDefault();
        var name = $('#name').val();
        var email = $('#email').val();
        var message = $('#message').val();
        $.post("<?php echo bloginfo( 'template_directory' ) . '/inc/mailit.php';?>", 
            {
                name: name,
                email: email,
                message: message
            },
            function(data) {
                var n = data.indexOf('<span class="success_message">');
                if (n !== 0) {
                    $('#message_box_1').empty().append(data);
                } else {
                    $('#contact_form').empty().append(data);
                }
            }
        );
    });
</script>

The script works fine when I load the contact page directly (i.e. go to http://example.com/contact-us) but it doesn't when I load the form and script into the dom using .load(). When I click #submit, the form submits without running the script. Any ideas what is going on?

Oh and the load script looks like this:

<script>
$('#top_links a').click(function (e) {
    e.preventDefault();
    var link = $(this).attr('href');
    $('#content').empty();

    $('#content').load(link + ' #content > *');


});
</script>

UPDATE:

Thanks to @pointy for pointing out the problems with .load(). So now I have modified my code to use $.get :

<script>
$('#top_links a').click(function (e) {
    e.preventDefault();
    var link = $(this).attr('href');
    $('#content').empty();


    $.get(link, { }, 
        function(data) {
            $('#content').replaceWith($(data).find("#content"));
        }
    )
});
</script>

The problem is the same, the AJAX Script above still doesn't prevent the form from submitting or send a post request when the user clicks the submit button. I have placed both scripts outside of the content that is being loaded with $.get

Daedalus
  • 7,586
  • 5
  • 36
  • 61
Thomas
  • 5,030
  • 20
  • 67
  • 100
  • Just run an Ajax call and `eval` the result. – Deep Frozen Jul 03 '12 at 23:27
  • @Rune NOOOOOOO, eval is a huge security risk and wouldn't help in this case... – TheZ Jul 03 '12 at 23:30
  • @TheZ Why are people always saying that eval is a huge security risk? As long as the file is on your server and cannot be modified from outside, there wont be a problem since it only evals what you have made?.. – Deep Frozen Jul 03 '12 at 23:33
  • @Rune You can't give such an easy opening http://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea – TheZ Jul 03 '12 at 23:34

2 Answers2

2

When you load with .load() and use a selector after the URL like you're doing, jQuery simply does not run any scripts in the loaded content. It explicitly strips them out and throws them away.

I think the main reason it does this is that, since it's throwing away some portion of the page that's been loaded, it has no idea whether the embedded scripts that are inside the selected content will work without other JavaScript on the page that's not selected.

edit — unfortunately your substitute code will suffer from the same problem. The issue is that $(data) involves converting the returned page HTML into a document fragment. That, internal to jQuery, will go through a function called "clean" that strips out the scripts. It does save them, but they're thrown away by the time that the $(data) function call returns.

It's probably going to be a lot smoother if you can figure out a way for your server to do the work of figuring out that it doesn't have to return a complete page. It'll make things faster anyway; there's no point shipping a complete page when you're going to only use a portion of it.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • If this is the case, it should be easy enough to debug... check for dom elements or print out the returned text from the load. – TheZ Jul 03 '12 at 23:25
  • I've tried adding the script outside of the loaded content, but that doesn't seem to work either. – Thomas Jul 03 '12 at 23:25
  • It is definitely, 100% true, and there's a jQuery bug in the database that I logged on the issue. There's no workaround, really. – Pointy Jul 03 '12 at 23:26
  • @Thomas it doesn't matter where the script is: if you use `.load("http://what/ever #something", ... )` then *no* scripts are run. – Pointy Jul 03 '12 at 23:27
  • Wow - that is a huge bug. Thanks! – Thomas Jul 03 '12 at 23:28
  • @Thomas As he points out (no pun-intended) it's possibly a dependency problem and jQuery is doing what it can to clean up your potential mess. – TheZ Jul 03 '12 at 23:29
  • @Thomas well the library guys are in a tough spot, because "fixing" it would probably cause as many problems as it solved. Note that it *does* run scripts when your URL is *just* a URL, without any trailing selector. – Pointy Jul 03 '12 at 23:30
  • @pointy So, Im just trying to do the same thing using $.get() instead and I geting the same problem. Is it the same issue? – Thomas Jul 03 '12 at 23:35
  • @Thomas Hmm I'm not sure. The library strips out scripts when you call `.html()` but it does run them. It may be that when you build the temporary DOM fragment from your page before pulling out your content, the same thing happens. – Pointy Jul 03 '12 at 23:40
  • @pointy Well, Im using $.get and loading the script outside of the loaded content. Im getting the exact same issue. Is it possible that something else is going on? – Thomas Jul 03 '12 at 23:48
  • Well I'm not sure exactly what you mean; perhaps you could update the question or ask a new one. It's hard/impossible to put extensive code samples in these comments :-) – Pointy Jul 03 '12 at 23:50
0

The problem was that the submit button was dynamically loaded content and I needed to use live(). $("#submit").live("click", function(e){})

Thomas
  • 5,030
  • 20
  • 67
  • 100