Rails 7中使用Stimulus JS实现至少勾选一个复选框才启用提交按钮
Rails 7 实现提交按钮禁用直到勾选至少一个复选框
步骤1:构建表单结构
在Rails视图中创建表单,提交按钮默认设置为disabled状态,同时给复选框组添加统一类名,方便后续JS选择:
<%= form_with(model: your_model, url: your_path) do |form| %> <!-- 用collection_check_boxes批量生成复选框 --> <%= form.collection_check_boxes :category_ids, Category.all, :id, :name, class: 'target-checkbox' do |b| %> <%= b.label do %> <%= b.check_box %> <%= b.text %> <% end %> <% end %> <!-- 默认禁用的提交按钮 --> <%= form.submit '提交', id: 'form-submit-btn', disabled: true %> <% end %>
如果是手动添加单个复选框,同样给每个复选框加统一类名:
<%= check_box_tag 'options[]', 'option1', false, class: 'target-checkbox' %> <%= label_tag 'options_option1', '选项1' %> <%= check_box_tag 'options[]', 'option2', false, class: 'target-checkbox' %> <%= label_tag 'options_option2', '选项2' %> <%= submit_tag '提交', id: 'form-submit-btn', disabled: true %>
步骤2:添加交互逻辑
方式一:使用Stimulus控制器(推荐,符合Rails 7生态)
- 生成Stimulus控制器:
rails generate stimulus checkbox_submit
- 在
app/javascript/controllers/checkbox_submit_controller.js中编写逻辑:
import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["checkbox", "submit"] connect() { // 页面加载时检查初始状态 this.toggleSubmitStatus() } toggleSubmitStatus() { // 判断是否有至少一个复选框被勾选 const hasChecked = this.checkboxTargets.some(box => box.checked) this.submitTarget.disabled = !hasChecked } }
- 在视图中绑定Stimulus控制器和目标元素:
<%= form_with(model: your_model, url: your_path, data: { controller: "checkbox-submit" }) do |form| %> <%= form.collection_check_boxes :category_ids, Category.all, :id, :name, class: 'target-checkbox', data: { checkbox_submit_target: "checkbox" } do |b| %> <%= b.label do %> <%= b.check_box %> <%= b.text %> <% end %> <% end %> <%= form.submit '提交', data: { checkbox_submit_target: "submit" }, disabled: true %> <% end %>
方式二:原生JavaScript(无需Stimulus)
在视图底部添加defer脚本,适配Turbo导航的场景:
<script defer> document.addEventListener('turbo:load', () => { const checkboxes = document.querySelectorAll('.target-checkbox'); const submitBtn = document.getElementById('form-submit-btn'); // 更新按钮状态的函数 const updateSubmitState = () => { const hasChecked = Array.from(checkboxes).some(cb => cb.checked); submitBtn.disabled = !hasChecked; }; // 初始加载时检查状态 updateSubmitState(); // 给每个复选框绑定change事件 checkboxes.forEach(cb => { cb.addEventListener('change', updateSubmitState); }); }); </script>
注意事项
- 如果复选框有默认勾选的配置,页面加载时的初始检查会自动启用提交按钮;
- 使用Turbo导航时,必须用
turbo:load事件替代DOMContentLoaded,确保页面刷新后脚本仍能正常工作。
内容的提问来源于stack exchange,提问作者Atekelt Afework
相关产品推荐
相关产品推荐

