如何在jQuery脚本被调用一次之后重新绑定它?

I have three things going on:

I am sending information with this form.

<form method="post" id="myForm" action="includes/functions.php">
    <input type="hidden" name="group_id" value="$group_id" />
    <input type="hidden" name="submit_join"/>
    <button class="request" id="sub" name="submit_join">Join</button>
</form>

This jQuery script runs a PHP script.

$("#sub").click(function() {
 $.post( $("#myForm").attr("action"), 
         $("#myForm :input").serializeArray(), 
         function(){ $("#sub").html("Applied").fadeIn().addClass("applied").removeClass("request"); 
   });
});
$("#myForm").submit(function() {
  return false; 
});

This is what the PHP script does. (Not a prepared statement)

if (isset($_POST['submit_join'])) {
  //User ID
  $user_id = $_SESSION['user_id'];
  $group_id = $_POST['group_id'];

  $sql="INSERT INTO group_assoc (user_id, group_id, permission, dateTime) VALUES ('$user_id', '$group_id', 0, now())";
  if (!mysqli_query($connection, $sql)) {
    die('Error: ' . mysqli_error($connection));
  }
}

-It works just fine when someone clicks the button once.

  • It triggers the jQuery script
  • The jQuery script triggers the PHP script
  • The PHP does its job
  • The jQuery removes the class "request" and puts a class "applied"

Problem: When the same user clicks another button (meaning a duplicate of the button that they just clicked), the page ignores the jQuery script and does what it would normally do, refresh the page. This is the unwanted process.

Why several forms and therefore why several buttons? I am doing a PHP while loop for every group in the website and every form contains a button (Join) that allows you to join the group and change the value on the database using the jQuery script above.

Question: How can I rebind the jQuery script so that when another button (<button class="request" id="sub" name="submit_join">Join</button>) is clicked, it will not ignore the jQuery script?

The problem seems to be that you are working with duplicate IDs, try with classes instead of id

<form method="post" class="myForm" action="includes/functions.php">
    <input type="hidden" name="group_id" value="$group_id" />
    <input type="hidden" name="submit_join" />
    <button class="request" class="sub" name="submit_join">Join</button>
</form>

and

$(document).on('submit', '.myForm', function () {
    return false;
})
$(document).on('submit', '.sub', function () {
    var $form = $(this).closest('form');
    $.post($form.attr("action"),
    $form.serializeArray(), function () {
        $("#sub").html("Applied").fadeIn().addClass("applied").removeClass("request");
    });
})

Its always a good idea to pass in the event to the event handler, and do a event.preventDefault() to avoid browser's default behaviour on the elements.

$("#myForm").submit(function(event) {
  event.preventDefault(); 
});

As for the multiple forms, you can use one handler to handle form submits. $('#sub') will bind to only the first button on the page, use a class to attach to multiple buttons of the same type which will still be inefficient. Here is a sample :

$('.subbtn').click(function(e){
    var $form = $(this).parents('form'),
        subUrl = $form.attr('action');    

    e.preventDefault();
    $.post(...)  ;  
})

This handler should take care of your requirement. You can however use a single handler attached to the common wrapper of the forms (worst case 'body') to improve efficiency.

Like what jagzviruz said, it's always best to use the submit event's event handler to prevent the page refresh. And also, make sure you don't have any duplicate element IDs.

My approach would be something like this: (untested)

HTML

<form method="post" class="myForm" action="includes/functions.php">
<input type="hidden" name="group_id" value="$group_id" />
<input type="hidden" name="submit_join"/>
<button class="request" class="submit" name="submit_join">Join</button>

JS

$(".myForm").each(function() {
    var $form = $(this),
        action = $form.attr('action'),
        $submit = $form.find('.submit');

    $form.submit(function(event) {
        event.preventDefault();

        return false;
    });

    $submit.click(function(event) {
        event.preventDefault();

        $.post(...);
    });
});

It's pretty much the same solution as what jagzviruz proposed, but I prefer to do things like this inside an .each() for clarity.