Livewire validation of array inputs is not rendering
class TravelDetail extends SlideOver
{
public $existed_visa_name = []; //an array input
}
protected $rules = [
'existed_visa_name.*' => 'required|min:6'
];
public function save()
{
$this->validate(); // validating here
return;
}
blade file
<input type="text" class="form-control form-control-solid ps-13" placeholder="{{ __('Visa Name') }}" wire:model.defer="existed_visa_name.{{ $key }}">
#error('existed_visa_name.{{ $key }}') <span class="error">{{ $message }}</span> #enderror
<!--It is in the loop and $key = 0 -->
Try this instead. Let me know if it works.
#error('existed_visa_name.' . $key).
Source Laracast question
Related
When updating multiple records , I need to check tel field is unique (except id's tel).
I know to use this to validate specified id
'tel' => 'unique:dtb_users,tel,'.$user->id
but multiple is not
$validator = Validator::make($request->all(), [
'tel.*' => [
'nullable',
'min:10',
'max:12',
'unique:dtb_users,tel' <- stuck here
]
]);
My form has more fields , here is two of those(in foreach loop)
<div class="form-group form-group-user form-user-table mb-1">
<input id="email_{{$user->id}}" name="email[{{$user->id}}]" type="email" data-id="{{ $user->id }}" class="form-control email-validation text-color{{ $errors->has("email.$user->id") ? ' is-invalid' : '' }} input_change" value="{{ $old['email'][$user->id] ?? $user->email }}" placeholder="{{__('user.email_placeholder')}}" disabled>
#if ($errors->has("email.$user->id"))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first("email.$user->id") }}</strong>
</span>
#endif
</div>
<div class="form-group form-group-user form-user-table mb-0 number">
<input id="tel_{{ $user->id }}" name="tel[{{ $user->id }}]" class="form-control tel-validation text-color{{ $errors->has('tel.' . $user->id) ? ' is-invalid' : '' }} input_change only-numbers" value="{{ $old['tel'][$user->id] ?? $user->tel }}" placeholder="00000000000" disabled>
#if ($errors->has("tel.$user->id"))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first("tel.$user->id") }}</strong>
</span>
#endif
</div>
I'm pulling my hair out , any idea is respected . Thanks for all !
Answer
'unique:dtb_users,tel' -> Rule::unique('dtb_users', 'tel')->ignore(*)
I think with an adjustment to how you're naming the input elements of your form, the following should work.
In your blade file, change the value of the name attribute to follow the format:
name="users[{{ $user->id }}][field]"
So;
<input id="tel_{{ $user->id }}" name="users[{{ $user->id }}][tel]"
class="form-control tel-validation text-color{{ $errors->has('tel.' . $user->id) ? ' is-invalid' : '' }} input_change only-numbers"
value="{{ $old['tel'][$user->id] ?? $user->tel }}"
placeholder="00000000000"
readonly />
Then in your controller action, update your validation rules to as follows:
$validator = Validator::make($request->all(), [
'users' => ['required', 'array'],
'users.*.tel' => [
'nullable',
'min:10',
'max:12',
Rule::unique('users', 'tel')->ignore('*'),
]
]);
I remember back in 2-3 years I struggled a lot with this too.
Here is the answer:
'tel' => 'unique:dtb_users,tel,'. $this->id .''
$this->id is the record you are trying to update. If it doesn't find it like that you can put request()->route()->parameter('paramName');
paramName is the one you declared in the route;
This way is working
$validator = Validator::make($request->all(), [
'tel.*' => [
'nullable',
'min:10',
'max:12',
new UserTelUniqueRule($request->all('id', 'tel'))
]
]);
In UserTelUniqueRule
<?php
namespace App\Rules;
use App\Models\DtbUsers;
use Illuminate\Contracts\Validation\Rule;
class UserTelUnique implements Rule
{
/**
* #param array $input
*/
protected $input;
/**
* Create a new rule instance.
* #param array $input
*
* #return void
*/
public function __construct($input)
{
$this->input = $input;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
foreach ($this->input['id'] as $id) {
$tel = $this->input['tel'][$id];
if (is_null($tel)) {
continue;
}
$user = DtbUsers::where('tel', $tel)
->where('id', '!=', $id)
->whereNull('deleted_at')
->first();
if ($user) {
return false;
}
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return __('validation.unique');
}
}
I am getting data from backend and I want users to verify and update. What I am doing is passing the data from controller and fill them inside a form in view blade. When the user verifies the data and submit them, I pass them to validation in my method inside controller. As soon as the validation start laravel throws error:
\Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException",
"The GET method is not supported for this route. Supported methods:
POST.
Below is one the method in FormsController.php passing the variable that have been collected from database to view forms.oneedit.blade.php
public function editingone(Request $request)
{
$nameinst = $request->nameinst;
$firstnm = $request->firstnm;
$lastnm = $request->lastnm;
$phn = $request->phn;
$myArray['nameinst'] = $nameinst;
$myArray['firstnm'] = $firstnm;
$myArray['lastnm'] = $lastnm;
$myArray['phn'] = $phn;
return view('forms.oneedit', $myArray);
}
Below I receive the data in forms.oneedit.blade.php in view
<form class="w-full max-w-lg border-4 rounded-lg p-2" action="{{ route('updateeditedone.fomrone') }}" method="post">
#csrf
<input class="#error('firstname') border-red-500 #enderror"
id="firstname" name="firstname" type="text" value="{{ old('firstname', $firstnm) }}" required>
#error('firstname')
<div class="text-red-500 mt-2 text-sm">
{{ $message }}
</div>
#enderror
......................
<input class="
#error('lastname') border-red-500 #enderror"
id="lastname" name="lastname" type="text" value="{{ old('lastname', $lastnm) }}" required>
#error('lastname')
<div class="text-red-500 mt-2 text-sm">
{{ $message }}
</div>
#enderror
......................
<button type="submit">Submit</button> </form>
Below are among the routes in web.php
Route::post('/editone/formone', [FormsController::class,'editingone'])->name('edit.fomrone');
Route::post('/update/edited/formone', [FormsController::class,'updateeditedngone'])->name('updateeditedone.fomrone');
Below is the method that I am trying to validate the values in FormsController.php where the error occurs
public function updateeditedngone(Request $request)
{
$this->validate($request, [
'nameinstitute'=> 'required|max:255',
'firstname' => 'max:255',
'lastname' => 'max:255',
'phone' => 'required|max:255',
]); }
NB: If I remove the validation process inside the controller and just get the value it works, something like below:
$val = $request->nameinstitute;
dd($val);
With the above I correctly get the values before validation, But if I try to validate them first the error is thrown. Thanks in advance.
Update:
I have edited the validation method so as to direct to a certain view as suggested but still the same error
public function updateeditedngone(Request $request)
{
$validator = Validator::make($request->all(),
[ 'nameinstitute'=> 'required|max:255','firstname' => 'max:255',
'lastname' => 'max:255',
'phone' => 'required|max:255']);
if ($validator->fails())
{
Session::flash('error', $validator->messages()->first());
return redirect()->back()->withInput();
}
dd($validator);
return redirect()->route('form.checkbtn');
php artisan view:clear php artisan cache:clear php artisan route:clear
Run it from CMD
It works for me
I tried to create a few tricks for my form "if the form fields is null or empty the submit button should be disabled".
I do this by using livewire but in my case the button it still disabled even if the form fields is filled.
livewire file :
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class ExampleForm extends Component
{
public $name = '';
public $email = '';
public $password = '';
public $disabled = true;
protected $rules = [
'name' => 'required|min:6',
'email' => 'required|email',
'password' => 'required|min:6',
];
public function updated($fields)
{
$this->validateOnly($fields);
if(!is_null($fields) && !empty($fields)) {
$this->$disabled = false;
} else {
$this->$disabled = true;
}
}
public function submitForm()
{
$validatedData = $this->validate();
Example::create($validatedData);
}
public function render()
{
return view('livewire.example-form');
}
}
in blade.php
<form wire:submit.prevent="submitForm">
<input type="text" wire:model="name">
#error('name') <span class="error">{{ $message }}</span> #enderror
<input type="text" wire:model="email">
#error('email') <span class="error">{{ $message }}</span> #enderror
<input type="password" wire:model="password">
#error('password') <span class="error">{{ $message }}</span> #enderror
<button type="submit" {{ $disabled ? 'disabled' : '' }}>Submit</button>
</form>
Updated answer
As per the requirement now, the disabled property should be set to false only if all the validation passes for the required fields.
public $disabled = true;
public function updated($fields)
{
$this->disabled = true;
$this->validate(); // this is a blocking call
$this->disabled = false; // execution will reach this line only if all passes the validation.
}
Note that, the $fields property passed through only has the currently updated property. so we cannot use it to validateOnly method, since it will only validate the passed property.
in blade code
<div class="form-group col-md-11">
<input id="title" type="text" class="form-control #error('title') is-invalid #enderror" name="title[]"
id="title_input" value="{{ old('title') }}" autocomplete="name" autofocus
placeholder="Masukan Title">
</div>
in controller code
public function insert(Request $request){
$data = $request->all();
if(isset($request->title) && $request->title){
foreach ($data['title'] as $key => $value) {
$faqs = new Faqs();
$faqs->title = json_encode($value);
$faqs->description = $request->description;
$faqs->course_id = $request->course_id;
$faqs->save();
}
}
dd($faqs);
}
in model code
class Faqs extends Model
{
protected $table = 'faqs';
protected $fillable = ['title', 'description', 'course_id'];
public function courses()
{
return $this->belongsTo(Course::class);
}
}
I want to enter the title of more than one data, when I code it above, there is an error like this. How do I fix the error?
ErrorException
Array to string conversion.
I am currently stuck on solving this problem. I am new to Laravel and the MVC framework. I am struggling to create the dynamic form that gives the user the ability to add as many forms as possible. When the user enters the page at first it generates 5 form fields . Here is a look at my code so far.
<div id ={{$id = "from".$i}} >
<div class="form-group col-md-6">
<div class="col-md-6 form-group">
<label for={{$id = "Address".$i}}>Address</label>
<input type="text" name = "address[{{$i}}]" class="form-control" id={{$id = "Address".$i}} placeholder="Street Address"> <!-- problem form array how does this work in laravel -->
</div>
<div class="form-group col-md-6">
<label for={{$id = "city".$i}}>City</label>
<input type="text" value = "{{ old('city') }}" class="form-control" id={{$id = "City".$i}} placeholder="City">
#if ($errors->has('city'))
<span class="help-block">
<strong>{{ $errors->first('city') }}</strong>
</span>
#endif
</div>
How would I go about validating a form in Laravel 5.2 with from array
here's my controller
public function Postdata(Request $request) {
$this->validate($request->all(), [
'address.*' => 'required|string',
'city' => 'required',
]);
}
I am using a for loop to generate the forms dynamically.
here is the error I get
ErrorException in ValidatesRequests.php line 49:
Argument 1 passed to App\Http\Controllers\Controller::validate() must be an instance of Illuminate\Http\Request, array given, called in
C:\wamp\www\Dynamic- 1.0\app\Http\Controllers\propContoller.php on line 34 and defined
Can someone please help or point me in the right direction thank you !
add name="city[{{$i}}]"
Create a specific request with php artisan make:request PostRequest
Change public function Postdata(Request $request) { to public function Postdata(PostRequest $request) {
Remove the validate function call from your controller
Go to /app/Http/Requests/PostRequest.php
Then edit the rules function to something like this ...
.
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [];
foreach($this->request->get() as $key => $val)
{
$rules['address.' . $key] = 'required';
$rules['city.' . $key] = 'required';
}
return $rules;
}
Thank You man ! this is the solution I end up with
<div class="form-group col-md-6">
<div class="col-md-6 form-group">
<label for={{$id = "Address".$i}}>Address</label>
<input type="text" name="address[{{$i}}]" class="form-control" id={{$id = "Address".$i}} placeholder="Street Address">
</div>
in post request i did this
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
$rules = [];
foreach($this->request->get('address') as $key => $val) {
$rules['address.'.$key] = 'required';
}
return $rules;
}