0

I have data which will append to blade view codes below and each of them is warped into a form, the issue is data that will send to back-end always comes from first form (somehow other forms data will be ignored).

How my forms look like:

one

Sending data from first form ID = 7

two

Sending data from second form Still ID 7

three

Code

<script defer>
  $(document).ready(function() {
   $("body").on("click", ".savedynspecto", function(e){
      var form = $(this).closest('form');
      var id = form.find('input[name="product_id"]').val();
      // e.preventDefault();
      $.ajax({
        type: "post",
        url: '{{ url('admin/spacssendto') }}',
        data: {
          '_token': $('input[name=_token]').val(),
          'product_id': id,
          'subspecifications': $(this).closest('form').find('select.subspecifications').val()
        },
        success: function (data) {
          alert('Specifications added successfully.');
        },
        error: function (data) {
          console.log('Error!');
        }
      });
    });
  });
</script>

Controller

public function spacssendto(Request $request) {

        $testingdata = $this->validate($request, array(
          'product_id' => 'required',
          'subspecifications' => 'required',
        ));
        $product = Product::find($request->product_id);
        $product->subspecifications()->sync($request->subspecifications, false);

        return response()->json($testingdata);
    }

HTML output of my forms

<tr>

  <form method="POST" action="http://site.pp/admin/products/15/edit" accept-charset="UTF-8">

  </form>
  <input name="_token" value="DLrcOa0eOm90e4aaGSYp2uCeiuKtbGCT9fCOUP16" type="hidden">

  <input name="product_id" id="product_id" value="15" type="hidden">

  <td>Graphic</td>

  <td>

    <select class="subspecifications form-control tagsselector" id="subspecifications" name="subspecifications[]" multiple="multiple">

      <option value="7">Intel 920</option>

    </select>

  </td>

  <td class="text-center">

    <button type="button" id="savedynspecto" class="savedynspecto btn btn-md btn-success"><i class="fa fa-check"></i> Save</button>

  </td>

</tr>

Note:

What makes me curious is why my form closed right after it opened!

<tr>
 <form method="POST" action="http://site.pp/admin/products/15/edit" accept-charset="UTF-8">

  </form>
...

here is how my row will append to blade

var my_row = $('<tr>');
var my_html = '{{ Form::open() }}<input name="product_id" id="product_id" type="hidden" value="{{$product->id}}"><td>'+value1.title+'</td>';
my_html += '<td><select class="subspecifications form-control tagsselector" id="subspecifications" name="subspecifications[]" multiple="multiple">'+helpers+'</select></td>';
my_html += '<td class="text-center"><button type="button" id="savedynspecto" class="savedynspecto btn btn-md btn-success"><i class="fa fa-check"></i> Save</button></td>{{Form::close()}}</tr>';
my_row.html(my_html);
$('#addcustomstr').append(my_row);

As you see my {{ Form::open() }} is before first <td> and {{Form::close()}} is right before </tr> but why is closing right after it's open?

Any idea?

mafortis
  • 6,750
  • 23
  • 130
  • 288
  • When is `$('#addcustomstr').append(my_row);` code called? At a glance, you're using `{{ $product->id }}`, which, when loaded from the server will be, let's say 1. If you called `$('#addcustomstr').append(my_row);` multiple times, each `` would have the same value of 1. – Tim Lewis Aug 09 '18 at 18:29
  • @TimLewis that's right, because the idea was to each form having product id, and in this case all the product id are the same (i am working in edit page) – mafortis Aug 09 '18 at 18:32
  • Right right. I see that now. On the subject of invalid HTML, you could actually remove your `
    ` elements, add a class to each of your ``, like `ssWrapper` and target that in your `. savedynspecto` click function; since you're using AJAX, you don't really *need* the form elements there.
    – Tim Lewis Aug 09 '18 at 18:42
  • @TimLewis ok, can you give me sample of targeting that class please? – mafortis Aug 09 '18 at 18:48
  • Change `$(this).closest('form');` to `$(this).closest(".ssWrapper");` :P Just make sure each `` has `class="ssWrapper"`. – Tim Lewis Aug 09 '18 at 18:49
  • and what about `csrf_token`? i need that in order to send post request – mafortis Aug 09 '18 at 18:50
  • @TimLewis I did what you suggested `....` still every time i click save only first form will send. – mafortis Aug 09 '18 at 18:53
  • 1
    That says ``; I said ****. Also, you can just use `_token: "{{ csrf_token() }}"` in your JS (assuming you're in `.blade.php` file) – Tim Lewis Aug 09 '18 at 18:57

2 Answers2

1

Your HTML is malformed. You have an input element as a direct descendant of a tr element. Only td and th are allowed as direct descendants of a tr element. Put your hidden input field inside the td tag, like this:

var my_html = '{{ Form::open() }}<td><input name="product_id" id="product_id" type="hidden" value="{{$product->id}}">'+value1.title+'</td>';

and check if that works.

EDIT: And that, of course, is also malformed HTML, since the form element isn't allowed inside a tr element as well. Wrap your whole table inside a form tag instead.

José A. Zapata
  • 1,187
  • 1
  • 6
  • 12
0

Solved

Thanks to everyone tried to help, as I was warned that forms are not allowed in tr td I've decided to use row outside of my table and append my data there, in that way i was able to run my forms with no problems.

mafortis
  • 6,750
  • 23
  • 130
  • 288