Я использую AlpineJs для создания небольшого проекта. У нас есть несколько вариантов, которые меняют цвет поля, когда оно активно/неактивно. Проблема в том, что я знаю, как этого добиться, только если это одно значение.
Livewire (php)
class ListingPromoteForm extends Component
{
use WithPagination;
public Listing $listing;
protected $marketplaces;
public $userCurrency;
public $total = 0;
public $selected = [];
public $modalOpen = false;
public function render()
{
$this->userCurrency = Auth::user()->userCurrency()->where('is_primary', true)->first();
$this->marketplaces = Marketplace::paginate(10);
return view('livewire.form.listing-promote-form',['marketplaces' => $this->marketplaces]);
}
public function submit(){
dd($this->selected);
}
}
Livewire (компонент)
<div class = "p-2" x-data = "{total:0,selected:@entangle('selected')}" wire:ignore>
<x-page-box class = "mb-3 bg-gray-50 rounded-lg">
<x-heading-2>{{ __('Current :name', ['name' => __('Balance')]) }}</x-heading-2>
<div class = "flex justify-end">
<span class = "font-bold">Rp {{ number_format($userCurrency->amount) }}</span>
</div>
</x-page-box>
<!-- Showing total -->
<div class = "p-2 flex justify-between">
<span>{{ __(':name Total', ['name' => __('Cost')]) }}</span>
<span x-text = "total"></span>
</div>
<form wire:submit = "submit">
<ul class = "divide-y-2 border mb-3 max-h-[500px] overflow-y-auto">
@foreach ($marketplaces as $item)
<li wire:key = "{{ $item->id }}">
<label for = "selected.{{ $item->id }}"
:class = "{{ $item->id }} in selected ? 'bg-green-100' : 'bg-white'"
class = "p-2 cursor-pointer hover:bg-blue-100 flex justify-between items-center">
<div class = "flex items-center">
<input value = "{{ $item->id }}" x-model = "selected" id = "selected.{{ $item->id }}"
name = "selected.{{ $item->id }}" type = "checkbox"
class = "text-gray-900 translate-y-px focus:ring-gray-700 me-2 rounded-lg block">
<div>
<p>{{ $item->website->domain }}</p>
<p class = "text-xs"><i class = "fa-solid fa-chart-simple ps-1"></i>
{{ __('Traffic :amount', ['amount' => 0]) }}</p>
</div>
</div>
<span class = "text-xs">Rp {{ number_format($item->price) }}</span>
</label>
</li>
@endforeach
</ul>
{{ $marketplaces->links() }}
<div class = "flex justify-end mt-2">
<x-primary-button>{{ __('Submit') }} <i
class = "ps-2 fa-solid fa-circle-arrow-right"></i></x-primary-button>
</div>
</form>
<x-shared.loading-widget wire:loading.flex>{{ __('Processing') }}</x-shared.loading-widget>
</div>
Я очень ценю любой ответ. Я прочитал документацию alpineJs, но мне не повезло. Спасибо






Если выбран массив, он должен работать, если выбран объект, вы можете использовать форму 'key' in selected
Условие не обязательно должно быть включено в массив, но может работать и в том случае, если оно включено:
Объект
<label for = "selected.{{$item->id}}"
class = "p-2 cursor-pointer hover:bg-blue-100 flex justify-between items-center"
:class = "'{{$item->id}}' in selected ? 'bg-green-100' : 'bg-white'"
>
The label
</label>
Множество
<label for = "selected.{{$item->id}}"
class = "p-2 cursor-pointer hover:bg-blue-100 flex justify-between items-center"
:class = "selected.includes({{$item->id}}) ? 'bg-green-100' : 'bg-white'"
>
The label
</label>
Другой вариант — использовать выражение JSON, но в этой ситуации оно немного многословно:
:class = "{'bg-green-100': selected.includes({{$item->id}}), 'bg-white': !selected.includes({{$item->id}})}"
Из опубликованного кода я вижу, что выбранная переменная представляет собой массив, содержащий значения выбранных флажков. Таким образом, ваш первоначальный код был на правильном пути (в моем предыдущем ответе была опечатка, теперь исправленная), selected.includes() - это правильный метод для проверки того, установлен ли флажок, в любом случае, поскольку атрибуты значения, взятые из DOM всегда представляет собой строки, и метод include() применяет строгое сравнение, поэтому мы должны добавлять кавычки к искомому значению:
:class = "selected.includes('{{$item->id}}') ? 'bg-green-100' : 'bg-white'"
обратите внимание на кавычки вокруг {{$item->id}}
Проблема несоответствия пятого и первого элементов, похоже, не связана с переключением класса, вы можете отладить ее, проверив DOM с помощью браузера, также вы можете добавить эту проверку Alpine в основной <div> для проверки в реальном времени. из выбранных идентификаторов:
<div x-text = "selected"></div>
Я попробовал оба варианта выше, но это не сработало. Я пытаюсь сделать вывод, и он показывает следующее: 2,3,4,5. Если бы я сделал это так (:class = "{{ $item->id }} в выбранном? 'bg-green-100': 'bg-white'"). Это работает, но есть ошибка. Если щелкнуть пятый элемент, будет применен первый элемент.
Я выдвинул гипотезу о нескольких сценариях, но если вы хотите получить более точный ответ, вам необходимо предоставить более конкретную информацию. Откуда берется выбранное? Как оно определяется и структурируется? Пожалуйста, отредактируйте свой вопрос и включите любую дополнительную информацию, которая может быть полезна.
Я отредактировал его с полным кодом
Я добавил некоторую информацию в свой ответ
Это работает, не знаю, нам нужно туда добавить кавычки. Спасибо
Знаете ли вы об использовании includeNot? Я просматриваю документацию alpineJS, но не могу ее найти. Или мне следует просто использовать вот так? !items.includes()
!items.includes() — правильное выражение, обратите внимание, что это общий JS-код, а не специфичный для AlpineJS.
Хорошо, я только что понял, что внутри x-text, x-data и т. д. мы также можем установить туда JavaScript.
Почему у вас есть квадратные скобки
[]вокруг класса, когдаselectedявляется массивом?