Laravel livewire 动态添加复选框
Laravel livewire adding checkbox dynamically
所以我这几天一直在学习 livewire
我正在尝试将复选框动态添加到 livewire 组件。
我已经可以在每次单击加号按钮时添加新的复选框
但是当我尝试单击添加的复选框时出现问题
就像我尝试单击第 3 个复选框时的屏幕截图一样,它被单击了 1 秒,然后单击移动到复选框 1
当我再次点击时,第二个复选框被点击
第三次点击后,第三个复选框被点击
所有添加的复选框都会发生
Here is the form screenshot
这是我的代码
addTodo.blade.php
<div x-data="{ modalOpen : false }" x-cloak >
<div class="group text-center cursor-pointer fixed bottom-0 right-0 mb-4 mr-4 flex items-center content-center overflow-y-auto">
<div class="group-hover:opacity-100 transition-all ease-in-out duration-300 opacity-0 p-2 mr-3 bg-white rounded text-sm">Add New Todo</div>
<button @click="modalOpen = true" class="m-auto w-12 h-12 bg-blue-500 rounded-full shadow-lg text-lg text-white text-center">
<svg class="mx-auto" width="32px" height="32px" viewBox="0 0 16 16" class="bi bi-plus" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
</svg>
</button>
</div>
<div x-show.immediate.transition.opacity="modalOpen" class="modal--wrapper bg-black flex items-center content-center bg-opacity-50 fixed top-0 left-0 w-full h-full">
<div @click.away="modalOpen = false" class="modal w-1/2 shadow-lg relative bg-white rounded mx-auto ">
<div class="modal__header flex items-center py-4 bg-blue-500 text-white px-8 rounded-tr rounded-tl">
<span>Add new Todo</span>
<div @click="modalOpen = false" class=" ml-auto text-white text-3xl cursor-pointer">
×
</div>
</div>
<form wire:submit.prevent="addtodo">
<div class="modal__body mt-8 px-8">
<div class="flex flex-col">
<input type="text" wire:model="title" placeholder="Todo name" class="border-2 outline-none focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded px-4 py-2 sm:text-sm border-gray-300" />
@error('title')
<span class="text-sm text-red-500 mt-1">{{$message}}</span>
@enderror
</div>
<div class="flex flex-col mt-3">
<textarea wire:model="description" placeholder="Todo description" class="border-2 outline-none focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded px-4 py-2 sm:text-sm border-gray-300"></textarea>
</div>
<div class="flex flex-col">
<div class="mt-3 flex items-center ">
<input type="text" wire:model="task.0" class="border-2 flex-1 outline-none focus:ring-blue-500 focus:border-blue-500 rounded px-4 py-2 sm:text-sm border-gray-300" placeholder="Task description" />
<div class="flex items-start ml-3">
<div class="flex items-center h-5">
<label class="text-sm ml-1 font-medium cursor-pointer text-gray-700">
<input
wire:key="0"
wire:model="is_done.0"
id="isdone0"
type="checkbox"
class="focus:ring-blue-500 h-4 w-4 cursor-pointer text-blue-600 border-gray-300 rounded">
Is done
</label>
</div>
</div>
<button type="button" wire:click.prevent="add_task({{$add_index}})" class=" ml-3 focus:ring-blue-900 rounded bg-blue-500 text-white hover:bg-blue-600">
<svg class="mx-auto" width="24px" height="24px" viewBox="0 0 16 16" class="bi bi-plus" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
</svg>
</button>
</div>
@error('task.0')
<span class="text-sm text-red-500 mt-1">{{$message}}</span>
@enderror
</div>
@foreach($task_input as $key => $task)
<div class="mt-3 flex items-center ">
<input type="text" wire:model="task.{{$task}}" class="border-2 flex-1 outline-none focus:ring-blue-500 focus:border-blue-500 rounded px-4 py-2 sm:text-sm border-gray-300" placeholder="Task description" />
<div class="flex items-start ml-3">
<div class="flex items-center h-5">
<label
wire:key="{{$task}}"
class="ml-1 text-sm font-medium text-gray-700">
<input
wire:key="{{$task}}"
wire:model="is_done.{{$task}}"
id="isdone{{$task}}"
type="checkbox"
class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-300 rounded">
Is done
</label>
</div>
</div>
<button type="button" wire:click.prevent="remove_task({{$key}})" class="ml-3 text-red-500 cursor-pointer">
<svg width="24px" height="24px" viewBox="0 0 16 16" class="bi bi-trash" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
</svg>
</button>
</div>
<div class="flex flex-col">
@error('task.*')
<span class="text-sm text-red-500 mt-1">{{$message}}</span>
@enderror
</div>
@endforeach
</div>
<div class="modal__footer mt-5 pt-4 pb-8 px-8">
<button type="submit" class="bg-blue-500 text-white px-3 py-2 rounded hover:bg-blue-600">Add Todo</button>
</div>
</form>
</div>
</div>
</div>
addTodo.php
<?php
namespace App\Http\Livewire\Todo;
use App\Models\Todo;
use App\Models\TodoItem;
use Livewire\Component;
class Addtodo extends Component
{
public $title, $description;
public $task, $is_done;
public $task_input = [];
public $add_index = 0;
protected $rules = [
'title' => 'required',
'description' => 'nullable',
'task.0' => 'required',
'is_done.0' => 'nullable',
'task.*' => 'required',
'is_done.*' => 'nullable'
];
protected $messages = [
'task.0.required' => 'The task description field is required',
'task.*' => 'The task description field is required',
];
public function remove_task($i)
{
unset($this->task_input[$i]);
}
public function add_task($add_index)
{
$add_index = $add_index + 1;
$this->add_index = $add_index;
array_push($this->task_input, $add_index);
}
public function render()
{
return view('livewire.todo.addtodo');
}
public function addtodo()
{
$this->validate();
$todo = new Todo();
$todo->title = $this->title;
$todo->description = ($this->description == null) ? "" : $this->description;
$todo->creator = 1;
$result = $todo->save();
foreach ($this->task as $key => $task) {
$todo_item = new TodoItem();
$todo_item->description = $task;
$todo_item->is_done = ($this->is_done == null) ? false : $this->is_done[$key];
$todo_item->todo_id = $todo->id;
$todo_item->save();
}
$this->reset_fields();
$this->emit('todoAdded');
}
public function reset_fields()
{
$this->title = "";
$this->description = "";
$this->task = [];
$this->is_done = [];
$this->task_input = [];
$this->add_index = 0;
}
}
所以发生这种情况是因为我没有设置复选框的初始值
我通过像这样更改我的代码来实现解决方案
public function add_task($add_index)
{
$add_index = $add_index + 1;
$this->add_index = $add_index;
$this->is_done[$add_index] = false;
array_push($this->task_input, $add_index);
}
所以我这几天一直在学习 livewire 我正在尝试将复选框动态添加到 livewire 组件。 我已经可以在每次单击加号按钮时添加新的复选框 但是当我尝试单击添加的复选框时出现问题 就像我尝试单击第 3 个复选框时的屏幕截图一样,它被单击了 1 秒,然后单击移动到复选框 1 当我再次点击时,第二个复选框被点击 第三次点击后,第三个复选框被点击 所有添加的复选框都会发生
Here is the form screenshot
这是我的代码
addTodo.blade.php
<div x-data="{ modalOpen : false }" x-cloak >
<div class="group text-center cursor-pointer fixed bottom-0 right-0 mb-4 mr-4 flex items-center content-center overflow-y-auto">
<div class="group-hover:opacity-100 transition-all ease-in-out duration-300 opacity-0 p-2 mr-3 bg-white rounded text-sm">Add New Todo</div>
<button @click="modalOpen = true" class="m-auto w-12 h-12 bg-blue-500 rounded-full shadow-lg text-lg text-white text-center">
<svg class="mx-auto" width="32px" height="32px" viewBox="0 0 16 16" class="bi bi-plus" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
</svg>
</button>
</div>
<div x-show.immediate.transition.opacity="modalOpen" class="modal--wrapper bg-black flex items-center content-center bg-opacity-50 fixed top-0 left-0 w-full h-full">
<div @click.away="modalOpen = false" class="modal w-1/2 shadow-lg relative bg-white rounded mx-auto ">
<div class="modal__header flex items-center py-4 bg-blue-500 text-white px-8 rounded-tr rounded-tl">
<span>Add new Todo</span>
<div @click="modalOpen = false" class=" ml-auto text-white text-3xl cursor-pointer">
×
</div>
</div>
<form wire:submit.prevent="addtodo">
<div class="modal__body mt-8 px-8">
<div class="flex flex-col">
<input type="text" wire:model="title" placeholder="Todo name" class="border-2 outline-none focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded px-4 py-2 sm:text-sm border-gray-300" />
@error('title')
<span class="text-sm text-red-500 mt-1">{{$message}}</span>
@enderror
</div>
<div class="flex flex-col mt-3">
<textarea wire:model="description" placeholder="Todo description" class="border-2 outline-none focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded px-4 py-2 sm:text-sm border-gray-300"></textarea>
</div>
<div class="flex flex-col">
<div class="mt-3 flex items-center ">
<input type="text" wire:model="task.0" class="border-2 flex-1 outline-none focus:ring-blue-500 focus:border-blue-500 rounded px-4 py-2 sm:text-sm border-gray-300" placeholder="Task description" />
<div class="flex items-start ml-3">
<div class="flex items-center h-5">
<label class="text-sm ml-1 font-medium cursor-pointer text-gray-700">
<input
wire:key="0"
wire:model="is_done.0"
id="isdone0"
type="checkbox"
class="focus:ring-blue-500 h-4 w-4 cursor-pointer text-blue-600 border-gray-300 rounded">
Is done
</label>
</div>
</div>
<button type="button" wire:click.prevent="add_task({{$add_index}})" class=" ml-3 focus:ring-blue-900 rounded bg-blue-500 text-white hover:bg-blue-600">
<svg class="mx-auto" width="24px" height="24px" viewBox="0 0 16 16" class="bi bi-plus" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
</svg>
</button>
</div>
@error('task.0')
<span class="text-sm text-red-500 mt-1">{{$message}}</span>
@enderror
</div>
@foreach($task_input as $key => $task)
<div class="mt-3 flex items-center ">
<input type="text" wire:model="task.{{$task}}" class="border-2 flex-1 outline-none focus:ring-blue-500 focus:border-blue-500 rounded px-4 py-2 sm:text-sm border-gray-300" placeholder="Task description" />
<div class="flex items-start ml-3">
<div class="flex items-center h-5">
<label
wire:key="{{$task}}"
class="ml-1 text-sm font-medium text-gray-700">
<input
wire:key="{{$task}}"
wire:model="is_done.{{$task}}"
id="isdone{{$task}}"
type="checkbox"
class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-300 rounded">
Is done
</label>
</div>
</div>
<button type="button" wire:click.prevent="remove_task({{$key}})" class="ml-3 text-red-500 cursor-pointer">
<svg width="24px" height="24px" viewBox="0 0 16 16" class="bi bi-trash" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
</svg>
</button>
</div>
<div class="flex flex-col">
@error('task.*')
<span class="text-sm text-red-500 mt-1">{{$message}}</span>
@enderror
</div>
@endforeach
</div>
<div class="modal__footer mt-5 pt-4 pb-8 px-8">
<button type="submit" class="bg-blue-500 text-white px-3 py-2 rounded hover:bg-blue-600">Add Todo</button>
</div>
</form>
</div>
</div>
</div>
addTodo.php
<?php
namespace App\Http\Livewire\Todo;
use App\Models\Todo;
use App\Models\TodoItem;
use Livewire\Component;
class Addtodo extends Component
{
public $title, $description;
public $task, $is_done;
public $task_input = [];
public $add_index = 0;
protected $rules = [
'title' => 'required',
'description' => 'nullable',
'task.0' => 'required',
'is_done.0' => 'nullable',
'task.*' => 'required',
'is_done.*' => 'nullable'
];
protected $messages = [
'task.0.required' => 'The task description field is required',
'task.*' => 'The task description field is required',
];
public function remove_task($i)
{
unset($this->task_input[$i]);
}
public function add_task($add_index)
{
$add_index = $add_index + 1;
$this->add_index = $add_index;
array_push($this->task_input, $add_index);
}
public function render()
{
return view('livewire.todo.addtodo');
}
public function addtodo()
{
$this->validate();
$todo = new Todo();
$todo->title = $this->title;
$todo->description = ($this->description == null) ? "" : $this->description;
$todo->creator = 1;
$result = $todo->save();
foreach ($this->task as $key => $task) {
$todo_item = new TodoItem();
$todo_item->description = $task;
$todo_item->is_done = ($this->is_done == null) ? false : $this->is_done[$key];
$todo_item->todo_id = $todo->id;
$todo_item->save();
}
$this->reset_fields();
$this->emit('todoAdded');
}
public function reset_fields()
{
$this->title = "";
$this->description = "";
$this->task = [];
$this->is_done = [];
$this->task_input = [];
$this->add_index = 0;
}
}
所以发生这种情况是因为我没有设置复选框的初始值
我通过像这样更改我的代码来实现解决方案
public function add_task($add_index)
{
$add_index = $add_index + 1;
$this->add_index = $add_index;
$this->is_done[$add_index] = false;
array_push($this->task_input, $add_index);
}