【发布时间】:2019-01-24 01:35:25
【问题描述】:
所以我有一个表单,我试图让用户将文本从帐单复制到送货地址。不幸的是,目前它会自动将帐单地址保存在送货地址中。
我的表单如下所示(尽管因大量字段而被截断):
=form_for @customer, url: create_customer_path, html: {class: 'new-customer} do |f|
.row
.col-md-4
= f.label :first_name
.col-md-8
= f.text_field :first_name, class: 'form-control', required:true
.row
.col-md-4
= f.label :billing_address1
.col-md-8
= f.text_field :billing_address1, class: 'form-control', required:true
.row
.col-md-12
= f.check_box :shipping_is_billing
= f.label :shipping_is_billing, 'Same as billing address'
.row
.col-md-4
= f.label :shipping_address1
.col-md-8
= f.text_field :shipping_address1
客户控制器
class CustomersController < ApplicationController
def new
@customer = CustomerForm.new
end
def create
@customer = CustomerForm.new(customer_params)
if @customer.save
redirect_to customer_success_path
else
render 'new'
end
end
private
def customer_params
params.require(:customer_form).permit!.tap do |p|
p[:captcha_response] = params['g-recaptcha-response']
end
end
end
CustomerForm(针对大量字段截断)
class CustomerForm
include ActiveModel::Model
CUSTOMER_ATTRS = %w[
first_name
].freeze
ADDRESS_ATTRS = %w[
address1 address2 city state zip
].freeze
attr_accessor(*CUSTOMER_ATTRS)
attr_accessor(*ADDRESS_ATTRS.map { |attr| 'billing_' + attr })
attr_accessor(*ADDRESS_ATTRS.map { |attr| 'shipping_' + attr })
attr_accessor :confirm_email, :captcha_response, :shipping_is_billing
validates :first_name, presence: true
validates :billing_address1, presence: true
validates :shipping_address1, presence: true, unless: :shipping_is_billing
def save
return false unless valid?
persist!
end
private
def captcha_passes
captcha = Captcha.new
return if captcha.valid?(captcha_response)
errors.add(:captcha_response, 'is invalid')
end
def persist!
customer = Customer.new(attrs_for_customer)
customer.billing_address = CustomerAddress.new(attrs_for_address('billing_'))
customer.shipping_address = CustomerAddress.new(
attrs_for_address(shipping_is_billing ? 'billing_' : 'shipping_')
)
customer.save!
customer
end
def attrs_for_customer
Hash[
CUSTOMER_ATTRS.map { |attr| [attr, send(attr)] }
]
end
def attrs_for_address(prefix)
Hash[
ADDRESS_ATTRS.map { |attr| [attr, send(prefix + attr.to_s)] }
]
end
end
JS
app.newCustomer = () => {
function init() {
let check = document.querySelector('#customer_form_shipping_is_billing')
check.addEventListener('change', toggledUseBilling)
}
let toggledUseBilling = event => {
shippingFields().forEach(field => {
if(event.target.checked) {
field.value = null;
field.removeAttribute('required');
field.setAttribute('disabled', true);
} else {
field.setAttribute('required', true);
field.removeAttribute('disabled');
}
})
}
let shippingFields = () => {
let selectors = [
'#customer_form_shipping_address1',
'#customer_form_shipping_address2',
'#customer_form_shipping_city',
'#customer_form_shipping_state',
'#customer_form_shipping_zip',
]
return document.querySelectorAll(selectors.join(', '));
}
return init();
}
坚持下!方法 我在复选框上使用三元运算符来确定要计费/发货的地址的属性。但它看起来并没有真正起作用。如何从表单中获取被标记的复选框?
以下是我尝试过的事情:
- 已将 = f.check_box :shipping_is_billing 转换为 =check_box_tag :shipping_is_billing。然后我必须更新我的 JS 以确保我抓住了正确的复选框。这会存储运输数据,但检查时不会复制业务数据。
- 已尝试将 attrs_for_address(shipping_is_billing ? 'billing_' : 'shipping_') 切换到 attrs_for_address(shipping_is_billing ? 'shipping_' : 'billing_')。如果我使用 check_box,这会将数据填充到运输,但复选框变得无效。
- 在 check_box_tag 周围放置一个 form_tag 但这实际上去掉了复选框
- 将 check_box 更改为 check_box_tag,更新了我的 JS 以在复选框上查找正确的 ID。如果输入,可以保存送货地址,但如果选中该框,则它不应用帐单地址,并且我收到提示送货地址不能为空
【问题讨论】:
标签: ruby-on-rails