Ruby on Rails/Devise/Simple Form:文本框为空时禁用按钮的实现疑问
你的实现方向不对哦
首先得明确说:你现在写的判断条件@message.comments.present?完全没get到需求点——这个条件是在检查这条消息已经存在的评论,和当前用户正在输入的内容半毛钱关系都没有,根本做不到“输入为空时禁用按钮”的效果。
然后要给你理清楚一个关键逻辑:纯Ruby(服务器端代码)没办法实时响应前端用户的输入变化。Ruby代码只在页面从服务器渲染出来的时候执行一次,页面加载到浏览器后,用户在输入框里敲字的过程是前端的事,服务器端的Ruby根本感知不到。
那如果不想用jQuery,又要实现需求,最优的方案是原生JS做前端实时监听+Ruby做服务器端验证,具体可以这么改:
1. 修正视图代码,添加原生JS监听
<%= simple_form_for([@message, @message.comments.build]) do |f| %> <div class="field"> <%= f.input :content, label: "Reply", id: "comment-content" %> </div> <!-- 初始状态设置为禁用按钮 --> <%= f.button :submit, class: "ui disabled button", id: "comment-submit" %> <script> // 获取输入框和按钮元素 const contentInput = document.getElementById('comment-content'); const submitButton = document.getElementById('comment-submit'); // 监听输入框的内容变化 contentInput.addEventListener('input', function() { // 去除首尾空格后判断是否为空 const hasContent = this.value.trim() !== ''; // 切换按钮的类 if (hasContent) { submitButton.classList.remove('disabled'); submitButton.classList.add('green'); } else { submitButton.classList.add('disabled'); submitButton.classList.remove('green'); } }); </script> <% end %>
2. 服务器端添加验证,防止空提交
就算前端禁用了按钮,用户还是可以通过浏览器控制台强行启用按钮提交空内容,所以必须在控制器里加一层验证:
# app/controllers/comments_controller.rb def create @message = Message.find(params[:message_id]) @comment = @message.comments.build(comment_params) # 先检查内容是否非空,再保存 if @comment.content.present? && @comment.save redirect_to @message, notice: 'Comment posted successfully!' else flash[:alert] = 'Oops, comment can\'t be empty!' redirect_to @message end end private def comment_params params.require(:comment).permit(:content) end
这样既满足了你不想用jQuery的要求,又实现了实时禁用按钮的用户体验,同时保证了数据的合法性。
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

