PHP foreach循环内Ajax表单提交的唯一标识问题
Hey there! Let's fix this issue step by step. The core problem here is that you're using unique IDs (avail_submit_form, signup) across multiple form instances generated by the foreach loop — but IDs can only exist once per page. That's why only the first form works, and your success message can't target the right element.
1. Fix the HTML: Replace IDs with Classes
First, update your PHP-generated HTML to use classes instead of IDs for the form and success container. Classes let us target all repeated instances properly, while we can keep the data-tmid attribute for extra context if needed.
Modified PHP/HTML snippet:
<?php if (isset($_SESSION['team_mem_id'])) { $query_team_matches = $conn->prepare($sql_team_matches); $query_team_matches->bindParam(':tid', $tid, PDO::PARAM_INT); $query_team_matches->execute(); $matches = $query_team_matches->fetchAll(PDO::FETCH_ASSOC); if (!empty($matches)) { foreach($matches as $Matches) { $tmid = $Matches['tmid']; $opponent = $Matches['opponent']; $location = $Matches['location']; $tm_datetime = $Matches['tm_datetime']; $match_date = date("F j",strtotime($tm_datetime)); $match_time = date("g:i A",strtotime($tm_datetime)); $match_when = $match_date. " @ ".$match_time; ?> <div class='match_container'> <div class='match_basic_info'> <h3><?php echo $match_when.' - <span style="font-size: 16px">'.$location.' vs '.$opponent; ?></span></h3> <a class='match_details_link' href='http://localhost:1234/tennisexcel/teams/match.php?r=team&tid=<?php echo $tid; ?>&tmid=<?php echo $tmid; ?>'>More info...</a> </div> <div class='match_avail_container'> <h3>My availability:</h3> <!-- Swap id for class --> <form class='avail_submit_form' data-tmid='<?php echo $tmid; ?>' action='http://localhost:1234/tennisexcel/test_ajax.php' method='POST'> <input type='hidden' name='uid' value='<?php echo $_SESSION['uid']; ?>'/> <input type='hidden' name='tid' value='<?php echo $_SESSION['tid']; ?>'> <input type='hidden' name='tmid' value='<?php echo $tmid; ?>'> <button class='match_avail_yes' type='submit' name='availability' value='1'>✔</button> <button class='match_avail_no' type='submit' name='availability' value='2'>✖</button> </form> <!-- Swap id for class --> <div class='signup match_avail_success success_display' data-tmid='<?php echo $tmid; ?>'> <p>success!</p> </div> </div> </div> <?php } } } ?>
2. Update the jQuery: Target Relative Elements
Now adjust your jQuery to bind the submit event to all forms with the avail_submit_form class. Use $(this) to reference the specific form that was submitted, then traverse the DOM to find its corresponding success container (this is more reliable than relying solely on data attributes).
Modified jQuery code:
$(document).ready(function() { // Bind submit event to every form instance $('.avail_submit_form').submit(function(evt) { evt.preventDefault(); var $form = $(this); // Store reference to the submitted form var url = $form.attr('action'); var formData = $form.serialize(); $.post(url, formData, function(response) { // Hide the exact form that was submitted $form.hide(); // Find the sibling success container and show it $form.siblings('.signup').removeClass('success_display'); // If you prefer using data-tmid instead of sibling traversal: // var tmid = $form.data('tmid'); // $('.signup[data-tmid="' + tmid + '"]').removeClass('success_display'); }); }); });
Why This Works:
- Classes over IDs: Using
.avail_submit_formensures we bind the event to every form generated by the loop, not just the first one. - Relative DOM traversal:
$form.siblings('.signup')targets the success container directly associated with the submitted form, so we don't have to worry about matchingdata-tmidvalues manually. $(this)context: Storing$(this)in$formkeeps a reference to the exact form that was submitted, ensuring all actions (hiding the form, showing success) only apply to that specific instance.
内容的提问来源于stack exchange,提问作者BL10s

