Custom Error Messages after submitting data Laravel - php

I already asked this question but there are a few things different this time. Last time the problem was fixed pretty well so now i just need a hand to tell me how to change the code so it works properly.
The thing i have changed is that i have implemented a way to successfully lend more then one book at once. So now i have an array which works perfectly.
So this is my View imagine this code 3 times one for every book you want to lend:
<div class="form-group row">
<label for="serialnumber" class="col-md-4 col-form-label text-md-right">{{ __('Gerät 1 (serialnumber) :') }}</label>
<div class="col-md-6">
<input id="serialnumber" type="text" class="form-control{{ $errors->has('serialnumber') ? ' is-invalid' : '' }}" name="serialnumber[]" value="{{ old('serialnumber') }}" required #if (Session::has('autofocus')) autofocus #endif>
#if ($errors->any())
<div class="alert alert-danger">The book with this serialnumber is already lend by antoher person
<ul>
</ul>
</div>
#endif
</div>
</div>
This is my Controller Code now:
public function store(BookRequest $request)
{
//if( !Book::find($request->get('serialnumber'))->exists() ) {
$this->middleware('guest');
request()->validate([
'serialnumber' => 'required',
'ma_id' => 'required'
]);
$requestData = $request->all();
$data = [
[
'serialnumber' => $requestData['serialnumber'][0],
'comment' => $requestData['comment'],
'ma_id' => $requestData['ma_id'],
],
[
'serialnumber' => $requestData['serialnumber'][1],
'comment' => $requestData['comment'],
'ma_id' => $requestData['ma_id'],
],
[
'serialnumber' => $requestData['serialnumber'][2],
'comment' => $requestData['comment'],
'ma_id' => $requestData['ma_id'],
]
];
Book::insert($data);
return redirect()->route('borrow.index')
->with('success','Successfully lend the book');
}
And the last is my Request.php page:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BookRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'serialnumber[0]' => 'required|unique:borrowed,serialnumber,null',
'serialnumber[1]' => 'required|unique:borrowed,serialnumber,null',
'serialnumber[2]' => 'required|unique:borrowed,serialnumber,null',
'ma_id' => 'required',
];
}
public function messages()
{
return [
'serialnumber' => 'Seems like you have added the same book more than once!',
];
}
}
And this is my error message which i got after i tried to lend a book which is already lend by another person. Before i implemented the array thing this code worked perfect. Another question that i have is how could i implement a way which shows an error message which says "Sorry but this book is currently not in our database please press the info button and get some administraive help" so that basically an error message appears when the book is not in our database we have a lot of books so it is possible that we forget to scan one. Every help is much appreciated!!
EDIT:
Forgot the error message
htmlspecialchars() expects parameter 1 to be string, array given

Change your view:
#if(!empty(old('serialnumber')))
#foreach(old('serialnumber') as $i=>$value)
<input id="serialnumber" type="text" class="form-control{{ $errors->has('serialnumber') ? ' is-invalid' : '' }}" name="serialnumber[]" value="{{ old('serialnumber.'.$i) }}" required #if (Session::has('autofocus')) autofocus #endif>
#endforeach
#endif
where $i is your array index
aslo you can modify your rules and message like:
public function rules(){
return [
'serialnumber.0' => 'required|unique:borrowed,serialnumber,null',
'serialnumber.1' => 'required|unique:borrowed,serialnumber,null',
'serialnumber.2' => 'required|unique:borrowed,serialnumber,null',
'ma_id' => 'required',
];
}
or
public function rules(){
return [
'serialnumber.*' => 'required|unique:borrowed,serialnumber,null',
'ma_id' => 'required',
];
}
and
public function messages()
{
return [
'serialnumber.*' => 'Seems like you have added the same book more than once!',
];
}

Related

How does this form gets the label name of each input

I'm working on some else project which is a Laravel 9 project and I have seen something interesting that have not seen it before.
Basically he defined the form inputs of projects like this (example):
<div class="form-group">
<span class="text-danger">*</span>
<label>{{ __('news')['nws_title'] }}</label>
<input type="text" name="nws_title" value="{{ old('nws_title' ,!empty($new) ? $new->nws_title : '') }}">
</div>
So as you can see for the <label>, this has been added:
{{ __('news')['nws_title'] }}
But I don't know what on earth is __('news') and what type of variable is this and how it calls the nws_title local name as label !!
So if you know, please let me know...
Also in the blade, he called the form request as well:
#php
$validationRequest = new \App\Http\Requests\News\NewsRequest();
$is_star = $validationRequest->rules();
#endphp
And this is the NewsRequest:
public function rules()
{
if($this->method() == 'POST') {
return [
'nws_title' => ['required'],
'nws_cat_id' => ['required'],
'nws_publish' => ['required', 'digits_between:0,1'],
'nws_lead' => ['required_if:nws_publish,1'],
'nws_description' => ['required_if:nws_publish,1'],
'nws_feature_image' => ['nullable', 'mimes:jpeg,jpg,png,bmp' ],
'nws_thumbnail_image' => ['nullable', 'mimes:jpeg,jpg,png,bmp', 'dimensions:min_width=200,min_height=200,ratio=1/1' ],
'gallery.*' => ['mimes:jpeg,jpg,png,bmp', 'nullable'],
];
}
return [
'nws_title' => ['required'],
'nws_cat_id' => ['required'],
'nws_publish' => ['required'],
'nws_lead' => ['required_if:nws_publish,1'],
'nws_description' => ['required_if:nws_publish,1'],
'nws_feature_image' => ['nullable', 'mimes:jpeg,jpg,png,bmp'],
'nws_thumbnail_image' => ['nullable', 'mimes:jpeg,jpg,png,bmp', 'dimensions:min_width=200,min_height=200,ratio=1/1'],
'gallery.*' => ['mimes:jpeg,jpg,png,bmp', 'nullable'],
];
}
Thanks in advance.
__() is a helper method for translation/localization. Depends on how localization is implemented in the app, but if it follows Laravel's default localization feature, then you can consult to the doc here.

Laravel backpack edit form displaying checklist items with selected values from database

In my crud controller, There is one field called "roles (Multiple checklist)", While before saving the roles, I am converting array into string like 1,2,3 using implode.
Ex: CrudController
setUp() method
$options = [
'name' => 'roles',
'label' => 'Roles',
'type' => 'checklist',
'entity' => 'roles',
'attribute' => 'name',
'model' => "Backpack\PermissionManager\app\Models\Role",
];
$this->crud->addField($options);
In Store method,
public function store(StoreRequest $request)
{
$sel_roles = $request->input("roles");
$roles = !empty($sel_roles) ? implode(",",$sel_roles) : "";
$request->request->set("roles",$roles);
//dd($request);
return parent::storeCrud($request);
}
Edit Method looks like this,
public function edit($id) {
$this->crud->hasAccessOrFail('update');
// get the info for that entry
$this->data['entry']= $this->crud->getEntry($id);
$options = [
'name' => 'roles',
'label' => 'Roles',
'type' => 'checklist',
'entity' => 'roles',
'attribute' => 'name',
'model' => "Backpack\PermissionManager\app\Models\Role",
];
$this->crud->addField($options);
$this->data['crud'] = $this->crud;
$this->data['fields'] = $this->crud->getUpdateFields($id);
$this->data['id'] = $id;
return view('crud::edit', $this->data);
}
If am trying to access, Edit page, I am getting below error,
ErrorException in line 15:
Call to a member function pluck() on string (View: /var/www/html/app/vendor/backpack/crud/src/resources/views/fields/checklist.blade.php)
checklist.blade.php page looks like below
<div #include('crud::inc.field_wrapper_attributes') >
<label>{!! $field['label'] !!}</label>
<?php $entity_model = $crud->getModel(); ?>
<div class="row">
#foreach ($field['model']::all() as $connected_entity_entry)
<div class="col-sm-4">
<div class="checkbox">
<label>
<input type="checkbox"
name="{{ $field['name'] }}[]"
value="{{ $connected_entity_entry->id }}"
#if( ( old( $field["name"] ) && in_array($connected_entity_entry->id, old( $field["name"])) ) || (isset($field['value']) && in_array($connected_entity_entry->id, $field['value']->pluck('id', 'id')->toArray())))
checked = "checked"
#endif > {!! $connected_entity_entry->{$field['attribute']} !!}
</label>
</div>
</div>
#endforeach
</div>
{{-- HINT --}}
#if (isset($field['hint']))
<p class="help-block">{!! $field['hint'] !!}</p>
#endif
</div>
How do I display the roles with selected values in the edit page.
Thanks
After hours of debug and verified,
Send the edit values in the collection format,
$options = [
'name' => 'role_id',
'label' => 'Roles',
'type' => 'checklist',
'entity' => 'roles',
'attribute' => 'name',
'model' => "Backpack\PermissionManager\app\Models\Role",
"value" => collect([$edit_value_array])
];

Laravel 5.4 - Duplicate row inserted

I have been using Laravel for a couple years and I'm stumped on this one. Using Laravel 5.4 with voyager. I have my own controller outside of the BREAD controller
Form:
<form method="POST" action="/admin/invites" accept-charset="UTF-8" class="form-edit-add">
<input name="_token" type="hidden" value="QgLgj5tG4RfD2CxCsqE2Qn5jcWfwQhsk5THT30vO">
<div class="panel-body">
<div class="form-group">
<label for="name">Business</label>
<input class="form-control" placeholder="Business Name" name="business_id" type="text">
</div>
<div class="form-group">
<label for="body">Referral Name</label>
<input class="form-control" placeholder="Referral Name" name="referral_name" type="text">
</div>
</div>
<input class="btn btn-primary width-100 mb-xs" type="submit" value="Save">
</form>
web routes:
Route::resource('/admin/invites', 'InviteController');
Controller:
public function store(Requests\InviteRequest $request)
{
DB::table('invites')->insert(
[
'user_id' => Auth::user()->id,
'business_id' => $request->business_id,
'referral_name' => $request->referral_name,
'url_token' => str_random(16)
]
);
return redirect('/admin/invites')->with([
'message' => "Successfully Added New",
'alert-type' => 'success',
]);
}
When I submit it creates 2 rows in the database. I don't have duplicate routes or controllers. My Request file is empty. I have an ID in the table that is auto increment with primary index.
Any thoughts or troubleshooting tips?
I think the main point you are missing here is that Voyager calls its store() twice. First, through AJAX to validate the fields and then again by normal form submit to store the BREAD to the database.
Take a look at the default store() implementation in Voyager:
public function store(Request $request)
{
$slug = $this->getSlug($request);
$dataType = Voyager::model('DataType')->where('slug', '=', $slug)->first();
// Check permission
Voyager::canOrFail('add_'.$dataType->name);
//Validate fields with ajax
$val = $this->validateBread($request->all(), $dataType->addRows);
if ($val->fails()) {
return response()->json(['errors' => $val->messages()]);
}
if (!$request->ajax()) {
$data = $this->insertUpdateData($request, $slug, $dataType->addRows, new $dataType->model_name());
return redirect()
->route("voyager.{$dataType->slug}.edit", ['id' => $data->id])
->with([
'message' => "Successfully Added New {$dataType->display_name_singular}",
'alert-type' => 'success',
]);
}
}
Notice the if (!$request->ajax()) condition, the first AJAX call would bypass that but the second call would get into it and store to the database.
So in short, you have to follow the same structure in your store() method. Perform your validations first. Then when it's time to save, put that code into the if (!$request->ajax()) condition.
your form has some issues:
<label for="name">Business</label>
<input class="form-control" placeholder="Business Name" name="business_id" type="text">
change label for to for="business_id
<label for="body">Referral Name</label>
<input class="form-control" placeholder="Referral Name" name="referral_name"
</div>
change label for to for="referral_name
change your store method to this:
public function store(Requests\InviteRequest $request) {
$this->validate($request, array(
'user_id' => 'required',
'business_id' => 'required',
'referral_name' => 'required',
));
DB::table('invites')->insert([
'user_id' => $request->user_id,
'business_id' => $request->business_id,
'referral_name' => $request->referral_name,
'url_token' => str_random(16),
// If you don't use timestamp delete these lines below
'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
]);
return redirect('/admin/invites')->with([
'message' => "Successfully Added New",
'alert-type' => 'success',
]);
}
see if it works.

Model binding in registration form for Laravel 5.4

I am trying to pull list of data from database and show it as a dropdown in a registration form. But I get error undefined variable universities.
Register Controller
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
$universities = University::lists('id', 'university');
$sch_depts = Department::lists('id', 'department');
return User::create([
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'university' => $data['university'],
'school_dept' => $data['school_dept'],
])
->with(compact('universities','sch_depts'));
}
register.blade.php
<div class="form-group{{ $errors->has('university') ? ' has-error' : '' }}">
<label for="university" class="col-md-4 control-label">University</label>
<div class="col-md-6">
{!! Form::select('university', $universities, null, array('id' => 'universitiy', 'class' => 'form-control')) !!}
#if ($errors->has('university'))
<span class="help-block">
<strong>{{ $errors->first('university') }}</strong>
</span>
#endif
</div>
</div>
I am getting an error universities undefined.
Let's assume you have a controller called RegisterController, the create method should only return view and it's corresponding data.
public function create()
{
$universities = University::lists('id', 'university');
$sch_depts = Department::lists('id', 'department');
return view('register', compact('universities', 'sch_depts'));
}
and you should also have a store method:
public function store(\Illuminate\Http\Request $request)
{
// your validation goes here
// or just use form request validation
// docs: https://laravel.com/docs/5.4/validation#form-request-validation
User::create([
'firstname' => $request->get('firstname'),
'lastname' => $request->get('lastname'),
'email' => $request->get('email'),
'password' => bcrypt($request->get('password')),
'university' => $request->get('university'),
'school_dept' => $request->get('school_dept'),
]);
// login user here or redirect to success page
}
and your routes/web.php file should contain the following routes:
Route::get('register', 'RegisterController#create');
Route::post('register', 'RegisterController#store');
This is really basics of Laravel, please read the docs.
P.S. Laravel comes with great Authentication system, which you can override to your needs.
This is what I did in Laravel 7, I'm also using the default authentication implementation from Laravel, so it might help
The solution is: in the RegisterController overwrite the method showRegistrationForm (which is declared in /vendor/laravel/ui/auth-backend/RegisterUsers) and add the data array.
So you will add something like this to your RegisterController
public function showRegistrationForm()
{
$universities = University::lists('id', 'university');
$sch_depts = Department::lists('id', 'department');
return view(
'auth.register',
[
'universities' => $universities,
'sch_depts' => $sch_depts
]
);
}}

Variable not showing on blade template

I'm creating a CRUD with 2 models in a form: automations and rules. 1 automation has 1 rule. On the edit form, I need to show field both from automations and rules.
This is my controller on edit method.
public function edit($id)
{
$actions = array(
1 => 'Enable',
2 => 'Pause',
);
$fields = \DB::table('fields')
->whereNull('field1_id')
->lists('field_name', 'id');
$schedules = \DB::table('schedules')
->lists('schedule_name', 'id');
$rules = \DB::table('rules')
->where('automation_id', '=', $id)
->get();
return view('automations.automations', [
'automations' => Automations::find($id),
'actions' => $actions,
'fields' => $fields,
'schedules' => $schedules,
'rules' => $rules
]);
But on my form, I my not able to show the values from Rules, only for Automations. What I am doing wrong? This is the blade form for 1 field from Rules:
<div class="form-group">
<label for="task-name" class="col-sm-3 control-label">Field 1 </label>
<div class="col-sm-6">
{!!
Form::select(
'field1',
(['' => 'Select a Field'] + $fields),
(isset($rules->field1) ? $rules->field1 : null),
['class' => 'form-control','id' => 'field1']
)
!!}
</div>
</div>
And for 1 field from automations:
<div class="form-group">
<label for="task-name" class="col-sm-3 control-label">Action on Campaigns</label>
<div class="col-sm-6">
{!!
Form::select(
'action_id',
(['' => 'Select an Action'] + $actions),
(isset($automations->action_id) ? $automations->action_id : null),
['class' => 'form-control']
)
!!}
</div>
</div>
DB::get() returns an array of stdClass objects. Therefore, $rules is an array, so you can't just access properties like $rules->field1. You need to iterate the array to find the actual object you're looking for, and then check that object. Or, if there's actually only one record, you can use first() instead of get().
DB::find() returns stdClass object or null, depending on if the record was found. That is why your automations works.

Categories