1

I am a bit confused with this. How to save multiple row data in laravel using ajax? The idea is to add products and when click on submit button I want to save the table data in database. I am getting an error as invalid argument supplied for foreach in my controller.

This is my blade template with script.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Products Invoice</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
          integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>
<body>
<div class="container mt-5">
    <div class="row" id="invoice-data">
        <div class="col-md-12">
            <table class="table table-bordered" id="main_table">
                <thead>
                <tr>
                    <th scope="col">Product Name</th>
                    <th scope="col">Description</th>
                    <th scope="col">Price</th>
                    <th scope="col">Qty</th>
                    {{--<th scope="col">Discount</th>--}}
                    <th scope="col">Amount</th>
                    <th scope="col">
                        <button class="btn btn-success addRow">Add More</button>
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr>
                        <td>
                            <select name="product_name[]" class="form-control productname" id="row_0">
                                <option>Select Product</option>
                                @foreach($products as $product)
                                    <option name="product_name[]" value="{{$product->id}}">{{$product->name}}</option>
                                @endforeach
                            </select>
                        </td>
                        <td><input type="text" name="description[]" class="form-control description" readonly></td>
                        <td><input type="text" id="price" name="price[]" class="form-control price"
                                   onkeyup="rateChange($(this));" readonly></td>
                        <td><input type="text" name="qty[]" class="form-control qty" onkeyup="qtyChange($(this));"
                                   onkeypress='return onlynumbers(event);'></td>
                        {{--<td><input type="text" name="dis[]" class="form-control dis"></td>--}}
                        <td><input type="text" name="amount[]" id="amount" class="form-control amount" readonly></td>
                        <td><a class="btn btn-danger remove">X</a></td>
                </tr>
                </tbody>
            </table>
        </div>
        <div class="col-md-12">
            <div class="form-group float-right">
                <label for="discount"><b>SubTotal</b></label>
                <input type="text" name="subTotal[]" id="subTotal" class="subTotal">
            </div>
        </div>
        <div class="col-md-12">
            <div class="form-group float-right">
                <label for="discount"><b>Discount <span>%</span></b></label>
                <input type="text" name="discount[]" id="discount" class="discount" onkeyup="amount_discount();"
                       onkeypress='return onlynumbers(event);'>
            </div>
        </div>
        <div class="col-md-12">
            <div class="form-group float-right">
                <label for="SubTotal"><b>Total</b></label>
                <input type="text" name="total[]" id="total" class="total" readonly>
            </div>
        </div>
        <div class="col-md-12">
            <div class="form-group float-right">
                <button type="button" id="saveInvoice" name="saveInvoice" class="btn btn-success float-right">Submit</button>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    $("#saveInvoice").click(function () {
        $.ajax({
            url: "{{ route('invoice.store') }}",
            method: "POST",
            data: $("#invoice-data").serialize(),
            dataType: "json",
            success: function (data) {
                console.log(data);
            }
        });
    });
</script>
</html>

And this is my controller to store the data.

public function store(Request $request)
{
    $invoices = [];
    foreach ($request->input('product_name') as $key => $value) {
        $invoices["product_name.{$key}"] = 'required';
        $invoices["description.{$key}"] = 'required';
        $invoices["price.{$key}"] = 'required';
        $invoices["qty.{$key}"] = 'required';
        $invoices["amount.{$key}"] = 'required';
        $invoices["subTotal.{$key}"] = 'required';
        $invoices["discount.{$key}"] = 'required';
        $invoices["total.{$key}"] = 'required';
    }
    $validator = Validator::make($request->all(), $invoices);

    if ($validator->passes()) {
        foreach ($request->input("product_name") as $key => $value) {
            $invoice = new Invoice;

            $invoice->product_name = $request->get("product_name")[$key];
            $invoice->description = $request->get("description")[$key];
            $invoice->price = $request->get("price")[$key];
            $invoice->qty = $request->get("qty")[$key];
            $invoice->amount = $request->get("amount")[$key];
            $invoice->subTotal = $request->get("subTotal")[$key];
            $invoice->discount = $request->get("discount")[$key];
            $invoice->total = $request->get("total")[$key];

            $invoice->save();
        }
    }
}

It returns me 500 internal server error.

1 Answer 1

1

I think you need to print the "$request->input('product_name')" before foreach loop to check product name is coming is an array or not? because error you are getting is " invalid argument supplied for foreach in my controller". Just write print_r($request->input('product_name')) and check value is coming is an array or not?

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks Sohil. But i didn't understand why it is showing me null ?
In the blade view file you have not used <form> tag and in button click you are submitting the serialize data of id "invoice-data" which is assign to the div tag. So use form tag and give id to it and replace "invoice-data" id with form id in the ajax script.
Thanks Sohil. But i have one issue that when i use the form tag and try to add more row, my page get refresh and the all data gets clear. Will you help me out with that please?
Just use preventDefault method in your button click script.Check for how to use it.
It will definitely refresh the page because you are using button tag. Use this button to add more <button type="button" class="btn btn-success addRow">Add More</button> to prevent the page refreshing.
|

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.