skip to Main Content

I have been trying to get two modal to work on the same table. I have one modal for the edit user and the other one to add user.

I know when you follow the tuttorial on Livewire docs they use one modal for the both action.

My problem is that I want to validate in the input that there is not a duplicate email in the database.

My Blade View:

<div>
<h1 class="text-2xl font-semibold text-gray-900">Users</h1>
<div class="py-4 space-y-4">
    <div class="flex justify-between">
        <div class="w-1/4">
            
            <x-input.text wire:model="search" placeholder="Search Users..."/>
        
        </div>
        <div>

            <x-button.primary wire:click="create"><x-icon.plus/> New</x-button.primary>

        </div>
    </div>
</div>

<div class="flex-col space-y-4">
    <x-table>
        <x-slot name="head">
            <x-table.heading sortable multi-column wire:click="sortBy('id')" :direction="$sorts['id'] ?? null">Id</x-table.heading>
            <x-table.heading sortable multi-column wire:click="sortBy('email')" :direction="$sorts['email'] ?? null">Email</x-table.heading>
            <x-table.heading sortable multi-column wire:click="sortBy('username')" :direction="$sorts['usernames'] ?? null">User Name</x-table.heading>
            <x-table.heading sortable multi-column wire:click="sortBy('accesslevel')" :direction="$sorts['accesslevel'] ?? null">Access Level</x-table.heading>
            <x-table.heading />
        </x-slot>

        <x-slot name="body">
         
            @forelse ($users as $user)
            <x-table.row wire:loading.class.delay="opacity-50" wire:key="row-{{ $user->id }}">
             

                <x-table.cell>
                    
                        

                        <p class="text-cool-gray-600">
                            {{ $user->id }}
                        </p>
                   
                </x-table.cell>

                <x-table.cell>
                    <span class="text-cool-gray-900 font-medium">{{ $user->email }} </span>
                </x-table.cell>

                <x-table.cell>
                    <span class="inline-flex text-cool-gray-900  font-medium ">
                        {{ $user->username }}
                    </span>
                </x-table.cell>

                <x-table.cell>
                    {{ $user->accesslevel }}
                </x-table.cell>

                <x-table.cell>
                    <x-button.link wire:click="edit({{ $user->id }})">Edit</x-button.link>
                </x-table.cell>
            </x-table.row>
            @empty
            <x-table.row>
                <x-table.cell colspan="6">
                    <div class="flex justify-center items-center space-x-2">
                        <x-icon.inbox class="h-8 w-8 text-cool-gray-400" />
                        <span class="font-medium py-8 text-cool-gray-400 text-xl">No users found...</span>
                    </div>
                </x-table.cell>
            </x-table.row>
            @endforelse
        </x-slot>
    </x-table>

</div>

<!-- Edit User -->
<div>
    <form wire:submit.prevent="save">
        <x-modal.dialog wire:model.lazy="showEditModal">
            <x-slot  name='title' >
            
                Edit User

            </x-slot>
            
                <x-slot name='content'>
                    
                    <div>
                        <div>
                            <x-input.group for="email" label="Email" :error="$errors->first('editing.email')">
                                
                                <x-input.text wire:model.lazy="editing.email" id="email" placeholder="Email"/>
                                
                            </x-input.group>
                        </div>

                    </div>

                    <x-input.group for="username" label="Username" :error="$errors->first('editing.username')">
                        
                        <x-input.text wire:model.lazzy="editing.username" id="username" placeholder="Username"/>
                    
                    </x-input.group> 
                    
                    <x-input.group for="accesslevel" label="Access Level" :error="$errors->first('editing.accesslevel')">
                        
                        <x-input.select wire:model.lazy="editing.accesslevel" id="accesslevel">

                            @foreach (AppModelsUser::LEVEL as $value => $label)
                                <option value="{{ $value }}">{{ $label }}</option>
                            @endforeach

                        </x-input.select>

                    </x-input.group>
                

            </x-slot>
            
            
            <x-slot name='footer'>
                
                <x-button.secondary wire:click="$set('showEditModal', false)">Cancel</x-button.secondary>

                
                <div>
                    <x-button.primary type="submit">Save</x-button.primary>
                    @if ($errors->any())
            
                    <div class="alert alert-danger">
                        <ul>
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                        </ul>
                    </div>
                    @endif
                </div>
            </x-slot>
        
        </x-modal.dialog>

    </form>
</div>
<!--Create user -->
<form wire:submit.prevent="saveCreate">
    <x-modal.dialog wire:model.lazy="showCreateModal">
        <x-slot  name='title' >
        
            Create User

        </x-slot>
        
            <x-slot name='content'>
                

                
                <x-input.group for="emailCreate" label="Email" :error="$errors->first('creating.email')">
                    
                    <x-input.text wire:model.lazy="creating.email" id="emailCreate" placeholder="Email"/>
                
                </x-input.group>
                
                <x-input.group for="usernameCreate" label="Username" :error="$errors->first('creating.username')">
                    
                    <x-input.text wire:model.lazy="creating.username" id="usernameCreate" placeholder="Username"/>
                
                </x-input.group>

                
                <x-input.group for="accesslevelCreate" label="Access Level" :error="$errors->first('creating.accesslevel')">
                    
                    <x-input.select wire:model.lazy="creating.accesslevel" id="accesslevelCreate">

                        @foreach (AppModelsUser::LEVEL as $value => $label)
                            <option value="{{ $value }}">{{ $label }}</option>
                        @endforeach

                    </x-input.select>

                    

                </x-input.group>
            

        </x-slot>
        
        
        <x-slot name='footer'>
            
            <x-button.secondary wire:click="$set('showCreateModal', false)">Cancel</x-button.secondary>
            <div>
            <x-button.primary type="submit">Save</x-button.primary>
            @if ($errors->any())
    
            <div class="alert alert-danger">
                <ul>
                    @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
            @endif
        </div>

        </x-slot>
    
    </x-modal.dialog>

</form>

When I enter my email in my add modal I am getting a validation error saying I need to input an email, but I clearly typed on in.

I guess there is somthing wrong with my validation, or what I want to do is not possible in Livewire.

Livewire component:


namespace AppHttpLivewire;

use AppModelsUser;
use CreateUsersTable;
use IlluminateSupportFacadesHash;
use IlluminateValidationRule;
use LivewireComponent;

class UserTable extends Component
{
    
    public $showEditModal = false;
    public $showCreateModal = false;
    public $password = '';
    public $search = '';  

    
    public function mount() 
    { 
        
        $this->editing = User::make();
        $this->creating = User::make();
        $this->editing = $this->makeBlankUser(); 
    }
    public User $editing;
    public User $creating;

    public function rules() 
    { 
        return [ 
            'editing.email' => 'required',
            'editing.accesslevel' => 'required|in:'.collect(User::LEVEL)->keys()->implode(','),
            'editing.username' => '',
            'editing.password' => '',
            'creating.accesslevel' => 'required|in:'.collect(User::LEVEL)->keys()->implode(','),
            'creating.username' => 'required',
            'creating.email' => 'required|email',
        ];        
           
     }


    
    public function edit(User $user)
    {       
        $this->editing = $user;      

        $this->showEditModal = true;
    }

    public function makeBlankUser()
    {
        return User::make([ 'accesslevel' => '3']);
    }
    
    public function create()
    {
        if ($this->creating->getKey()) $this->creating = $this->makeBlankUser();
        $this->showCreateModal = true;
    }

    public function save()
    {      
       
        $this->validate();
        
        $this->editing->save();

        $this->showEditModal = false;
       
        
    }
    public function saveCreate()
    {
        

        $this->validate();     
       
        
        $this->creating->save();

        $this->showCreateModal = false;
        
        
    }

    public function render()
    {
        return view('livewire.user-table', [
            'users' => User::search('email',$this->search)->paginate(25),
        ]);
    }
}

What am I missing ?

2

Answers


  1. Chosen as BEST ANSWER

    I ended up adding a function inputValidation(). I toggle on and off the array I want to pass to the rules with my create() or edit().

    
    namespace AppHttpLivewire;
    
    use AppModelsUser;
    use LivewireComponent;
    use LivewireWithPagination;
    
    class UserTable extends Component
    {
        use WithPagination;
        public $showEditModal = false;
        public $showCreateModal = false;
        public $password = '';
        public $search = '';
        public $createUser = false;
        public $editUser =false;
        public $rulesEdit = [];
        public $rulesCreate = [];
        public $sortField;
        public $sortDirection = 'asc';
        public User $editing;
    
        protected $queryString = ['sortField', 'sortDirection'];
        protected $listeners = ['refreshUsers' => '$refresh'];
    
     
        
        public function mount() 
        { 
            
            $this->editing = User::make();   
            $this->editing = $this->makeBlankUser()
        }
        
      
        protected $rules = '';
       
       
        public function rules() 
        { 
            
            $rules = $this->inputValidation();
           
            return $rules;   
          
         }
    
        public function inputValidation()
        {
    
            if($this->editUser = true){        
                $validatedData=[
                        'editing.email' => 'required',
                        'editing.accesslevel' => 'required|in:'.collect(User::LEVEL)->keys()->implode(','),
                        'editing.username' => ''
                    ];
                return $validatedData;
            }
    
            
            if($this->createUser = true){
                
                $validatedData=[
                    'editing.email' => 'required|email|unique:user,email', 
                    'editing.accesslevel' => 'required|in:'.collect(User::LEVEL)->keys()->implode(','),
                    'editing.username' => ''     
                ];
                return $validatedData;   
            }
    
        }
        
        public function edit(User $user)
        {       
    
    
            $this->editUser = true;
    
            $this->editing = $user;
        
            $this->showEditModal = true;
        }
    
        public function makeBlankUser()
        {
            return User::make([ 'accesslevel' => '3']);
        }
        
        public function create(User $user)
        {       
            $this->createUser = true;        
    
            
            if ($this->editing->getKey()) $this->editing = $this->makeBlankUser();
            
            $this->showCreateModal = true;
            
        }
    
        public function save()
        {      
        
            $this->validate();
            
            $this->editing->save();
    
            $this->showEditModal = false;
            $this->editUser = false;
            $this->showCreateModal = false;
           
            
        }
    
    
    
        public function sortBy($field)
        {
            $this->sortDirection = $this->sortField === $field
                ? $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc'
                : 'asc';
    
            $this->sortField = $field;
        }
        
        public function render()
        {
            return view('livewire.user-table', [
                'users' => User::search('email',$this->search)->orderBy($this->sortField, $this->sortDirection)->paginate(25),
            ]);
        }
    }```
    

Please signup or login to give your own answer.
Back To Top
Search