我是几个月前发现Livewire的新手,对Vanilla JS有点生疏。
我已经创建了一个Livewire组件来过滤新闻文章表,但我很难使用Choices.js库来选择多个类别并将它们放入数组中。
Livewire组件:
public $filters = [
...
'categories' => [],
...
];
public function render()
{
$reports = Article::query()
->where('active', true)
->when($this->filters['categories'], function ($query, $category_ids) {
$query->whereHas('categories', function ($query) use ($category_ids) {
$query->whereIn('category_id', $category_ids);
});
})
->get();
$categories = Category::all();
return view('livewire.reports.list-reports', compact('categories'));
}
刀片:
...
<div class="mb-2" wire:ignore>
<label class="mb-1">Category</label>
<select wire:model="filters.categories" class="form-control js-choice" multiple id="filter-categories">
@foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->type }}</option>
@endforeach
</select>
</div>
...
@section('page-scripts')
<script src="{{ asset('assets/js/user/plugins/choices/choices.js') }}"></script>
@endsection
choices.js
文件:
import Choices from "choices.js";
const elements = document.querySelectorAll('.js-choice');
elements.forEach((item) => {
const choices = new Choices(item, {
removeItems: true,
removeItemButton: true,
searchEnabled: true,
placeholder: true,
placeholderValue: 'Select your options'
});
return choices;
});
问题是
在不使用choices.js
和使用本机浏览器多选框的情况下,它工作得非常好,filter.categories
属性输出"categories": ["13","2","26"...]
并相应地更新控制器查询,显示具有所选类别ID的所有新闻文章。
但是使用choices.js
,它只输出最后一次点击的值,看起来像这样:"categories": {"value":"13"}
。因为它不在数组中,所以它只是返回在此示例中ID为13
的所有新闻文章。单击多个选项只是将属性更改为最后单击的选项。此外,从选择框中清除所有选项不会将filters.categories
属性重置为空,它只是使用最后关闭的选项的ID填充它。
我如何收集所选选项的ID并将其放置到filter.categories
数组中,并在删除项目时删除它们?
我知道我需要在choices.js
文件中放入一些逻辑来访问所选选项的detail.value
,但我真的很难让它工作。我已经探索了Alpine,因为我相信这可能是关键,但我不知道从哪里开始。
任何帮助都是非常感谢的,我已经被困在这几天。
1条答案
按热度按时间ajsxfq5m1#
我没有choices.js的经验,所以我会根据我使用slimselect.js的经验尽我所能。
基本上,当JS应用于选择框时,它通常会抽象出您实际单击的内容,并且这些元素已经在wire:ignore块中,因此部分DOM不会重新加载。
所以当我使用你描述的东西时,我使用JS回调函数来设置Livewire组件的属性。
最简单的形式是这样的
只要看看choices.js文档,你就可以使用'choice'事件。
希望这能帮上忙