新手问题 如何在用户注册表单获取 text_field value 并通过参数传到 controller 中

springwq · 2016年01月07日 · 最后由 springwq 回复于 2016年03月04日 · 2776 次阅读

目前的项目有这样的需求,在用户的注册表单界面,需要用户输入手机验证码,然后才能注册成功。

怎样才能在不提交 form 的情况下,把 用户填写的手机号码获取到,然后传递到 Users#send_sms action 中呢?

在这个注册页面,可以通过 $("#phone_number").val() 获取到手机号,但是不知道怎么才能把这个值传递到 参数中,比如: params.merge(phone_number: phone_number)

class UsersController < ApplicationController
  # 发送验证码短信到用户手机,需要提供手机号码
  def send_sms
     phone_number = ?
  end
end

注册表单:

<%= form_for(:user, url: users_path) do |f| %>
  <%= f.text_field :phone_number, placeholder: "手机号", autofocus: true, id: "phone_number" %>
  <input type="text" placeholder="验证码"/>
  <%= link_to send_sms_users_path, method: :get, id:"send_sms",remote: true  do %>
    <span id="send_sms">获取验证码</span>
  <% end %>
  <%= f.password_field :password, placeholder: "密码" %>
  <%= f.submit "注册", class: "button" %>
<% end %>

如果?

点获取验证码,用 js 发 Ajax 请求去弄?

#3 楼 @qinfanpeng 也想过,在 send_sms.js.erb 文件里能取到 phone_number, 但是我该怎么传到 controler 的 send_sms action 里面 ? 平时,只是用 Ajax 来 render html partial.

暂不清楚你send_sms.js.erb这里是做啥用的,不过参考 jQuery 代码如下:

$.post 'send_sms_users_path',
       data: { phone_number: $("#phone_number").val() }

@qinfanpeng 这个 ajax post 请求中 data 参数,发送到后台 可以用 params[:phone_number] 进行获取了

@qinfanpeng @lb563 现在问题是怎么触发这个 POST 请求?

下面这个 获取验证码的链接,已经是 Ajax 请求了,路由是 send_sms_users_path, 对应的 view users/send_sms.js.erb

<%= link_to send_sms_users_path, method: :get, id:"send_sms",remote: true  do %>
   <span id="send_sms">获取验证码</span>
 <% end %>

在 send_sms.js.erb 里面 这样写

$.post("/users/send_sms", data: { phone_number: $("#phone_number").val()});

然后 在 Users#send_sms 的 action 里面 还是没有获取到 prams[:phone_number]

参数是这样的:

[1] pry(#<UsersController>)> params
=> {"controller"=>"users", "action"=>"send_sms"}
$.post("/users/send_sms", { phone_number: $("#phone_number").val()});

顺便提一下,你的这个 post 还没有写返回的处理

#7 楼 @springwq 你这里肯定就不能这样写了,把<%= link_to send_sms_users_path, method: :get, id:"send_sms",remote: true do %> <span id="send_sms">获取验证码</span><% end %> 换成按钮之类的,在 js 里区监听点击事件,然后触发 Ajax 请求。 另外send_sms.js.erb不是你这样用的,它一般用于返回一段简单的 script(太复杂的别这样搞,你会后悔的)给浏览器,浏览器会自动执行。建议还是系统地看书学习一下。

#8 楼 @xworm 请问 post 操作一定要写返回处理吗?

手机号是 11 位。可以监听每次输入操作,keyup 或 keydown。判断输入框里面的值是否达到十一位,达到了就获取这个值然后 post 传到后台。你获取还没真正注册的人的手机号做什么作用呢?可能,这个手机号就是乱写的

#10 楼 @pathbox 不是必须的,不写就相当于丢掉了返回状态,万一处理失败了呢

#11 楼 @pathbox keydown 和 keyup 是有区别的,最近用过一次 keypress,回调中获取的 input 的值会有一次点击的延迟,也就是要点第 12 个键时,才能取到 11 位的值

另外,万一人家最后一位输入错了怎么办

#11 楼 @pathbox 在注册时获取手机号码,然后发送短信验证码,目的就是确保这个手机号是用户自己的。

没必要非要异步提交吧,你搞两个表单,一个输入手机号获取验证码,另一个通过验证码注册,相互不影响,这样不行吗?要让体验一些的话,获取验证码的表单使用 Ajax 来 render html partial,

#16 楼 @helperhaps 目前设计图就是一个表单,要是两个表单就容易很多了,主要是本人对 Ajax 这些知识不太熟悉。

#17 楼 @springwq 话说设计图会看到有几个表单?你样式统一的话看起来就是一个,两个表单的话,基本不怎么用 ajax 的知识啊,

<%= form_for(:user, url: sms_path) do |f| %>
  <%= f.text_field :phone_number, placeholder: "手机号" %>
  <%= f.submit "获取验证码", class: "button" %>
<% end %>
<%= form_for(:user, url: users_path) do |f| %>
  <%= f.text_field :code, placeholder: "验证码" %>
  <%= f.password_field :password, placeholder: "密码" %>
  <%= f.submit "注册", class: "button" %>
<% end %>

#17 楼 @springwq @helperhaps 的方案也可以,不过有个问题是 form 不能嵌套,也就是说你的手机号字段要么放到最前面,要么放在最后面。

#18 楼 @helperhaps 但是,第二个 form 注册也是需要手机号的,怎么在第二个 form 获取手机号呢?

#20 楼 @springwq 如果手机号格式正确并且验证码发送成功,请求页面的时候往第二个 form 中写一个隐藏表单放手机号,然后提交到后台。

22 楼 已删除

@helperhaps @qinfanpeng 谢谢回复,最后参考了一位大神的代码,用 Ajax 解决了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号