How to display flash error without refreshing page

2019-08-09 07:58发布

问题:

I have a submit form that is shown in a lightbox. I validate the form pretty heavily but there are circumstances where a playlist is already submitted, in which case I can't tell before a form is submitted.

Currently I have :disable_with => 'Submitting...'

It would be completely awesome if the error was sent back to the form, and the submit button would re-enable.

Would this be possible without too much complication?

I also have a second related question... Because my form is in a lightbox, it's code is actually ON the index page (my app is just one page pretty much). This means that there really is no 'new' action, but rather a @playlist = Playlist.new(:title => ...) in my index action (along with a @playlists = Playlist.all, etc). In my routes I did this: resources :playlists, :only => [:create]

Does this sound about right the way I did it?

EDIT: HEre is some code, although it's basically about as simple as you can imagine it.

The following kind of works... it creates the playlist if its valid, otherwise it does nothing. Both times create.js.erb is called.. i just dont now how to make this work to completion now. on success i need to close the window, on failure i need to load the errors into the form thats already on the screen. Im not sure where that goes though :/

  before_filter :load_genres, :only =>[:index, :user]
  before_filter :new_playlist, :only => [:index, :new]

  def index
    @playlists = Playlist.order('created_at DESC').page(params[:page]).per(30)
  end

  def create
    @playlist = Playlist.new(params[:playlist])
    respond_to do |format|
      if @playlist.save
        format.html { redirect_to root_path, :notice => "Playlist submitted" }
        format.js   {}
      else
        format.html { render :action => :new, :layout => !request.xhr? }
        format.js {}
      end
    end
  end

  def new

  end

  def load_genres
    @genres = Genre.order(:name)
  end

  def new_playlist
    @playlist = Playlist.new(:title => params[:title], :url => params[:url], :description => params[:description])
  end

Heres the first like of my form (located in index.html.erb):

<%= form_for @playlist, :remote => true do |f| %>

I currently have no html or code in create.html.erb

回答1:

Without seeing your code I can only make broad suggestions.

One would be to set up a js.erb response to the controller action-- or you could do a js script tag in an if clause inside your HTML. Either way you would use jQuery to update the element.

Inside the js/html erb file:

jQuery('#flash_area).html(<flash message>);

The the flash area in the view would need an id of flash_area (or whatever you want to name it).



回答2:

Here is my solution to this Issue.... I put these in all my js.erb files

$('#flash').html("<%= escape_javascript raw(flash_display) %>");

With this Helper

def flash_display
  response = ""
  flash.each do |name, msg|
    response = response + content_tag(:div, msg, :id => "flash_#{name}")
  end
  flash.discard
  response
end

this works well with the flash div already set up in layout

<div id="flash">
  <% flash.each do |name, msg| %>
    <%= content_tag :div, msg, :id => "flash_#{name}" %>
  <% end %>
</div>

Hope this Helps