I'm trying to figure out to load a sign UP partial and a sign IN partial in the same bootstrap modal code in an effort to keep it dry.
How is that possible with my current situation?
<%= link_to "Sign in", :sign_in, id: "signin", "data-toggle" => "modal", "data-target" => "#sign-in" %>
modal partial
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Sign In</h4>
</div>
<div class="modal-body">
<%= render "sessions/new" %>
</div>
</div>
</div>
</div>
New session partial
<div class="row">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
I would render both partials and use javascript to show/hide the correct ones. Make sure in your signup partial you use the class signup in the outermost element and render that within render that right below your signin partial
<%= link_to "Sign in", :sign_in, id: "signin", "data-toggle" => "modal", "data-target" => "#sign-in" %>
<%= link_to "Sign in", :sign_in, id: "signup", "data-toggle" => "modal", "data-target" => "#sign-in" %>
<div class="row signin">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
Javascript
$(document).ready(function() {
$("#signin").click(function() {
$(".modal .signup").hide();
$(".modal .signin").show();
});
$("#signup").click(function() {
$(".modal .signin").hide();
$(".modal .signup").show();
});
});
Another way
Another way to do it would be to use ajax to load your partial into the body of the modal. You'd want a controller action for it that simply renders a partial and has layout false so you don't get excess layout elements passed with it.
If you don't have a lot, you don't need to make it a new controller, but I just did that here
Javascript
$(document).ready(function() {
$("#signup").click(function() {
setModal("modals/signup");
});
$("#signin").click(function() {
setModal("modals/signin");
});
});
// Doesn't have to be in a function, but it's better to keep it dry.
// Could also add more configuration (like the selector it uses)
function setModal(url) {
$.get(url, function(data) {
$("#myModal .modal-body").html(data);
});
}
Controller
class ModalsController < ApplicationController
def signin
render partial: "sessions/new", layout: false
end
def signup
render partial: "registrations/new", layout: false
end
end
Routes
get "modals/signin", to: "modals#signin"
get "modals/signup", to: "modals#signup"
Related
I have added bootstrap modal to edit user profile. It edits user profile but when there is an error in the form content it redirects to localhost:3000/user .how can I get errors in the modal itself? I used devise gem for user. what did I do wrong
_edit.html.erb
<div class="modal" id="EditProfileModal" data-keyboard="false" data-backdrop="static" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title">Edit user</h4>
</div>
<div class="modal-body">
<div class="container">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: {method: :put}) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :email %><br/>
<%= f.email_field :email, autofocus: true, :value => current_user.email %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="form-group">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br/>
<%= f.password_field :password, autocomplete: "off" %>
<% if #minimum_password_length %>
<br/>
<em><%= #minimum_password_length %> characters minimum</em>
<% end %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %><br/>
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="form-group">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br/>
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: {confirm: "Are you sure?"}, method: :delete %></p>
</div>
</div>
<div class="modal-footer">
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
header
<% if user_signed_in? %>
<header>
<%= link_to "sign out", destroy_user_session_path, method: :delete %>
<%= link_to "Edit profile", '#EditProfileModal', {'data-toggle' => "modal"} %>
<div style="text-align: center">Signed in as <b><%= current_user.email %></b></div>
</header>
<%= render "devise/registrations/edit"%>
<% end %>
Form submission always forces a page reload. You can bypass this by submitting your form as ajax request. In Rails you can do this by passing option remote: true to your form_for call. Keep in mind, that to properly handle response from server you gonna need to handle javascript event:
$('[selector]').on('ajax:success', function(e, data, status, xhr) {
// do something
})
You need to use ajax for form submission with data-remote=true.
than you need to override the update action of registrations controller,
In the update action, you can check whether there is error or not with
if resource.update_attributes(your_params)
redirect_to :back # else any where you want to redirect
else
respond_to :js
end
and in registrations/update.js.erb you can add the div for show errors.
$(".modal-body").prepend("<div><%= resource.errors %></div>")
I Have an application in RoR and I need to make a login modal.
I´m using the gem devise.
sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
respond_to :js
end
In the devise folder of the views, I have the sessions folder with 2 files: _new.html.erb and new.js.erb
_new.html.erb
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button class="close" data-dismiss="modal">x</button>
<h2 class="dark">Log in</h2>
</div>
<div class="modal-body">
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end -%>
<div class="actions">
<%= f.submit "Log in", class: "btn btn-md btn-black-line" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
</div>
</div>
new.js.erb
$('#modaldevise').html('<%= j render('new') %>');
$('#modaldevise').modal();
In my application.html.erb I use this code to use modal:
<div id="modaldevise" class="modal fade"></div>
Finally I have a side menu that have the login link:
<%= link_to 'Login', new_user_session_path, 'data-toggle' => "modal" , 'data-target' => "#modaldevise" %>
When I press the Login link, the background becomes darker and the modal is opened, but the information from the partial _new.html.erb is not showed.
What is wrong here?
You can avoid using new.js.erb and do something like this:
application.html.erb
<div id="modaldevise" class="modal fade">
<%= render 'your_path/new' %>
</div>
side menu
<%= link_to 'Sign in', '#', "data-toggle" => "modal", "data-target"=>"#modaldevise" %>
I'm maintaining an older Rails 3.2.22 app and I'm trying to add a modal to pop up with a simple form to add a note.
Here is my view (cut down for readability)
<% #assigned.each do |call| %>
<%= link_to "Notes", '#ajax-modal', data: { toggle: "modal", target: "#note-modal" }, class: 'btn btn-small btn-inverse' %>
<%= render 'layouts/note_modal', :call => call %>
<% end %>
Here is my modal app/views/layouts/_note_modal.html.erb
<div id="note-modal" class="modal hide fade" tabindex="-1">
<div class='modal-header'>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title"><%= call.incident_number %> Notes</h3>
</div>
<div class='modal-body'>
<div class="modal-body-content">
<%= form_for(#note, url: call_note_calls_path, html: {class: "form-inline"}) do |f| %>
<%= f.text_field :message, :maxlength => 255 %>
<%= f.hidden_field :call_id, value: call.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.button "Add Note", class: 'btn btn-info btn-small', data: {disable_with: "<i class='icon-spinner'></i>Posting..."} %>
<% end %></div>
<div class="ajax-loader">
</div>
</div>
<div class='modal-footer'>
<button type="button" data-dismiss="modal" class="btn">Close</button>
</div>
</div>
When I load the page and there are several calls I click on the notes link, the partial renders in a modal and I can submit a note. The problem is if I have 10 calls on the screen no matter which notes link I click on it adds a note to the first call on the screen.
Am I passing locals incorrectly? I know this code is inside of the block so it should pull the call object and pass it as a local to the partial in the modal but it's not.
Any help is greatly appreciated.
I think the issue is that you render the modal each time for a note but they all have the same id. So you are always opening the first modal. Actually IMHO you just need to render the modal once and pass the note_id via an data attribute on the link which triggers the modal. So basically configure the modal via the caller.
I was able to figure this out on my own and still render the partial within the loop by calling an index as part of the target ID for the modal. Working code below.
<% #assigned.each_with_index do |call, index| %>
<%= link_to "Notes", '#note-modal', data: {toggle: "modal", target: "#note-modal#{index}" }, class: 'btn btn-small btn-inverse' %>
<%= render 'layouts/note_modal', call: call, index: index %>
<% end %>
<div id="note-modal<%= index %>" class="modal hide fade" tabindex="-1">
<div class='modal-header'>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title"><%= call.incident_number %> Notes</h3>
</div>
<div class='modal-body'>
<div class="modal-body-content">
<%= form_for(#note, url: call_note_calls_path, html: {class: "form-inline"}) do |f| %>
<%= f.text_field :message, :maxlength => 255 %>
<%= f.hidden_field :call_id, value: call.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.button "Add Note", class: 'btn btn-info btn-small', data: {disable_with: "<i class='icon-spinner'></i>Posting..."} %>
<% end %></div>
<% call.notes.each do |n| %>
<li><%= n.message %> added by <%= n.user.username %></li>
<% end %>
<div class="ajax-loader">
</div>
</div>
<div class='modal-footer'>
<button type="button" data-dismiss="modal" class="btn">Close</button>
</div>
</div>
I am making an ecommerce website page.It consists of two parts.A sidebar having a list of all products and a right column where the details of the product is shown once the product is selected from the list.
I am making ajax calls to load the various partials of the application. The sidebar having all the products is index,the one on right having the details of products is show which shows the details of the product selected.
Now when I edit the product(through a modal) how do I automatically reload the respective partials so that the new changes are reflecte.For me to see the changes I have to refresh the pages currently,how do i ensure the partials are automatically loaded once I click submit on the edit modal.
My index.html.erb looks like
<div class="container">
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-4 sidebar-offcanvas" id="sidebar" role="navigation">
<div class="well sidebar-nav">
<ul class="nav">
<div class="jumbotron well">
<h3>Product Listing Application</h3>
</div>
<%= link_to "New Product", new_product_path, remote: true, class: "btn btn-primary" %>
<div class="list-group">
<%= render "index" %>
</div>
</ul>
</div><!--/.well -->
</div><!--/span-->
<div class="col-xs-10 col-sm-8">
<div id="page-content-wrapper">
<div class="page-content">
<div class="col-md-12 product-info" id="product-details">
</div>
</div>
</div>
<div id="product-modal" class="modal fade"></div>
</div>
</div><!--/row-->
</div>
My _index.html.erb is
<% #products.each do |product| %>
<%= link_to product_path(product), remote: true, class: "list-group-item" do %>
<h4 class="list-group-item-heading"><%= product.name %></h4>
<p class="list-group-item-text"><%= number_to_currency product.price %></p>
<% end %>
<% end %>
My _edit.html.erb is
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3><%= "Editing #{#product.name}" %></h3>
</div>
<%= render "form" %>
</div>
</div>
My _form.html.erb is
<%= form_for #product, remote: true, html: { class: "form-horizontal", style: "display:inline;" } do |f| %>
<div class="modal-body">
<ul class="errors"></ul>
<div class="control-group">
<%= f.label :name, class:"control-label" %>
<div class="controls">
<%= f.text_field :name %>
</div>
</div>
<div class="control-group">
<%= f.label :price, class: "control-label" %>
<div class="controls">
<%= f.text_field :price %>
</div>
</div>
</div>
<div class="modal-footer">
<%= f.submit class: "btn btn-primary" %>
<%= link_to "Cancel", "#", class: "btn", data: {dismiss: "modal"} %>
</div>
<% end %>
You can use
location.reload();
on your js.erb for refresh your partial, or for your instance vaiable
you can directly use
#post = #post.reload # in palce of #post you can your instance variable
create a js file same name as your page
add below code in it
edit.js.erb
$("<%= escape_javascript render(:partial => 'ur_partial_page_name') %>").dialog();
$('#new_comment_link').hide();`
in your edit page form where u r calling modal dialog
<%= link_to "edit", edit_product_path (#product, :format => :js), :remote => true %>
In your product controller
def edit
#source = Product.find(params[:id])
respond_to do |format|
format.html # edit.html.erb
format.xml { render :xml => #product }
format.js
end
end
and in your partial form
<%= form_for (#product, :remote => true) do |f| %>
I'm trying to alter my devise registration view file to work with bootstrap modals.
I have followed the bootstrap instructions and slotted the form into the modal and linked it to the navbar menu. Now, when i click on 'Register' in my navbar. Nothing happens. The form doesn't go anywhere. I had this working when it was just a standard page view. Can anyone help? Thank you.
I am trying to follow this answer but am getting confused: Twitter Bootstrap Modal not popping up for user login
I have:
views/devise/shared/registration_items:
<% if user_signed_in? %>
<li>
<%= link_to('Edit registration', edit_user_registration_path) %>
</li>
<% else %>
<li>
<%= link_to 'Register', new_user_registration_path, :remote => true, 'data-toggle' => "modal", 'data-target' => "#myModal", :method: 'get' %>
</li>
<% end %>
views/devise/registrations/new
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Sign up</h4>
</div>
<div class="modal-body">
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :first_name, required: true, autofocus: true %>
<%= f.input :last_name, required: true, autofocus: true %>
<%= f.input :email, required: true, autofocus: true %>
<%= f.input :password, required: true %>
<%= f.input :password_confirmation, required: true %>
</div>
</div>
<div class="modal-footer">
<div class="form-actions">
<%= f.button :submit, "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
</div>
</div>
</div>
respond_to do |format|
format.js
end
I get a syntax error (syntax error, unexpected ':', expecting =>) on this line:
<%= render 'devise/shared/registration_items' %>
Please can anyone help. Thank you.
There is a syntax error. Change to :method => 'get' or method: 'get' in the line below
'data-toggle' => "modal", 'data-target' => "#myModal", :method: 'get'