简体   繁体   中英

Registering event handlers for dynamically added content

So, I have several files:

-- model      -- step1.php
              -- step2.php
-- view       -- main.php
              -- step1.php
              -- step2.php
-- controller -- step1.php
              -- step2.php

Now basically what I'm trying to do is to call step1 view from main.php:

$(document).ready(function(){
    $("#MyForm").validate({
        submitHandler: function(form) {
            $.post('../controller/step1.php', $("#MyForm").serialize(), function(data) {
                $('#step1_controller').html(data);
            });
        }
    });
});

This works, but when you submit the form in main.php step1 controller is executed and step2 view loaded.

Problem is, when I load step2 view via this ajax request, step2 view is no longer able to load step2 controller. When I open step2 view in browser, however, everything works fine and step2 controller is loaded.

main.php -> loads step2.php -> loads step2 controller

  • main.php successfully loads step2 view
  • step2 view successfully loads step2 controller

  • BUT main.php isn't able to load step2 controller

I know this is little confusing but I'll be very thankful if somebody can help me.

Anyway, how do all these pages using these dynamic ajax loaded installation steps work?

You know, you fill out a form in step1, click submit, step2 shows, fill out a form, submit step3 shows. What's the best way?

step2 view:

<script>
$(document).ready(function(){
    $("#Foo").validate({
        submitHandler: function(form) {
                $.post('../controller/step2.php', $("#Foo").serialize(), function(data) {
                $('#results_step2').html(data);
            });
        }
    });
});
</script>


<h1 class="header_step2">Lorem</h1>

<p />

<form name="Foo" id="Foo" action="" method="POST" enctype="multipart/form-data">
<select size="1" name="Bar">
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
</select>

<button type="submit">
<div id="results_step2"> Save </div>
</button>
</form>

The reason your code is not working is that document.ready has already happened by the time you load view2.

A quick fix for this is to attach the validation listener in the success callback that renders the corresponding form. This will allow you to remove your javascript from view2. Ideally, you will probably eventually want to organize your code differently to ease this kind of pain. It is nice to be able to separate javascript from html.

In the meantime, the following should fix your problem:

Option 1

$(document).ready(function(){

    var attachFooValidation = function() {
        $("#Foo").validate({
            submitHandler: function(form) {
                $.post('../controller/step2.php', $("#Foo").serialize(), function(data) {
                    $('#results_step2').html(data);
                });
            }
        });
    }

    $("#MyForm").validate({
        submitHandler: function(form) {
            $.post('../controller/step1.php', $("#MyForm").serialize(), function(data) {
                $('#step1_controller').html(data);
                attachFooValidation();
            });
        }
    });
});

Option 2

if you don't want to do that, you could also just lose the document.ready from view2 and move the script after the form as follows:

<h1 class="header_step2">Lorem</h1>

<p />

<form name="Foo" id="Foo" action="" method="POST" enctype="multipart/form-data">
<select size="1" name="Bar">
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
  <option value="Foo">Bar</option>
</select>

<button type="submit">
<div id="results_step2"> Save </div>
</button>
</form>

<script>
$("#Foo").validate({
    submitHandler: function(form) {
            $.post('../controller/step2.php', $("#Foo").serialize(), function(data) {
            $('#results_step2').html(data);
        });
    }
});
</script>

That said, I recommend reorganizing your code to separate your scripts from your markup.

You need to read up on binding listeners to events in Javascript (jQuery) so that new elements loaded via ajax are correctly handled

Basically as it stands all your code is in the document.ready block, which only runs when the page loads. At that point your step 2 form doesn't exist and so doesn't get the Javascript event bound to it

Something like

$("#MyForm").on('submit', function() {
   $(this).validate({
       // your code here
   });
});

would bind the submit event of all forms with the id #MyForm to the validate code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM