ببعض التطبيقات نحتاج لإعطاء مستخدم التطبيق ميزة إضافة عدد لا نهائي من الحقول، في هذا المقال سيتم شرح كيفية عمل ذلك بإستخدام jquery، وكيفية حفظ البيانات في قاعدة البيانات بإستخدام إطار العمل لارافيل.
الخطوات
إنشاء route
Route::get('/categories',[CategoryController::class,'index']);إنشاء الدالة index بداخل CategoryController
public function index(){
return view('category');
}كما نرى فإن الدالة index تقوم بعرض صفحة category.blade.php.
إنشاء form في صفحة category
بداية نحتاج لتضمين مكتبة jquery
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css"> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/js/bootstrap.min.js"></script>
تم إيضا تضمين مكتبة bootstrap وذلك لأنني أعتمد عليها في فمن المممكن تضمين مكتبات أخرى مثل taillwind css او بدون هذه المكتبات.
إنشاء form في صفحة category.blade.php
<form action="{{ route('saveData') }}" method="POST">
@csrf
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (Session::has('success'))
<div class="alert alert-success text-center">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
<p>{{ Session::get('success') }}</p>
</div>
@endif
<table class="table table-bordered" id="dynamicAddRemove">
<tr>
<th>Title</th>
<th>Action</th>
</tr>
<tr>
<td><input type="text" name="moreFields[0][title]" placeholder="Enter title" class="form-control" /></td>
<td><button type="button" name="add" id="add-btn" class="btn btn-success">Add More</button></td>
</tr>
</table>
<button type="submit" class="btn btn-success">Save</button>
</form>
الجزء المهم في الفورم هو إسم input field وهو name="moreFields[0][title]" وكذلك id الخاص بالـ button وهو add-btn و dynamicAddRemove
- name="moreFields[0][title]" : وهو إسم الحقل وفي كل مره يتم إضافة حقل جديد يتم تغيير [0] إلى 1,2,3.... وهكذا.
- add-btn : وهو ما سنتعامل به مع حدث الضغط في jquery.
- dynamicAddRemove: وهو الدف الذي سيتم إضافة الـ text بداخلة.
كتابة كود jquery لإضافة الحقول عند الضغط على add-btn
<script type="text/javascript">
var i = 0;
$("#add-btn").click(function(){
++i;
$("#dynamicAddRemove").append('' +
'<tr>' +
'<td>' +
'<input type="text" name="moreFields['+i+'][title]" placeholder="Enter title" class="form-control" />' +
'</td>' +
'<td>' +
'<button type="button" class="btn btn-danger remove-tr">Remove</button>' +
'</td>' +
'</tr>');
});
$(document).on('click', '.remove-tr', function(){
$(this).parents('tr').remove();
});
</script>- تم تعريف i=0 وهي قيمة إفتراضية، وسيتم زيادة الرقم بـ 1 كل مره يتم الضغط على الزر.
- عند الضغط على زر الإضافة add-btn يتم زيادة i بـ 1، وبداخل الدف dynamicAddRemove سيتم إضافة صف جديد مع تغيير إسم الحقل بقيمة i .
- remove-tr عند الضغط عليها سيتم إزالة الصف الموجوده بداخله.
إنشاء route لإضافة البيانات
Route::post('/store',[CategoryController::class,'store'])->name('saveData');إنشاء fillable بداخل category Model
class Catetory extends Model
{
use HasFactory;
public $fillable=['title'];
}إنشاء دالة store لحفظ البيانات بداخل CategoryController
public function store(Request $request)
{
$request->validate([
'moreFields.*.title' => 'required'
]);
foreach ($request->moreFields as $key => $value) {
Catetory::create($value);
}
return back()->with('success', 'Categories Has Been Created Successfully.');
}- بداية نتحقق من المدخلات وكما نلاحظ أن إسم المدخلات هو 'moreFields.*.title'.
- حفظ البيانات بعد عمل foreach على المدخلات
- إرجاع رسالة success بعد حفظ البيانات.
كود صفحة category.blade.php بالكامل
<!DOCTYPE html>
<html>
<head>
<title>Laravel 8 - Add/remove multiple input fields dynamically using Jquery</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/js/bootstrap.min.js"></script>
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body>
<div class="container">
<div class="card mt-3">
<div class="card-header"><h2>Add/remove Multiple Input Todo Fields Dynamically using Jquery In Laravel</h2></div>
<div class="card-body">
<form action="{{ route('saveData') }}" method="POST">
@csrf
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (Session::has('success'))
<div class="alert alert-success text-center">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
<p>{{ Session::get('success') }}</p>
</div>
@endif
<table class="table table-bordered" id="dynamicAddRemove">
<tr>
<th>Title</th>
<th>Action</th>
</tr>
<tr>
<td><input type="text" name="moreFields[0][title]" placeholder="Enter title" class="form-control" /></td>
<td><button type="button" name="add" id="add-btn" class="btn btn-success">Add More</button></td>
</tr>
</table>
<button type="submit" class="btn btn-success">Save</button>
</form>
</div>
</div>
</div>
<script type="text/javascript">
var i = 0;
$("#add-btn").click(function(){
++i;
$("#dynamicAddRemove").append('' +
'<tr>' +
'<td>' +
'<input type="text" name="moreFields['+i+'][title]" placeholder="Enter title" class="form-control" />' +
'</td>' +
'<td>' +
'<button type="button" class="btn btn-danger remove-tr">Remove</button>' +
'</td>' +
'</tr>');
});
$(document).on('click', '.remove-tr', function(){
$(this).parents('tr').remove();
});
</script>
</body>
</html>
عمل جميل الاجراء store ينفذ الكثير من عمليات الادخال Catetory::create($value); يعني لو لدينا 20 عنوان سيكون تم استدعاء Catetory::create($value); عشرين مرة اقترح انشاء استعلام واحد يحوي ال عشرين قيمة وتنفيذ استعلام واحد مرة واحد حيث تكون الحلقة من اجل بناء الاستعلام insert