最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Rails modal form - updating popup with content from html.erb file after unsuccessful form submission - Stack Overfl

programmeradmin0浏览0评论

I have a Rails view (recipes/new) which allows users to enter a new recipe. In that view, the user can select items from another model, ingredients. I wanted a way for the users to add a new ingredient without leaving the recipe form.

I created a link for new ingredients which loads a JQuery modal box. Here is the code in my recipes.js file which drives the modal:

assets/javascripts/recipes.js

this code from @coreyward's answer - see Jquery modal windows and edit object for details - thanks, corey!

$(function(){
    var $modal = $('#modal'),
        $modal_close = $modal.find('.close'),
        $modal_container = $('#modal-container');

    $('a[data-remote]').live('ajax:beforeSend', function(e, xhr, settings){
        xhr.setRequestHeader('accept', '*/*;q=0.5, text/html, ' + settings.accepts.html);       
    });

    $('a[data-remote]').live('ajax:success', function(xhr, data, status){
        $modal
            .html(data)
            .prepend($modal_close)
            .css('top', $(window).scrollTop() + 40)
            .show();
        $modal_container.show();
    });

    $('.close', '#modal').live('click', function(){
        $modal_container.hide();
        $modal.hide();
        return false;
    });
});

My link in the recipes/new.html.erb:

<%= link_to 'New ingredient', new_ingredient_path, :remote => true %>

This works great, in the sense that it loads the modal form with the new ingredient form in there. I can fill out the form, and if the ingredient is saved, I call another function from my controller to close the modal:

ingredients_controller.rb

def create
  if @ingredient.save
    respond_to do |format|
      format.js { render :js => "close_modal();" }
    end
  end
end

My problem is when the form is not filled out correctly. The user clicks and gets no feedback that there are any errors/missing fields, etc... I would like to reload the ingredient form in the popup box, which will render a shared errors partial:

ingredients/new.html.erb

<%= form_for @ingredient, :remote => true do |i| %>
    <%= render 'shared/ingredient_error_messages' %>

    <div class="field">
        <%= i.label :name %>
        <%= i.text_field :name %>
    </div>
    <div class="field">
        <%= i.label :srm %>
        <%= i.text_field :srm %>
    </div>
    <div class="field">
        <%= i.label :price %>
        <%= i.text_field :price %>
    </div>
    <div class="actions">
        <%= i.submit "Save ingredient" %>
    </div>
<% end %>

shared/_ingredient_error_messages.html.erb

<% if @ingredient.errors.any? %>
    <div id="error_explanation">
        <h2><%= pluralize(@ingredient.errors.count, "error") %>
            prohibited this recipe from being saved:</h2>
        <p>There were problems with the following fields:</p>
        <ul>
            <% @ingredient.errors.full_messages.each do |msg| %>

                <li><%= msg %></li>
            <% end %>
        </ul>
    </div>
<% end %>

What's the best way to get this to work? I can easily create another JS function and call it from the controller if the save is not successful, but I can't find a way to pass in anything but straight text/html. Is there a way, in the controller, I can parse and output to a function the contents of my 'new' view? Is there a better/cleaner way to do this?

I have a Rails view (recipes/new) which allows users to enter a new recipe. In that view, the user can select items from another model, ingredients. I wanted a way for the users to add a new ingredient without leaving the recipe form.

I created a link for new ingredients which loads a JQuery modal box. Here is the code in my recipes.js file which drives the modal:

assets/javascripts/recipes.js

this code from @coreyward's answer - see Jquery modal windows and edit object for details - thanks, corey!

$(function(){
    var $modal = $('#modal'),
        $modal_close = $modal.find('.close'),
        $modal_container = $('#modal-container');

    $('a[data-remote]').live('ajax:beforeSend', function(e, xhr, settings){
        xhr.setRequestHeader('accept', '*/*;q=0.5, text/html, ' + settings.accepts.html);       
    });

    $('a[data-remote]').live('ajax:success', function(xhr, data, status){
        $modal
            .html(data)
            .prepend($modal_close)
            .css('top', $(window).scrollTop() + 40)
            .show();
        $modal_container.show();
    });

    $('.close', '#modal').live('click', function(){
        $modal_container.hide();
        $modal.hide();
        return false;
    });
});

My link in the recipes/new.html.erb:

<%= link_to 'New ingredient', new_ingredient_path, :remote => true %>

This works great, in the sense that it loads the modal form with the new ingredient form in there. I can fill out the form, and if the ingredient is saved, I call another function from my controller to close the modal:

ingredients_controller.rb

def create
  if @ingredient.save
    respond_to do |format|
      format.js { render :js => "close_modal();" }
    end
  end
end

My problem is when the form is not filled out correctly. The user clicks and gets no feedback that there are any errors/missing fields, etc... I would like to reload the ingredient form in the popup box, which will render a shared errors partial:

ingredients/new.html.erb

<%= form_for @ingredient, :remote => true do |i| %>
    <%= render 'shared/ingredient_error_messages' %>

    <div class="field">
        <%= i.label :name %>
        <%= i.text_field :name %>
    </div>
    <div class="field">
        <%= i.label :srm %>
        <%= i.text_field :srm %>
    </div>
    <div class="field">
        <%= i.label :price %>
        <%= i.text_field :price %>
    </div>
    <div class="actions">
        <%= i.submit "Save ingredient" %>
    </div>
<% end %>

shared/_ingredient_error_messages.html.erb

<% if @ingredient.errors.any? %>
    <div id="error_explanation">
        <h2><%= pluralize(@ingredient.errors.count, "error") %>
            prohibited this recipe from being saved:</h2>
        <p>There were problems with the following fields:</p>
        <ul>
            <% @ingredient.errors.full_messages.each do |msg| %>

                <li><%= msg %></li>
            <% end %>
        </ul>
    </div>
<% end %>

What's the best way to get this to work? I can easily create another JS function and call it from the controller if the save is not successful, but I can't find a way to pass in anything but straight text/html. Is there a way, in the controller, I can parse and output to a function the contents of my 'new' view? Is there a better/cleaner way to do this?

Share Improve this question edited May 23, 2017 at 11:50 CommunityBot 11 silver badge asked Feb 28, 2012 at 22:16 JimJim 2,3101 gold badge19 silver badges44 bronze badges 5
  • 1 Sounds like you are trying to do what this guy was trying to do: stackoverflow./questions/6374664/… – PhillipKregg Commented Feb 28, 2012 at 22:27
  • @PhillipKregg - man, I searched around for similar questions and found a few which didn't quite fit. Somehow I missed the one you linked to. I should be able to figure this out based on that example code. What's SO best practice now, delete this question or what? – Jim Commented Feb 28, 2012 at 22:36
  • Well, you can delete it if you want. Or you can leave it up and it will provide another resource for folks who are looking for the same info. I can put the link as an answer at the bottom and you can mark it as the solution. It's a good resource, and it will give me the free fake points for not doing anything. A win-win. :) – PhillipKregg Commented Feb 28, 2012 at 22:41
  • @PhillipKregg - just got everything up and running with my project. This is my first time integrating AJAX/JS stuff, and I was not aware of the power of the js.erb files. Thanks for the enlightenment! :) – Jim Commented Feb 28, 2012 at 22:50
  • No problem - best of luck with your project. – PhillipKregg Commented Feb 28, 2012 at 23:21
Add a ment  | 

1 Answer 1

Reset to default 3

Here is a link to a github Rails JQuery-Modal form that was designed by Ramblex to do this very thing:

https://github./ramblex/modal-form

Here is the respective SO question that it solved (so you can upvote his answer): Rails and modal jquery dialog form

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论