Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap Modal not closing on data dismiss (Rails)

I have a rails application with an edit modal. The submit functionality works, but the close buttons do not do anything.

Edit.js.erb:

$("#modal-window").html("<%= escape_javascript(render 'users/edit') %>");

_edit.html.erb

<div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Modal Header</h4>
      </div>
      <div class="modal-body">
 <%= form_for @user,url: root_path,:method => :GET do |f|%> 
    <%= f.label :password %>
    <%= f.password_field :password, class: 'form-control' %>
     <%= f.submit "Save changes", class: "btn btn-primary" %>
     <%# submit_tag 'Cancel', :type => :reset, :class => "btn btn-danger", "data-dismiss" => "modal", "aria-hidden" => "true" %>
<% end %> 
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      </div>
    </div>

The lines from the view that opens and houses the modal

<%= link_to 'Edit Password', edit_path(user.id),  {:remote => true, 'data-toggle' =>  "modal", 'data-target' => '#modal-window'}  

......


<div id="modal-window" class="modal hide fade" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"></div>

I have the gems set up. //= require bootstrap/modal and //= require jqueryare in my application.js

Edit: Full application.js

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
//= require turbolinks
//= require_tree .
//= require bootstrap/modal
//= require jquery
like image 323
Btuman Avatar asked Jun 30 '17 23:06

Btuman


1 Answers

As the bootstrap-modal-rails gem would work with a Rails 4 application version, you could consider just using the Bootstrap modals to ge it work.

You can create a modal div, then add the button which will make a request to a certain method in the controller, which will respond with a js file, that then will render the partial which will fill the modal div.

In your index.html.erb you can set the link_to helper:

<%= link_to 'Edit Password', edit_path(user), remote: true, data: { toggle: 'modal', 'target': '#modal-window' } %>
...
<!-- Modal -->
<div class="modal fade " id="modal-window" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">

This specifies the path, in this case the one that responds to the edit method in the UsersController, add the remote: true option to start an asynchronous request to such method, and specifiy as data attributes the data-toggle and data-target.

Then, in the bottom if you prefer, you can create the #modal-window div, setted to work as a bootstrap modal, and which most match in id and data-target with the link_to helper to be "opened".

The route that's defined in the link_to expects an id, and use the alias option to create a short version:

get 'users/edit/:id', to: 'users#edit', as: 'edit'

Your controller just needs the method, edit, which will respond in Javascript, it just receives the id param that's sent:

def edit
  @user = User.find(params[:id])
end 

As edit responds in json format, then you need to create a file with the same name of your method plus the extension js and erb, this is edit.js.erb, and contains the code to render the _edit partial, and show the modal:

$("#modal-window").html("<%= j render 'users/edit' %>");
$('#modal-window').modal('show')

Finally the _edit partial will contain the content that will be added to the div modal created before, this can be easily tweaked, in the .modal-body div, so you can add the form:

<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">&times;</span></button>
      <h4 class="modal-title" id="myModalLabel">Modal title</h4>
    </div>

    <div class="modal-body">
      <%= form_for @user, url: edit_path do |f|%> 
        <%= f.label :password %>
        <%= f.password_field :password, class: 'form-control' %><br>
        <%= f.submit "Save changes", class: "btn btn-primary" %>
      <% end %> 
    </div>

    <div class="modal-footer">
      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      <button type="button" class="btn btn-primary">Save changes</button>
    </div>
  </div>
</div>

Note this depends on Bootstrap, so you need to add the gem to your Gemfile file, and configure both js and css application files:

# Gemfile
gem 'bootstrap-sass'

# application.js
//= require jquery
//= require bootstrap-sprockets

# application.scss
@import "bootstrap-sprockets";
@import "bootstrap";

In the application.js, as bootstrap depends on jQuery, this must be added before the bootstrap one, and for the css configuration, the file must be scss in order to make the proper import's.

like image 62
Sebastian Palma Avatar answered Nov 14 '22 17:11

Sebastian Palma