Skip to content

Instantly share code, notes, and snippets.

@johnmeehan
Last active February 14, 2023 19:20
Show Gist options
  • Save johnmeehan/571d9462187c553bd986ac8470d7cc26 to your computer and use it in GitHub Desktop.
Save johnmeehan/571d9462187c553bd986ac8470d7cc26 to your computer and use it in GitHub Desktop.
Rails + Reform + Bootstrap + Ajax Modal Form
# simple_form Reform Form for creating a basic postal address
# errors will be shown on the violating fields
= simple_form_for(@form, remote: true) do |f|
.modal-dialog
.modal-content
.modal-header
%button.close{"aria-hidden" => "true", "data-dismiss" => "modal", :type => "button"} ×
%h3.modal-title
New Address for
= @customer.name
.modal-body
= f.hidden_field :customer_id
= f.input :type, collection: [['Shipping','ShippingAddress'], ['Billing', 'BillingAddress']], include_blank: false, input_html: { class: 'form-control'}
= f.input :line_1, label: 'Line 1', input_html: { class: 'form-control' }
= f.input :line_2, label: 'Line 2', input_html: { class: 'form-control' }
= f.input :line_3, label: 'Line 3', input_html: { class: 'form-control' }
= f.input :line_4, label: 'Line 4', input_html: { class: 'form-control' }
= f.input :line_5, label: 'Line 5', input_html: { class: 'form-control' }
= f.input :line_6, label: 'Line 6', input_html: { class: 'form-control' }
= f.input :country, collection: Address.countries, include_blank: false, input_html: { class: 'form-control' }
.modal-footer
= f.button :submit, class: 'btn btn-lg btn-success'
%button.btn.btn-lg.btn-danger{"aria-hidden" => "true", "data-dismiss" => "modal"} Close
# Address Model
# nice and clean now that the form handles all the validations
class Address < ActiveRecord::Base
belongs_to :customer
# Countries list for addresses. (there are gems for this...)
def self.countries
['Ireland']
end
end
# Reform form object.
# - no more messing with strong params.
# - the form handles all the validations.
class AddressForm < Reform::Form
include Reform::Form::ActiveModel::FormBuilderMethods # This is removed in later Reform 2.2
include Reform::Form::ActiveModel::ModelReflections # this is removed in 2.2
property :customer_id, type: Types::Form::Int
property :type, default: 'ShippingAddress'
property :primary, type: Types::Form::Bool, default: false
property :delivery_foc, type: Types::Form::Bool, default: false
property :line_1
property :line_2
property :line_3
property :line_4
property :line_5
property :line_6
property :country, default: 'Ireland'
validates :type,
:line_1,
:line_2,
:country,
:customer_id,
presence: true
end
class AddressesController < ApplicationController
def new
@customer = Customer.find params[:customer_id]
@address = @customer.shipping_addresses.build
@form = AddressForm.new(@address)
respond_to do |format|
format.js # renders new.js.erb which will insert the modal form into the page
end
end
def create
@customer = Customer.find params[:address][:customer_id]
@form = AddressForm.new(Address.new)
respond_to do |format|
if @form.validate(params[:address]) && @form.save
format.js # renders the create.js.erb which will remove the modal
else
format.js { render :new }
end
end
end
end
// Used to hide the modal if there is no errors.
// and update the address dropdown with the newly created one.
<% if @form.errors.blank? %>
// Hide the modal
$('#modal-window').modal('hide');
// add the newly created address to the list of options
$('#sales_order_shipping_address_id').append("<option value='>" + "<%= @form.id %>" + "'>" + "<%= @form.line_1 %>" + "</option>");
<% else %>
// dont hide let it show the errors in the UI
<% end %>
// renders the form inside the div
$("#modal-window").html("<%= escape_javascript(render 'addresses/modal') %>");
-# Some page where the modal appears over.
-# The target for the JS to put the modal content
#modal-window.modal.fade{ 'role' => "dialog" }
-# Link to trigger modal
=link_to 'New Address', new_customer_address_path(current_user.active_reseller_id), remote: true, data: { toggle: 'modal', target: '#modal-window'}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment