condition in laravel validation - php

Please help me, I'm trying to validate each row of the row that was highlighted with red in the form using the validate([]). If a user filled one of the columns in a row, and try to submit it with the other fields left unfilled, then it will prompt the user that the remaining fields are required to be filled. I have come up with various conditions but sadly none on them worked out,
this is my store function
public function store(Request $request){
$currentStatus = 0;
$data = $request->validate([
'to' => 'required',
'date' => 'date',
'address' => 'required',
'reference' => 'required',
'attention' => 'required',
'area' => 'required',
'project' => 'required',
'salesman' => 'required',
'location' => 'required'
]);
\App\Contract::create($data + ['status' => $currentStatus]);
return redirect('contracts/pendings');

first u need to create a FormRequest php artisan make:request MyControllerNameRequest
Then in MyControllerNameRequest define your rules
public function rules(): array
{
return [
'firstField' => ['required', 'int'],
'secondField' => ['required', 'int'],
'thirdFied' => ['required', 'int'],
'fourthField' => ['required', 'int'],
];
}
after go in to your controller and add MyControllerNameRequest like attribute in action
public function store(MyControllerNameRequest $request)
{
$model = Model::create($request->validated());
return redirect()->route('route.name');
}
or in some_name.blade.php add required
<input type="text" name="name" value="{{ old('value') }}" required>

I'm assuming that the names in HTML look like this:
<form method="post" action="{{ route('test') }}">
#csrf
<input type="text" name="data[0][quantity]">
<input type="text" name="data[0][unit]">
<input type="text" name="data[1][quantity]">
<input type="text" name="data[1][unit]">
<input type="submit">
</form>
You could try something like this in your controller.
$this->validate($request, [
'data.*.quantity' => 'sometimes|required_with:data.*.unit',
'data.*.unit' => 'sometimes|required_with:data.*.quantity',
]);
The required_with params accept multiples fields separated per comma, so you may have to pass all your fields in the validation. The sometimes validates only when it's passed values, so this may do the trick.

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.

How can I validate the sum of the values in Laravel?

I have 3 input tag with type number in blade.php. I want to validate the sum is equal to 100. So, how to do that? Thanks for your help.
Blade.php
<input type="number" name="number1" />
<input type="number" name="number2" />
<input type="number" name="number3" />
Controller
public function store(Request $request) {
$data = $request->validate([
'number1' => 'required',
'number2' => 'required',
'number3' => 'required',
]);
$sum = $data['number1'] + $data['number2'] + $data['number3'];
$myDb = new Mynumber();
$myDb->number1 = $data['number1'];
$myDb->number2 = $data['number2'];
$myDb->number3 = $data['number3'];
$myDb->save();
}
You can extend the validator with a new rule by adding this in a service provider:
$validator->extend("sumsTo", function ($attribute, $value, $parameters) {
$expected = floatval(array_shift($parameters));
$otherParameters = request()->only($parameters);
return floatval(array_sum(array_merge(array_values($otherParameters), [ $value ]))) === $expected;
});
Then you'd use this as:
$request->validate([
'field1' => 'sumsTo:100,field2,field3',
'field2' => 'sumsTo:100,field1,field3'
'field3' => 'sumsTo:100,field1,field2'
]);
This will flag all 3 fields as failed as well.
If you want to stay within the boundaries of Laravels validator, I'd suggest you either use the after validation hook or create a temporary field (within PHP, do NOT use client sided tech for this job!) with the sum of all the necessary fields and validate against it.
$validator = Validator::make([
'field1' => 50,
'field2' => 25,
'field3' => 22,
], [
'field1' => 'required|numeric',
'field2' => 'required|numeric',
'field3' => 'required|numeric',
]);
$validator->after(function ($validator) {
if ($validator->getData()['field1'] + $validator->getData()['field2'] + $validator->getData()['field3'] !== 100) {
$validator->errors()->add('field1', 'Make sure the sum of all fields equals 100.');
}
});

How do I ignore inputs that don't have data in update method

I have a form to update user data name and email and username. The question is if user want to update only user, how do I keep same email and name or change only name in my case the validation required all inputs this is my controller
public function update(Request $request, $username )
{
if($username != Auth::user()->username){
return abort('401');
}
$request->validate([
'name' => 'min:10|max:50|required',
'username' => 'unique:users|max:30|min:3|required',
'email' => 'email|unique:users|max:200|required',
]);
$checkuserindb = User::findOrFail(Auth::user()->id);
$checkuserindb->update([
'name' => $request->name,
'username' => $request->username,
'email' => $request->email
]);
return redirect()->route('userProfile', $request->username)->with('message', 'your account has been updated!');
}
On your input field just add the actual value from database like this:
<input type="text" name="name" value="{{$user->name}}">
<input type="text" name="username" value="{{$user->username}}">
<input type="email" name="email" value="{{$user->email}}">
Also use 'sometimes' rule and update any of the fields you want:
'name' => 'min:10|max:50|sometimes',
'username' => 'unique:users|max:30|min:3|sometimes',
'email' => 'email|unique:users|max:200|sometimes',

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.

How to pass form value from model to controller in laravel

I have a modal form that passes value to the model, to controller which will finally run the code to insert to database, but my problem is I don't know how to pass the value from my form to model and to my controller. Here is my model code
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class addbusiness extends Model
{
//fillable fields
protected $fillable = ['Fname', 'staffphn'];
}
and below is my controller code that insert into database
public function insert(Request $request){
//validate post data
$this->validate($request, [
'Fname' => 'required',
// 'content' => 'required'
]);
DB::table('business')->insert(
['owner_id' => 3, 'bus_name' => 'Fname' ,'address' => 'Fname' ,'phone' => 'Fname' ,'email' => 'Fname' ,'logo' => 'Fname','country' => 'Fname', 'createdon' => date('Y-m-d H:i:s' ), 'createdby' => 'Fname',]
);
As you can see i passed values straight to my database, and not from my form. the insert code works fine
here is my form
<input type="text" class="form-control" name="Fname" id="Fname" value="" placeholder="Business Name" required />
<span class="glyphicon glyphicon-briefcase form-control-feedback"></span>
My problem now is that I don't know how to pass the form value to my model and finally to my controller. Any help with proper documentation would be appreciated as am new to laravel.
Business::create([
'Fname' => $request->get('Fname'),
...
]);
Or you can use $request->all() if the form has all the correct name attributes:
Business::create($request->all());
Your Model should just be called Business for this to work.

Categories