Rails合并表单字段

时间:2014-07-04 12:45:28

标签: javascript jquery ruby-on-rails-3 forms rails-activerecord

我有一个Rails 3.2.18应用程序,我在其中对模型进行简单的创建/更新操作。

有一个名为短信的字段,我使用ActionMailer以2812222222@vtext.com的形式向个人电话发送消息。目前我手动输入这个很好,但我希望其他人能够输入一个电话号码,选择一个运营商并将这两个项目合并为sms字段中的正确格式2812222222 @ vtext。 COM。使用它比用户能够了解完整的短信到电子邮件地址更加用户友好。

我认为我可以通过JS / JQuery完成大部分工作,但我不确定如何开始。

我希望他们能够以281-555-4444格式输入电话号码并让运营商选择Tmobile,Verizon等下拉菜单并替换@ tmomail.net,@ vtext.com等,剥离(正则表达式)电话号码并将其与运营商(@ vtext.com)合并到短信字段中。

如果有人能直接指出我,我们将不胜感激。

更新

我想我可以使用辅助方法来定义载波:

def phone_carriers
{
  "All Tell" => "@message.alltel.com",
  "AT&T" => "@txt.att.net",
  "Boost" => "@myboostmobile.com",
  "Cellular South" => "@csouth1.com",
  "Centennial Wireless" => "@cwemail.com",
  "Cincinnati Bell" => "@gocbw.com",
  "Cricket Wireless" => "@sms.mycricket.com",
  "Metro PCS" => "@mymetropcs.com",
  "Powertel" => "@ptel.net",
  "Qwest" => "@qwestmp.com",
  "Rogers" => "@pcs.rogers.com",
  "Sprint" => "@messaging.sprintpcs.com",
  "Suncom" => "@tms.suncom.com",
  "T-Mobile" => "@tmomail.net",
  "Telus" => "@msg.telus.com",
  "U.S. Cellular" => "@email.uscc.net",
  "Verizon" => "@vtext.com",
  "Virgin Mobile USA" => "@vmobl.com"
}

将attr_accessor:carrier添加到Person模型

然后在表单中执行以下操作:

<%= f.input :phone, placeholder: "555-555-5555", required: true, input_html: {required: true} %>

<%= f.select :carrier, phone_carriers.map{ |k, v| [k, v] }, {include_blank: true}, {placeholder: "Select your phone carrier", class: "select2"} %>

但我仍然无法确定如何将电话号码剥离至5555555555并将:phone字段与:carrier对象自动合并到:sms字段(最好是客户端)

3 个答案:

答案 0 :(得分:1)

在做了大量的研究和破坏之后,我想出了以下内容来完成这项工作。模型和表单仅显示我所做的更改,而不是完整的表单或模型。

表格

<%= f.label 'Cell_Phone'%>
<%= f.text_field :phone, placeholder: "xxx-xxx-xxxx", required: true %>
<%= f.label :carrier, "SMS Notifications", class: "control-label" %>
<%= f.select :carrier, phone_carriers.map{ |k, v| [k, v] }, {include_blank: true}, {placeholder: "Select your phone carrier", class: "select2"} %>
<%= f.hidden_field :sms %>

模型

attr_accessible :carrier
attr_accessor :carrier

的CoffeeScript

$ ->
  $("#person_carrier").on "change", update_sms_address
  $("#person_phone").on "keyup", update_sms_address
  update_sms_address

update_sms_address = ->
    digits  = $("#person_phone").val().match(/\d+/g)
    phone   = digits.join("") if digits
    carrier = $("#person_carrier").val()

    if phone? && phone.length == 10 && carrier
      sms = phone + carrier
      $("#person_sms").val(sms)
      $("#person-sms-number").html(sms)
    else if !carrier
      $("#person_sms").val("")
      $("#person-sms-number").html("Choose a carrier to receive SMS notifications")
    else
      $("#person_sms").val("")
      $("#person-sms-number").html("Invalid phone number")

当输入格式为281-444-4444的电话号码时,这似乎有效,因为它将数字向下删除并将其与载波数组中的值连接,并相应地设置隐藏的:sms字段。

我现在唯一的问题是因为我正在为运营商使用虚拟属性,如果我再次编辑此人,则不保留运营商选择并将其留空。如果我提交表单而不更改任何信息,它将保留:sms字段,但它可能会令人困惑,因为:carrier不是数据库记住的实际字段,而是虚拟属性。

还有更好的方法吗?

答案 1 :(得分:0)

如果您使用标准的javascript字符串库,则不会像

那样
function prepare(str){
  str2 = str.replace("(","").replace(")","").replace("-","")
  carrier = getCarrier //assuming this implemented by you somewhere 
  return (st2.concat(carrier))
}

答案 2 :(得分:0)

我首先要创建一个载体表:

rails generate model Carrier name:string email_domain:string

通过在迁移中添加以下内容在Person模型中引用它:

change_table :people do |t|
  t.references :carrier
end
add_index :people, :carrier_id

以下是您的人物模型:

belongs_to :carrier
validates_presence_of :carrier

def sms
  carrier ? "#{phone}@#{carrier.email_domain}"
end
def phone_with_dashes
  "#{phone[0..2]}-#{phone[3..5]}-#{phone[6..9]}"
end
def phone_with_dashes=(_phone_with_dashes)
  self.phone = _phone_with_dashes.gsub(/-/ ,'')
end

现在,您的观点(我会将格式保留给您):

Phone: <%= f.phone_field :phone_with_dashes %>
Carrier: <%= f.collection_select :carrier_id, Carrier.all, :id, :name %>
<div id='person-sms-number'>
  <%= f.object.sms %>
</div>

最后,Coffeescript:这里唯一需要改变的是你不再需要'#person_sms'输入,因为你不再直接持久化这个值 - 你是从其他领域动态生成的。