in this tutorils will explain how to make a Form Repeater in Laravel Step by step.



First Step Create the Laravel Project using following command
composer create-project laravel/laravel billsystem-app
after that you have to create the routes files in web.php file
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BillController;
Route::get('/', function () {
return view('welcome');
});
Route::get('/bill', [BillController::class, 'index']);After that create a controller
php artisan make:controller BillController
paste the following codes
class BillController extends Controller
{
public function index()
{
return view('bills.index');
}
}return view(‘bills.index’); which is passing the to respective view page inside the views folder
index.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<style>
.container {
display: flex;
justify-content: center;
}
</style>
</head>
<body
<div class="container">
<div class="col-md-6" >
<h2>Bill Form</h2>
<form>
<table class="table table-bordered" id="billTable">
<thead>
<tr>
<th>Product Name</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
<th>Action</th>
</tr>
</thead>
<tbody id="billRows">
<tr>
<td><input type="text" name="products[0][product_name]" class="form-control" required></td>
<td><input type="number" name="products[0][quantity]" class="form-control quantity" required></td>
<td><input type="number" name="products[0][price]" class="form-control price" required></td>
<td><input type="number" class="form-control total" readonly></td>
<td><button type="button" class="btn btn-danger removeRow">Remove</button></td>
</tr>
</tbody>
</table>
<button type="button" id="addRow" class="btn btn-primary" >Add Row</button>
<hr>
<div class="form-group">
<label for="grandTotal"><b>Grand Total:</b></label>
<input type="number" id="grandTotal" class="form-control" readonly>
</div>
</form>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
let rowIndex = 1;
// Add new row
document.getElementById('addRow').addEventListener('click', function() {
let row = `<tr>
<td><input type="text" name="products[${rowIndex}][name]" class="form-control" required></td>
<td><input type="number" name="products[${rowIndex}][quantity]" class="form-control quantity" required></td>
<td><input type="number" name="products[${rowIndex}][price]" class="form-control price" required></td>
<td><input type="number" class="form-control total" readonly></td>
<td><button type="button" class="btn btn-danger removeRow">Remove</button></td>
</tr>`;
document.getElementById('billRows').insertAdjacentHTML('beforeend', row);
rowIndex++;
});
// Calculate total and grand total dynamically
document.addEventListener('input', function(event) {
if (event.target.classList.contains('quantity') || event.target.classList.contains('price')) {
let row = event.target.closest('tr');
let quantity = row.querySelector('.quantity').value || 0;
let price = row.querySelector('.price').value || 0;
let total = quantity * price;
row.querySelector('.total').value = total;
calculateGrandTotal();
}
});
// Remove row
document.addEventListener('click', function(event) {
if (event.target.classList.contains('removeRow')) {
event.target.closest('tr').remove();
calculateGrandTotal();
}
});
// Calculate grand total
function calculateGrandTotal() {
let grandTotal = 0;
document.querySelectorAll('.total').forEach(function(totalInput) {
grandTotal += parseFloat(totalInput.value || 0);
});
document.getElementById('grandTotal').value = grandTotal;
}
});
</script>
</body>
</html>
I attached the video below How to make this System