3

I am trying to submit a form which has dynamically generated fields to controller using Ajax. Its like an invoice. There is date, customer, sub_total, tax, and ttl fields which are permanent (invoice header). Then there are n number of dynamically generated form fields (invoice lines). Here is the dynamically generated html. Every input field has distinct names and id's.

<tbody id="list">
    <tr>
        <td>
            <input name="sku1" id="sku1" readonly="" type="text" value="K5693">
        </td>
        <td>
            <input name="name1" id="name1" readonly="" type="text" value="HANDLEBAR">
        </td>
        <td>
            <input name="rate1" id="rate1" readonly="" type="text" value="45.00">
        </td>
        <td>
            <input name="qty1" id="qty1" readonly="" type="text" value="2">
            </td>
        <td>
            <input name="disc1" id="disc1" readonly="" type="text" value="0">
        </td>
        <td>
            <input name="ttl1" id="ttl1" readonly="" type="text" value="90.00">
        </td>
        <td class="text-center">
            <a onclick="removeField(this)"><i class="fas fa-trash-alt"></i></a>
        </td>
    </tr>
    <tr>
        <td>
            <input name="sku2" id="sku2" readonly="" type="text" value="K5693">
        </td>
        <td>
            <input name="name2" id="name2" readonly="" type="text" value="HANDLEBAR">
        </td>
        <td>
            <input name="rate2" id="rate2" readonly="" type="text" value="45.00">
        </td>
        <td>
            <input name="qty2" id="qty2" readonly="" type="text" value="2">
        </td>
        <td>
            <input name="disc2" id="disc2" readonly="" type="text" value="10">
        </td>
        <td>
            <input name="ttl2" id="ttl2" readonly="" type="text" value="80.00">
        </td>
        <td class="text-center">
            <a onclick="removeField(this)"><i class="fas fa-trash-alt"></i></a>
        </td>
    </tr>
</tbody>

Permanent fields HTML

        <div class="form-group">
            <label for="date">Date</label>
            <input type="text" class="form-control" id="date" name="date" placeholder="00/00/0000"></input>
        </div>
        <div class="form-group">
            <label for="customer">Customer</label>
            <select class="form-control" id="customer">
                @foreach($customers as $customer)
                    <option value="{{$customer->id}}">{{$customer->name}}</option>
                @endforeach
            </select>
        </div>

        <div class="card p-3">
            <table>
            <tr>
                <td class="h5">SUB TOTAL</td>
                <td class="h5 text-right pr-3">AED</td>
                <td><input type="text" class="form-control text-right" id="sub_total"placeholder="00.00" value="0.00" readonly></input></td>
            </tr>                   
            <tr>
                <td class="h5">VAT</td>
                <td class="h5 text-right pr-3">AED</td>
                <td><input type="text" class="form-control text-right" id="tax" placeholder="00.00" value="0.00" readonly></input></td>
            </tr>                       
            <tr>
                <td class="h5">TOTAL</td>
                <td class="h5 text-right pr-3">AED</td>
                <td><input type="text" class="form-control text-right" id="ttl" placeholder="00.00" value="0.00" readonly></input></td>
            </tr>
        </table>                        
    </div>

The javascript is here is triggered with a button click:

function createData(){
    var date = document.getElementById('date').value;
    var customer = document.getElementById('customer').value;
    var sub_ttl = document.getElementById('sub_total').value;
    var tax = document.getElementById('tax').value;
    var ttl = document.getElementById('ttl').value;
}

I started with getting values from permanent fields. Not sure how to gather values from n number of dynamically generated fields and pass it on to controller. Have beein going through many articles regarding this, not able to figure it out. Any help please?

Lucid Polygon
  • 542
  • 9
  • 26

3 Answers3

4

You will have to do something like this :

<tbody id="body">
<tr>
    <td>
        <input name="skus[]"readonly="" type="text" value="K5693">
    </td>
    <td>
        <input name="names[]" readonly="" type="text" value="HANDLEBAR">
    </td>
    <td>
        <input name="rates[]" readonly="" type="text" value="45.00">
    </td>
    <td>
        <input name="qtys[]" readonly="" type="text" value="2">
        </td>
    <td>
        <input name="discs[]" readonly="" type="text" value="0">
    </td>
    <td>
        <input name="ttls[]" readonly="" type="text" value="90.00">
    </td>
    <td class="text-center">
        <a onclick="removeField(this)"><i class="fas fa-trash-alt"></i></a>
    </td>
</tr>

Then in your controller you will be able to get all values like this:

$skus = request('skus');
$names = request('names');
...
for($i = 0 ; $i < count($skus) ; $i++)
 {
   $sku = $skus[$i];
   $name = $names[$i];
   ...
 }
Juan Carlos Ibarra
  • 1,299
  • 14
  • 15
  • 1
    Not sure why was this down voted.This method works. Up voted. But I need it using AJAX. Not standard form submit way. – Lucid Polygon Feb 15 '19 at 10:01
  • sorry I did not crack it yet. I am currently using the normal form submit. – Lucid Polygon Feb 17 '19 at 03:25
  • Hii @JuanCarlosIbarra . I know I'm too late to look this. But I wanna ask something. When I tried your answer, the error comes up with message `Parse error: syntax error, unexpected 'i' (T_STRING), expecting ';'` right on the `for(int i = 0 ; i < count($skus) ; i++)` . Can you help me to solve that error please – Bariq Dharmawan Jul 23 '19 at 04:23
  • My mistake @BariqDharmawan I used Java instead of PHP should be like this`for ($i = 0 ; $i < count($skus) ; $i ++)` – Juan Carlos Ibarra Jul 26 '19 at 15:12
  • 2
    this is honestly the best answer i've seen on the topic. This especially works for me since i'm having to do this by updating existing records, not simply creating new ones like every tutorial on the internet wants to show examples for. It's easy to just throw a find() function in there and get the row I need to alter then save it using this method – maximus1127 Aug 27 '19 at 01:42
  • OK, recently I was working with this method as well. But I've one question, how can we validate data using this method and if validation failed, Laravel will redirect back and how can we sustain fields than? – hassanrazadev Mar 29 '20 at 11:13
0

Change your code as below. Put <form> and submit button where you want.

//submit opening invoice data
        $('#invoice_form').on('submit', function(event){
            event.preventDefault();
            $.ajax({
                url:"put your url",
                method:'post',
                data:$(this).serialize(),
                dataType:'json',
                success:function(data)
                {
                    //do whatever you want
                }
            })
    });
<form id ="invoice_form">
<tbody id="body">
<tr>
    <td>
        <input name="skus[]"readonly="" type="text" value="K5693">
    </td>
    <td>
        <input name="names[]" readonly="" type="text" value="HANDLEBAR">
    </td>
    <td>
        <input name="rates[]" readonly="" type="text" value="45.00">
    </td>
    <td>
        <input name="qtys[]" readonly="" type="text" value="2">
        </td>
    <td>
        <input name="discs[]" readonly="" type="text" value="0">
    </td>
    <td>
        <input name="ttls[]" readonly="" type="text" value="90.00">
    </td>
    <td class="text-center">
        <a onclick="removeField(this)"><i class="fas fa-trash-alt"></i></a>
    </td>
</tr>
</tbody>

  <button type="submit" class="btn btn-success"><i class="fas fa-download"></i> Save</button>
  
</form>

controller.php

 public function create(Request $request){
    if($request->ajax())
    {
     $skus= $request->skus;
     $names= $request->names;
     $rates= $request->rates;
     $qtys= $request->qtys;

     for($count = 0; $count < count($skus); $count++)
     {
      $data = array(
       'skus' => $skus[$count],
       'names'  => $names[$count],
       'rates'  => $rates[$count],
       'qtys'  => $qtys[$count]
      );

      $insert_data[] = $data; 
     }

     Invoice::insert($insert_data);

     return response()->json([
      'success'  => 'Invoice Saved Successfully!'
     ]);
    }
}
Iresha Shyamean
  • 61
  • 1
  • 3
  • 12
-1

All you really need is a way to serialize the entire form.

Here's how to do it with jQuery:

https://api.jquery.com/serialize/

Here's how to do it with plain Javascript:

Serialize HTML form to JSON with pure JavaScript

JTinkers
  • 1,631
  • 9
  • 18