Whenever you receive a POST in a controller ALWAYS return a redirect to a new route. NEVER return a view (or you end up with problems like this).
Laravel Validation returns blank page on failure
I have a project where several validations are working perfectly. However I added a new controller recently and noticed a break for a route. It seems that if the previous page was a POST request, 302 does not redirect to the page with its blade view but rather redirects to the page but left blank. To illustrate, see the below sequence of logic:
public function pickstudent(Request $request){
$term = $request->term;
$session = $request->session;
$stclass = $request->stclass;
$classname = Stclass::where('id', $stclass)->first()->name;
$students = Student::where('studentClassId', $stclass)->get();
return view('admin.fees.pickstudent', compact('students', 'stclass', 'term', 'session', 'classname'));
}
admin/fees/pickstudent has a form that gets submitted to :
public function entertransaction(Request $request){
$term = $request->term;
$session = $request->session;
$banks = Bank::all();
$stclass_id = $request->stclass;
$student_id = $request->student_id;
$studentname = Student::find($student_id)->surname.' '.Student::find($student_id)->firstName.' '.Student::find($student_id)->otherName;
$students = Student::where('studentClassId', $stclass_id)->get();
$paid = Transaction::where('student_id', $student_id)->pluck('fee_id');
$fees= Fee::where('term', $term)->where('session', $session)->where('stclass_id', $stclass_id)->whereNotIn('id', $paid)->get();
$officers = Role::find(4)->users()->get();
// if($fees->isEmpty()){
// return back()->with('success', 'Nothing owed');
// }
// else{
return view('admin.fees.entertransaction', compact('students', 'fees', 'student_id', 'studentname', 'term', 'session', 'stclass_id','banks','officers'));
}
admin/fees/entertransaction has another form that's submitted to:
public function submitpayment(Request $request){
$validator = Validator::make($request->all(), [
'fees' => 'required',
'paymentcode' => 'required',
]);
if ($validator->fails()) {
return redirect('admin/fees/pretransaction')
->withErrors($validator)
->withInput();
}
// request()->validate([
// 'paymentdate' => 'required',
// 'paymentcode' => 'required|unique:transactions',
// 'channel' => 'required',
// 'fees' => 'required',
// 'officer' => 'required',
// 'bank' => 'required',
// ], [
// 'fees' => 'Name must be at least 2 char.',
// 'officer' => 'Name should not be greater than 100 characters.',
// 'paymentcode.unique' => 'A student with that Registration/Admission Number already Exists.',
// 'bank' => 'Please check your mobile Number entry. Those are not numbers.',
// ]);
// $this->validate($request, [
// 'paymentdate' => 'required',
// 'paymentcode' => 'required|unique:transactions',
// 'channel' => 'required',
// 'fees' => 'required',
// 'officer' => 'required',
// 'bank' => 'required',
// ]);
I left the commented code so you see I have tried all validation methods I know. When validation fails, rather than return the errors to ../../entertransactions, it returns a blank .../.../entertransactions. Below is my entertransactions view:
@extends('layouts.admin')
@section('content')
@if (count($errors) > 0)
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
@endif
@if ($message = Session::get('failure'))
<div class="alert alert-danger">
<p>{{ $message }}</p>
</div>
@endif
Enter Transaction
{{$studentname}} @csrf <thead>
<th>Fee</th>
<th>Amount</th>
<th><input type="checkbox" id="feeall">Select All</th>
</thead>
<tbody>
@foreach($fees as $fee)
<tr>
<td>{{$fee->name}}</td>
<td>{{$fee->amount}}</td>
<td><input type="checkbox" value="{{$fee->id}}" class="fees" name="fees[]" id="fees[]"></td>
</tr>
@endforeach
</tbody>
</table>
<hr>
<div class="form-group">
<label for="channel">Payment Channel</label>
<select name="channel" id="channel" class="form-control">
<option selected="true" disabled="true">Select Payment Channel</option>
<option value="transfer">Mobile/Internet Transfer</option>
<option value="teller">Bank Deposit</option>
</select>
</div>
<div class="form-group">
<label for="Class">Bank Name:</label>
<select class="form-control" name="bank" id="bank">
<option selected="true" disabled="true">Select Bank</option>
@foreach($banks as $bank )
<option value="{{ $bank->name }}">{{ $bank->name }}</option>
@endforeach
</select>
</div>
<div class="form-group">
<label for="paymentdate">Payment Date</label>
<input type="date" name="paymentdate" id="paymentdate" class="form-control">
</div>
<div class="form-group">
<label for="paymentcode">Transaction Reference(e.g Teller Number, Transfer code)</label>
<input type="text" name="paymentcode" id="paymentcode" class="form-control">
</div>
<div class="form-group">
<label for="payevidence">Upload Payment Evidence [Optional]</label>
<input type="file" class="form-control-file" name="payevidence" id="payevidence">
</div>
<div class="form-group">
<label for="Class">Account Officer</label>
<select class="form-control" name="officer" id="officer">
<option selected="true" disabled="true">Select Account Officer</option>
@foreach($officers as $officer )
<option value="{{ $officer->id }}">{{ $officer->fullName }}</option>
@endforeach
</select>
</div>
<input type="hidden" name="student_id" value="{{$student_id}}">
<input type="hidden" name="stclass_id" value="{{$stclass_id}}">
<input type="hidden" name="term" value="{{$term}}">
<input type="hidden" name="session" value="{{$session}}">
<button type="submit" class="btn btn-success">Submit Payment</button>
</form>
</div>
$("#feeall").click(function (){
if ($("#feeall").is(':checked')){
$(".fees").each(function (){
$(this).prop("checked", true);
});
}else{
$(".fees").each(function (){
$(this).prop("checked", false);
});
}
});
$("#sessionall").click(function (){
if ($("#sessionall").is(':checked')){
$(".sessions").each(function (){
$(this).prop("checked", true);
});
}else{
$(".sessions").each(function (){
$(this).prop("checked", false);
});
}
});
If you have multiple forms that are shown in sequence, then there must also be a GET route at each step that knows how to display the next form and what data it requires.
When there is a validation error, the same GET route will be called and needs to be able to recreate the form again.
Please or to participate in this conversation.