The modal does not close properly when the controller calls format.js

I have a modal that appears as an editing form for an object. It opens and works fine with the controller, but when the action completes, the modal value does not close.

Everything works fine when the controller displays a new page, but when the form (which is in the modal) is set to remote: true, I get problems.

So the modal code looks something like this:

boilerplate bootstrap modal markup
id='edit_stream_4'
form_for(@stream, remote: true) do |f|
...etc...
f.submit

... and in the controller I have

def update
  respond_to do |format|
    if @stream.update
      format.js
    ...etc...

... and at /streams/update.js.erb

$('#edit_stream_4').modal("hide");
$('#workspace').html("<%= escape_javascript(render :partial => 'streams/show', stream: @stream) %>");

When I click the refresh button in the form in modal mode, the record is updated, and I can see a partial re-rendering in the background, but the modality remains.

, , js, , js, update.js.erb, , ?

- , javascript , ?

. , , , - , , , , [= , , jQuery, ) Rails ajax [= , div ajax] - , Rails- ajax .

, , , , , .

- todo. : . , .

, =

container.html.erb

<div id='viewport'>
  <div class='row'>
    <div class='col-md-4'>
      <%= render 'streams/index', streams: @streams %>
    </div>
    <div class='col-md-4'>
      <%= render 'layouts/object_views/index_settings', settings: @settings %>
    </div>
    <div class='col-md-4'>
      <%= render 'layouts/tips' %>
    </div>
  </div>
  <div class='row' id='workspace'>
    <%= render 'layouts/workspace/workspace' %>
  </div>
</div>

, "layouts/workspace/workspace" :

/layouts/workspace/_workspace.html.erb

<div id='workspace'>
    <%= image_tag("WIN1.png", class:'center-block img-responsive') %>
</div>

=

/streams/_index.html.erb

  <table class='table'>
    <thead>
      <tr>
        <th>Streams</th>
      </tr>
    </thead>
    <tbody>
      <% streams.each do |stream| %>
        <tr>
          <td><strong><%= link_to "#{stream.name}", stream, remote: true %></strong></td>
          <td><%= render 'layouts/components/object_modal', modal_params: {modal_action: :edit, modal_object_class: :stream, modal_object_id: stream.id} %></td>
        </tr>
      <% end %>
      <tr>
        <td>
          <%= render 'layouts/components/object_modal', modal_params: {modal_action: :new, modal_object_class: :stream} %>
        </td>
      </tr>
    </tbody>
  </table>

... , : @streams, , - <%= link_to "#{stream.name}", stream, remote: true %> : <%= render 'layouts/components/object_modal', modal_params: {modal_action: :edit, modal_object_class: :stream, modal_object_id: stream.id} %>.

:

//_object_modal.html.erb

<a href="#" data-toggle="modal" data-target=<%=modal_data_target(modal_params)%>>
  <span><%=modal_params[:modal_alt_title] || "#{modal_params[:modal_action]} #{modal_params[:modal_object_class]}"%></span>
</a>

<div class="modal fade bannerformmodal" tabindex="-1" role="dialog" aria-labelledby="bannerformmodal" aria-hidden="true" id=<%=modal_id(modal_params)%>>
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel"><%=modal_title(modal_params)%></h4>
      </div>
      <div class="modal-body">
        <%= render partial: "#{modal_params[:modal_object_class]}s/#{modal_params[:modal_action]}", locals: {id: modal_params[:modal_object_id], parent_id: modal_params[:parent_id]} %>
      </div>
    </div>
  </div>
</div>

- , .., : <%= render partial: "#{modal_params[:modal_object_class]}s/#{modal_params[:modal_action]}", locals: {id: modal_params[:modal_object_id], parent_id: modal_params[:parent_id]} %>.

, , , . - s . , , , stream, :

/_edit.html.erb

<%= bootstrap_form_for(stream = Stream.find_by_id(id), remote: true) do |f| %>
  <% if stream.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(stream.errors.count, "error") %> prohibited this stream from being saved:</h2>

      <ul>
      <% stream.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.text_field :name %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
<%= button_to 'Delete Stream', stream_path(stream), method: :delete, class: 'btn btn-danger', data: { confirm: "Are you sure?" }  %>

... :

  def edit
  end

  def update
    respond_to do |format|
      if @stream.update(stream_params)
        # format.html { redirect_to whatisnext_path, notice: 'Stream was successfully updated.' }
        # format.json { render :show, status: :ok, location: @stream }
        format.js
      else
        format.html { render :edit }
        format.json { render json: @stream.errors, status: :unprocessable_entity }
      end
    end
  end

... js -

/update.js.erb

$('#viewport').html("<%= escape_javascript(render 'whatisnext_signed_in_dynamic' %>");

... , . , - , , .

, , Rails ajax jQuery , , ?

+4
2

, , , . update.js.erb .

$(".modal-backdrop").remove();
+3

jQuery , .

​​ remote: true, Rails POST AJAX.

, ajax:success, , .

<script type="text/javascript">
    $(function(){
        $("#MODAL_FORM").bind('ajax:success', function(event, data, status, xhr){

            // Reset the Values
            $('#MODAL_FORM input#email').val('');

            // Let them know it was sent (Submit Button)
            $('#MODAL_FORM #SEND_BUTTON').attr('value', 'Form Sent!');

            // SET timeout to close the modal after above
            // Does no have to be a timeout, this just lets the user
            // See the text that it was sent, then closes it.
            setTimeout(function(){

                // Close the Window
                $('#MODAL_FORM a.CLOSE_MODAL_LINK').click();
                // OR
                $('#modal').modal('toggle');
                // OR
                $('#modal').modal('hide');

                // Reset the Submit Button Text
                $('#MODAL_FORM #SEND_BUTTON').text('value', 'Send');

            }, 500);
        })
    })
</script>
0

Source: https://habr.com/ru/post/1623131/


All Articles