Search code examples
laravellaravel-livewirealpine.js

Why I can not call public methods of form on the component?


I have a component app/Livewire/Admin/Common/AssignUsers.php with AssignUsersForm form :

<?php

namespace App\Livewire\Admin\Common;

use App\Livewire\Forms\Admin\Common\AssignUsersForm;
use Livewire\Component;

class AssignUsers extends Component
{
    public AssignUsersForm $form;
    public bool $selectSupervisorUser;
    public bool $onlyStaff;

    public function mount(bool $selectSupervisorUser,  bool $onlyStaff)
    {
        $this->selectSupervisorUser = $selectSupervisorUser;
        $this->onlyStaff = $onlyStaff;
    }

    public function render()
    {
        return view('livewire.admin.common.assign-users');
    }
}

I created AssignUsersForm with command :

php artisan livewire:form Admin/Common/AssignUsersForm

and filled file app/Livewire/Forms/Admin/Common/AssignUsersForm.php with code :

<?php

namespace App\Livewire\Forms\Admin\Common;

use App\Library\StaffUsers;
use App\Library\SupervisorUsers;
use Livewire\Component;
use Livewire\Form;

class AssignUsersForm extends Form
{
    public $selectedStaffUsers = [];
    public $staffUsersSelectionItems = [];
    public $supervisorUsersSelectionItems = [];

    function __construct(protected Component $component, protected $propertyName ) {
        parent::__construct($component, $propertyName);
        $this->staffUsersSelectionItems = StaffUsers::get(true);
        $this->supervisorUsersSelectionItems = SupervisorUsers::get(true);

    }

    public function addStaffUser()
    {
        dd("addStaffUser"); // I DO NOT SEE THIS MESSAGE
        $this->selectedStaffUsers[] = ['staff_user_id' => ''];
        \Log::info(varDump($this->selectedStaffUsers, ' -1 addStaffUser  $this->selectedStaffUsers::'));
    }

    public function removeStaffUser($index)
    {
        dd("removeStaffUser");  // I DO NOT SEE THIS MESSAGE
        unset($this->selectedStaffUsers[$index]);
        $this->selectedStaffUsers = array_values($this->selectedStaffUsers);
    }

}

But calling addStaffUser and removeStaffUser from my resources/views/livewire/admin/common/assign-users.blade.php :

     $form::{{ print_r($form, true) }}


    <button class="btn btn-danger form-control" type="button"
        wire:click="$parent.form.removeStaffUser({{ $index }})">{!! AppIconFacade::get(IconEnum::Delete, title:'Delete this Staff user' ) !!}
    </button>


    <button class="btn btn-warning form-control" wire:click="form.addStaffUser" type="button">+ Add</button>

For the first button I got error in browser's console :

Alpine Expression Error: $wire.$parent.form.removeStaffUser is not a function
Expression: "$wire.$parent.form.removeStaffUser(0)"

For the second nothing happens in browser's console - but it seems as valid syntax.

Checking output of $form in the code above I see

App\Livewire\Forms\Admin\Common\AssignUsersForm Object

mentioned.

How to make it working ?


Solution

  • Currently it doesn't seem possible to call a nested function. I tried finding out how the wire:click is handled in the source code but had no luck in the complex JavaScript. Probably the method handling the click isn't processing the dot. In this case, just place the function on your main component and then reference the form component:

    public function addStaffUser()
    {
        $this->form->addStaffUser();
    }