简体   繁体   中英

using respond_to do |format| format.js to show a message inside of a modal after photo is favorited inside a modal?

The web user has a modal open with a picture showing, they click on:

photos/show.html.erb

<%= link_to favorite_photo_path("#{photo.id}"), method: :put do %>
  <span class="glyphicon glyphicon-heart"></span>
<% end %>

The end goal is to keep the user inside of the modal, with a message shown inside of the modal, "You have successfully favorited this photo"... I am testing this out in the middle of the controller where I call respond_to do... However, when the glyphicon is clicked the model is updated however browser ends up stuck on www.examples.com/photos/1/favorite

Routes

resources :photos do
  match :favorite, on: :member, via: [:put, :delete]
end

PhotosController

def favorite
  @photo = Photo.find params[:id]
    if request.put?
     response = current_user.favorite_photos.new(photo: @photo)
     if !response.valid?  
      redirect_to :back, notice: response.errors.full_messages
     else
      response.save
        respond_to do |format| 
          format.js
        end
     end
    else request.delete?
      current_user.favorites.delete(@photo)
      redirect_to :back, notice: 'You successfully unfavorited this photo' 
    end 
  end

photos/favorite.js.erb

 $('.modal-dialog.photo>.message').html('You have successfully favorited this photo');

When html { redirect_to :back } is used, it closes the modal.

To utilize the JavaScript response, you will need to add the remote: true option to your link.

http://guides.rubyonrails.org/working_with_javascript_in_rails.html

If you want to handle this via AJAX, don't use redirect back.

Also use flash.now for AJAX.

Instead handle both scenarios in you're JavaScript file.

# app/views/photos/favorite.js.erb     
<% if flash.now[:notice] %>
   $('.modal-dialog.photo>.message').html("<%= j flash.now[:notice] %>")
<% else %>
  $('.modal-dialog.photo>.message').html("<%= j flash.now[:alert] %>")
<% end %>

# app/views/photo/unfavorite.js.erb
<% if flash.now[:notice] %>
  $('.modal-dialog.photo>.message').html("<%= j flash.now[:notice] %>")
<% end %>

It kind of goes that notice is like success and alert are error.

And change your controller to this:

def favorite
  @photo = Photo.find params[:id]
  favorite_photo = current_user.favorites.build(photo: @photo)

  if favorite_photo.save
    flash.now[:notice] = 'You successfully favorited this photo'
  else
    flash.now[:alert] = favorite_photo.errors.full_messages
  end
  respond_to :js
end

def unfavorite
  @photo = Photo.find params[:id]
  current_user.favorites.delete(@photo)
  flash.now[:notice] = 'You successfully unfavorited this photo'
  respond_to :js
end

And your routes to match this configuration.

I'd POST to favorite and DELETE to unfavorite due to the DB implications of each.

Currently you can only pass notice and alert to a render or redirect_to . But you can defined your own flash types. But don't constrain yourself by using only these two.

if success
  flash[:success] = "Something good"
else
  flash[:error] = "Something bad"
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM