1

I have a for each loop that outputs notes along with upvotes/downvotes that share a relationship with the notes, it works fine but I can have a lot of these forms being dynamically recreated, The only way I can use ajax to post a specific form is by foreach looping the Ajax script along with the form, so that the id's of the form in the ajax script are unique.

I'd like to remove the bloat from the Ajax script and just use a single request to post the data, but I can't figure out how to post a specific form without using unique ID's.

@foreach ($getNotesAll as $getnotes)

<p class="notes">{{$getnotes->body}}</p>

<?php $formRand = rand(); ?>

<form class="vote-form" id="upvote-form{{$formRand}}" method="post" 
action="/notes/vote">

<button type="submit" form="upvote-form{{$formRand}}" id="vote-up{{$formRand}}" 
class="vote-btn upvote"></button>

  <input type="hidden" name="type" value="1">
  <input type="hidden" name="voteid" value="{{$_SESSION['user_id']}}">
  <input type="hidden" name="noteUniqueID" value="{{$getnotes->noteUnique}}">
  <input type="hidden" name="noteid" value="{{$getnotes->user_id}}">

  {{csrf_field()}}
  </form>



  <form class="vote-form" id="downvote-form{{$formRand}}" method="post" 
  action="/notes/vote">

  <button type="submit" form="downvote-form{{$formRand}}" id="vote-
  down{{$formRand}}" class="vote-btn"></button> 

  <input type="hidden" name="type" value="0">
  <input type="hidden" name="voteid" value="{{$_SESSION['user_id']}}">
  <input type="hidden" name="noteid" value="{{$getnotes->user_id}}">
  <input type="hidden" name="noteUniqueID" value="{{$getnotes->noteUnique}}">
  {{csrf_field()}}
  </form> 



 <?php

  echo "<script>
   $( '#downvote-form". $formRand . "' ).on( 'submit', function(e) {
    e.preventDefault(); 
     $.ajax({
       type: 'POST',
       url: '/notes/vote',
       data: $(this).serialize(),
       success: function( msg ) {

      }
   });
 });


  $( '#upvote-form".$formRand."' ).on( 'submit', function(e) {
    e.preventDefault(); 
    $.ajax({
       type: 'POST',
       url: '/notes/vote',
       data: $(this).serialize(),
       success: function( msg ) {";

     }
   });
  });";  ?>



 @endforeach

I've tried something along the lines of this

$(function () {
$('form').on('submit', function (e) {
    $.ajax({
        type: 'post',
        url: '/notes/vote',
        data: $(this).serialize(),
        success: function () {
            location.reload();
        }
    });
    e.preventDefault();
  });
 });

But that just posts all the forms on the page when clicking a single button, I've tried adding a unique onclick event for the forms but I've had the same result. Any guidance would be appreciated

1
  • You can consider to bind a token to each form. Then hide it in your document as input type="text" readonly, or add it to a constant variable (const token_$1 where $1 is the step in the iteration) in your javascript snippet. If choosing the latter approach, add this info to the form data before submitting the form. Commented Apr 10, 2017 at 6:57

2 Answers 2

1

Based on your statement:- But that just posts all the forms on the page when clicking a single button

I assume that you want to send only that form whose submit button clicked.So do like below:-

1.Instead of $('form').on('submit', function (e) { Use $('.vote-btn').on('click', function (e) {

2.Instead of $(this).serialize(), Use $(this).parent('form').serialize(),

So code need to be:-

$(function () {
    $('.vote-btn').on('click', function (e) {
        e.preventDefault();
        $.ajax({
            type: 'post',
            url: '/notes/vote',
            data: $(this).parent('form').serialize(),
            success: function () {
                location.reload();
            }
        });
    });
});
Sign up to request clarification or add additional context in comments.

5 Comments

stepho based on <input type="hidden" name="type" value="0"> you can get it's a down-vote form submitted or up-vote form submitted
This seems to have the same effect as the previous code I quoted in the bottom of my post, It sends the form, but each foreach entry has upvote and downvote buttons, and pressing one downvote on a single form button actually gives all the other note entries a downvote.
@stepho my code will send only that form whose submit button is clicked, not all the forms
@stepho no need to repeat the code this will work for each-one
I'm in the wrong here, your code does work, so my bad! I forgot that I duplicated some entries in the DB, so the reason why It was liking all entries was because the entry data was the same. Sorry, been a long night haha. Thanks again, I appreciate it.
0

I think your problem it's you have several forms in one page, and you want to send all of them at the same time, but you're really sending only one; the one of the submit button you're clicking on.

Your code it's fine but the jquery on submit function fires only when you click the submit button in one form. And that jquery only works with that form, it doesn't sends all the forms at the same time.

Try creating only one form and adding the {{$formRand}} to the inputs like this example:

<input type="hidden" name="type{{$formRand}}" value="1">

2 Comments

If I did that, I'd have no way of inserting anything into my controller because It wouldn't recognise the input names. The two forms are needed as it differentiates from an upvote and a downvote. Is there anyway of adding a unique id to the form buttons with an onclick and pass the id variables through the ajax request?
You can have two or more submit buttons in a form. Example: <input type='submit' name='upvote' value='1'><input type='submit' name='downvote' value='1'> You should check which parameter you have received to know if it's an upvote or a downvote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.