Laravel Livewire Real Time Validation switching between classes - laravel-8

I'm wondering about how I can switch between classes in Livewire real time form validation?
let's imagine that i have a form with some input fields such as (email) inside the input class I have a laravel directive #error('email') is-invalid #enderror this will repeat "is-invalid" class when the form field is empty.
what I want to achieve is switching between "is-invalid " and "is-valid" classes the first one if the form field is empty and second one if the form field is filled.
Here is my code :
class ContactForm extends Component
{
public $name;
public $email;
protected $rules = [
'name' => 'required|min:6',
'email' => 'required|email',
];
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function saveContact()
{
$validatedData = $this->validate();
Contact::create($validatedData);
}
}
<form wire:submit.prevent="saveContact">
<input type="text" wire:model="name" class="#error('name') is-invalid #enderror">
#error('name') <span class="error">{{ $message }}</span> #enderror
<input type="text" wire:model="email" class="#error('email') is-invalid #enderror">
#error('email') <span class="error">{{ $message }}</span> #enderror
<button type="submit">Save Contact</button>
</form>

We can use the error bag $errors and check if it has an error with the existing #error blade directive to show the error message.
<form wire:submit.prevent="saveContact">
<input type="text" wire:model="name" class="#if($errors->has('name')) is-invalid #else is-valid #endif">
#error('name') <span class="error">{{ $message }}</span> #enderror
<input type="text" wire:model="email" class="#if($errors->has('email')) is-invalid #else is-valid #endif">
#error('email') <span class="error">{{ $message }}</span> #enderror
<button type="submit">Save Contact</button>
</form>
I have used the has function from the error bag and the usual #if blade directive to achieve this.
Now if there is no error and input is valid, the is-valid class will be added.
Similarly if the validation fails, is-invalid class will be added.

jhones,
You need to address it with javascript. See my answer below.
class ContactForm extends Component
{
public $name;
public $email;
protected $rules = [
'name' => 'required|min:6',
'email' => 'required|email',
];
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function saveContact()
{
$validatedData = $this->validate();
Contact::create($validatedData);
}
}
<form wire:submit.prevent="saveContact">
<input type="text" wire:model="name" class="#error('name') is-invalid #else is-valid #enderror" id="name-input">
#error('name') <span class="error">{{ $message }}</span> #enderror
<input type="text" wire:model="email" class="#error('email') is-invalid #else is-valid #enderror" id="email-input">
#error('email') <span class="error">{{ $message }}</span> #enderror
<button type="submit">Save Contact</button>
</form>
<!-- javascript here: i use jquery syntaxe here -->
<script>
$(document).ready(function() {
$('#name-input').change(function(){
$(this).removeClass('is-invalid')
});
$('#email-input').change(function(){
$(this).removeClass('is-invalid')
});
})
</script>
Explanation 👇
I modify the HTML as following:
<input type="text" wire:model="name" class="#error('name') is-invalid #else is-valid #enderror" id="name-input">
#error('name') <span class="error">{{ $message }}</span> #enderror
<input type="text" wire:model="email" class="#error('email') is-invalid #else is-valid #enderror" id="email-input">
I add an id to each input to be able to call them in the script later.
Also i add the class "is-valid" if the server didn't return an error msg.
Hope this solution helps you. Let me know

Hi friend you can use ;
<input id="email" class="form-control #if($errors->has('form.email')) is-invalid #else {{ $is_valid }} #endif" name="email" type="email" wire:model.lazy="form.email">
#error('form.email')<label id="email-error" class="error invalid-feedback" for="email" >{{ $message }}</label> #enderror
And class is ;
public function updated($name)
{
$a= $this->validateOnly($name, [
'form.email' => 'required|email',
'form.password' => 'required',
]);
if($a) {
$this->is_valid='is-valid';
}
else {
$this->is_valid='';
}
}

Related

Laravel 8 - Login Authentication Failed

Im new to Laravel and i have an error when i tried to login into my user, I have tried to identify the mistake and i think it would be in the auth()->attempt in SessionsController.php.
I tried to ddd($attributes); before the auth()->attempt and the input is there but it failed in auth()->attempt. So i tried ddd(auth()->attempt) and i got false.
If anyone know how to fix this please help me :(
This is my error
Below is my code:
routes/web.php:
Route::get('login', [SessionsController::class, 'create'])->middleware('guest');
Route::post('login', [SessionsController::class, 'store'])->middleware('guest');
sessions.create.blade.php (Login Page)
<form method="POST" action="/login" class="mt-10">
#csrf
<!-- Email -->
<div class="mb-6">
<label for="email" class="block mb2 uppercase font-bold text-xs text-gray-700">
Email
</label>
<input type="email" class="border border-gray-400 p-2 w-full" name="email" id="email" value="{{ old('email') }}" required>
#error('email')
<p class="text-red-500 text-xs mt-1">{{ $message }}</p>
#enderror
</div>
<!-- Password -->
<div class="mb-6">
<label for="password" class="block mb2 uppercase font-bold text-xs text-gray-700">
Password
</label>
<input type="password" class="border border-gray-400 p-2 w-full" name="password" id="password" required>
#error('password')
<p class="text-red-500 text-xs mt-1">{{ $message }}</p>
#enderror
</div>
<!-- Submit -->
<div class="mb-6">
<button type="submit" class="bg-blue-400 text-white rounded py-2 px-4 hover:bg-blue-500">
Log In
</button>
</div>
</form>
create_users_table.php
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('username')->unique();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
User.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $guarded = [];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt('$password');
}
public function posts()
{
return $this->hasMany(Post::class);
}
}
SessionsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades;
class SessionsController extends Controller
{
public function create()
{
return view('sessions.create');
}
public function store()
{
$attributes = request()->validate([
'email' => 'required|email',
'password' => 'required',
]);
// ddd($attributes);
///ddd(auth()->attempt($attributes));
if (auth()->attempt($attributes)) {
return redirect('/')->with('success', 'Welcome Back!');
}
throw ValidationException::withMessages(['email' => 'Your provided credentials could not be verified.']);
}
public function destroy()
{
auth()->logout();
return redirect('/')->with('success','Goodbye!');
}
}

Retrive ids and check related boxes

Using
Laravel 8.54
Livewire 2.6
Laratrust package for roles and permissions
I want to edit the permissions role like that
RolesEdit.php (livewire component)
<?php
namespace App\Http\Livewire\Admin\Roles;
use App\Models\Role;
use Livewire\Component;
use App\Models\Permission;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
class RolesEdit extends Component
{
public $data = [];
public $role;
public $selectedIds = [];
public function mount(Role $role)
{
$this->role = $role;
$this->data = $role->toArray();
}
public function update()
{
$this->data['permissions'] = $this->selectedIds;
$validated = Arr::except($this->validatedData(), ['permissions']);
$this->role->update($validated);
$this->role->permissions()->sync($this->data['permissions']);
}
public function validatedData()
{
return Validator::make($this->data, [
'display_name' => 'required',
'description' => 'required',
"permissions" => "required|array|min:1",
"permissions.*" => "required|distinct|min:1",
])->validate();
}
public function render()
{
$permissions = Permission::all();
return view('livewire.admin.roles.roles-edit', compact('permissions'));
}
}
Roles-edit.blade.php
<div class="mt-1">
<label class="form-label">{{ __('site.display_name') }}</label>
<input wire:model="data.display_name" type="text" class="form-control" placeholder="Enter role name" />
</div>
<div class="mt-1">
<label class="form-label">{{ __('site.role_description') }}</label>
<textarea wire:model="data.description" type="text" class="form-control"
placeholder="Enter Description"></textarea>
</div>
<div class="row w-100">
#foreach ($permissions as $permission)
<div class="col-md-3">
<div class="form-check ms-5">
<input wire:model.defer="selectedIds" class="form-check-input" id="{{ $permission->name }}"
value="{{ $permission->id }}" type="checkbox"
{{ $role->permissions->contains($permission->id) ? 'checked' : '' }} />
<label class="form-check-label" for="{{ $permission->name }}">
{{ $permission->display_name }}</label>
</div>
</div>
#endforeach
</div>
When I open roles-edit view I want to check boxes that have $permission->id related to role so I use
{{ $role->permissions->contains($permission->id) ? 'checked' : '' }}
But it did not work … all checkboxes is unchecked
instead using code:
{{ $role->permissions->contains($permission->id) ? 'checked' : '' }}
try this
#if($role->permissions->contains($permission->id)) checked #endif
also try to add wire:key directive to the parent div of the input element
<div class="form-check ms-5" wire:key="input-checkbox-{{ $permission->id }}">
I suggest you, create an array to retrieve the permissions ids of the role
public $permissionsIds = [];
public function mount(Role $role)
{
$this->role = $role;
$this->data = $role->toArray();
$this->permissionsIds = $this->role->permissions()->pluck('id');
}
// in blade
#if(in_array($permission->id,$permissionsIds)) checked #endif

Add invalid class to form-group using VueValidate to bootstrap CSS

How to add invalid class to form-group if the validation fails on input. By default VueValidate adds to the input.
<div class="form-group">
<label for="mobile" v-bind:class="{'text-danger': errors.has('mobile')}">Mobile</label>
<input type="text" v-validate="validation.mobile" class="form-control" v-model="user.mobile" name="mobile" id="mobile" />
<span class="invalid-feedback">{{ errors.first('mobile') }}</span>
</div>
Currently i am using v-bind:class="{'text-danger': errors.has('mobile')}" on the label and i get red colored label on field error.
If i could add invalid to form-group, it would be better to control with css. Below is my VueValidate Settings
Vue.use(VeeValidate, {
aria: true,
classes: true,
classNames: {
invalid: 'is-invalid'
}
});
You can bind a computed function to check errors and return the div's classes
{
computed: {
formGroupClass: function () {
if (this.error.has('mobile') ){
return ['form-group', 'invalid']
}
return ['form-group']
}
}
}
<div :class="formGroupClass">
<label for="mobile" v-bind:class="{'text-danger': errors.has('mobile')}">Mobile</label>
<input type="text" v-validate="validation.mobile" class="form-control" v-model="user.mobile" name="mobile" id="mobile" />
<span class="invalid-feedback">{{ errors.first('mobile') }}</span>
</div>

Trying to get property of non-object (View: C:\xampp\htdocs\MyP\resources\views\pekerja\index.blade.php)

i have problem 'Trying to get property of non-object' on this code. please someone check this code for make me clear. TQ
index.blade.php
<div class="form-group">
<label for="idUnit" class="control-label col-sm-3">Unit :</label>
<div class="col-sm-9">
<select name="idUnit" class="form-control input-sm" id="idUnit" disabled="disabled">
<option value="">Sila Pilih...</option> ---> error on this code!
#foreach ($KodUnit as $unit)
<option value="{{ $unit->id }}"
#if(isset(request()->idUnit) && request()->idUnit == $unit->id)
selected="selected"
#endif
>{{ $unit->nama }}</option>
#endforeach
</select>
</div>
</div>```
kodUnit model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class KodUnit extends Model
{
protected $table = 'kod_unit';
protected $primaryKey = 'id';
protected $fillable = ['id', 'kod', 'nama'];
public $timestamps = false;
}

How to add custom validator to reactive forms in Angular5

I have the following passwordvalidator which I don't know how to attach into the html. The way I am invoking it now it's not working loginForm.controls.password.errors.passwordValidator
See below in the actual code.
import { FormControl } from "#angular/forms";
export class PasswordValidator {
static getPasswordValidator() {
return function passwordValidator(control: FormControl): { [s: string]: boolean } {
// Write code here..
if (!control.value.match(/^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,})/)) {
return { invalidPassword: true };
}
return null;
}
}
}
Then this is how I am using it in login.ts
ngOnInit() {
this.loginForm = this.fb.group({
username: ['', [Validators.required, Validators.email]],
password: ['',
Validators.compose([
Validators.required,
PasswordValidator.getPasswordValidator()
]
)]
});
}
But can't find out how to add it to the formcontrol in login.html
<mat-form-field class="example-full-width">
<input id="password" formControlName="password" matInput placeholder="Password">
</mat-form-field>
<br>
<div *ngIf="loginForm.controls.password.invalid && (loginForm.controls.password.dirty || loginForm.controls.password.touched)"
class="alert alert-danger">
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.required">
You must fill out your password
</div>
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.passwordValidator && !loginForm.controls.password.errors.required">
Invalid email password
</div>
You should check if the key invalidPassword exist in errors of that controls or not like that
<mat-form-field class="example-full-width">
<input id="password" formControlName="password" matInput placeholder="Password">
</mat-form-field>
<br>
<div *ngIf="loginForm.controls.password.invalid && (loginForm.controls.password.dirty || loginForm.controls.password.touched)"
class="alert alert-danger">
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.required">
You must fill out your password
</div>
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.invalidPassword && !loginForm.controls.password.errors.required">
Invalid email password
</div>