如何使用Alpine JS实现Laravel问卷评分按钮点击后保持聚焦状态
解决方案
你当前代码的核心问题是每个评分按钮都独立维护了自己的点击状态,没有做同组互斥,因此无法实现仅单个按钮选中的效果。我们只需要把选中状态提升到每个问题的评分组外层,让同组所有按钮共享同一个状态即可,状态由Alpine响应式管理,和页面焦点完全无关,点击任意区域都不会丢失选中效果。
修改后的完整代码
<div> @foreach ($formDetail as $num => $row) <div class="grid grid-cols-1 mt-2 p-4" wire:model.defer="formDetail.{{$num}}.question"> {{$formDetail[$num]['question']}} </div> <!-- 给每个问题的评分组加Alpine共享状态 --> <div class="flex flex-nowrap gap-2 p-6" x-data="{ selectedRating: null }"> @foreach ($ratings as $index => $r) <div> <button type="button" @click="selectedRating = {{$index}}" :class="selectedRating === {{$index}} ? 'bg-red-400' : 'bg-green-500'" wire:click.prevent="chooseRate({{$index}},{{$num}})" class="rounded text-white px-2.5 cursor-pointer" > {{$r}} </button> </div> @endforeach @error('rating') <div class="text-red-400"> {{ $message }} </div> @enderror </div> <div class="p-8 flex flex-nowrap gap-6 -my-6"> <span class="-mx-2">Lowest</span> <span class="mx-64">Highest</span> </div> <div class="flex flex-nowrap w-2/3 p-6"> <textarea wire:model.defer="formDetail.{{$num}}.comment" class="border-blue-200 border-2 w-3/4 h-16 focus:border-blue-500 focus:outline-none" name="comment" cols="30" rows="10" ></textarea> </div> @endforeach </div>
核心修改说明
- 移除了每个按钮外层单独定义的
x-data="{click:false}",避免状态隔离 - 在每个问题的评分容器上新增Alpine状态
selectedRating: null,存储当前问题选中的评分索引 - 按钮点击时同时给
selectedRating赋值为当前评分的索引 - 按钮样式绑定改为判断当前索引是否等于
selectedRating,匹配则显示选中样式 - 修复了原代码所有按钮共用同一个
id="rate"的问题,符合HTML id唯一的规范
内容的提问来源于stack exchange,提问作者kalecaliber
相关产品推荐
相关产品推荐

