I have a form like this :
<%= simple_form_for #user, remote: true do |f| %>
<%= f.input :email %>
<%= f.input :photo, as: :attachinary %>
<%= f.button :submit %>
<% end %>
My controller looks like this :
def update
if #user.update(user_params)
respond_to do |format|
format.html { redirect_to user_path(#user) }
format.js
end
else
respond_to do |format|
format.html { render 'users/edit' }
format.js
end
end
end
It works good with the HTML version but not with javascript version.
I know that browsers don't allow file upload via XMLHttpRequest, so I find a solution with remotipart gem, but it only considers <%= f.file_field :file %> and not my <%= f.input :photo, as: :attachinary %>
Related
I have implemented a favorites system into my rails app, which works on the individual show page for the Tracks model. This is all handled through the Favorites controller, so I am attempting to use the same js file for both index and show pages. This is what I have tried so far. It works if I only have the show page material, the javascript doesn't work at all for either if I do it this way.
favorite.js.erb
<% if current_page?(track_path(#track)) %>
$("#favorites").html("<%= escape_javascript(render('tracks/favorites')) %>");
<% else %>
$("#favorites").html("<%= escape_javascript(render('albums/favorites')) %>");
<% end %>
the partial for tracks/favorites
<% if user_signed_in? && current_user.favorited?(#track) %>
<%= link_to image_tag('icons/heart_full.svg', width: 20), track_unfavorite_path(#track), method: :post, remote: true %>
<% else %>
<%= link_to image_tag('icons/heart_empty.svg', width: 20), track_favorite_path(#track), method: :post, remote: true %>
<% end %>
the partial for albums/favorites
<% if user_signed_in? && current_user.favorited?(track) %>
<%= link_to image_tag('icons/heart_full.svg', width: 20), track_unfavorite_path(track),
method: :post, remote: true %> <%= pluralize( track.favorites.count, 'favorite' ) %>
<% else %>
<%= link_to image_tag('icons/heart_empty.svg', width: 20), track_favorite_path(track),
method: :post, remote: true %> <%= pluralize( track.favorites.count, 'favorite' ) %>
<% end %>
Passing the instance variable as the parameter works for the show page, but trying to do it for the loop results is what is confusing me.
favorites_controller.rb
class FavoritesController < ApplicationController
before_action :authenticate_user!
before_action :find_track
def favorite
#track.favorites.where(user_id: current_user.id).first_or_create
respond_to do |format|
format.html { redirect_to #track }
format.js
end
end
def unfavorite
#track.favorites.where(user_id: current_user.id).destroy_all
respond_to do |format|
format.html { redirect_to #track }
format.js
end
end
private
def find_track
#track = Track.find(params[:track_id])
end
end
The view for Track show page is simple:
<div id="favorites">
<%= render 'tracks/favorites' %>
</div>
The view for the loop on the index page:
<% #tracks.each do |track| %>
<div class="track_thumbnail">
<% if track.avatar? %>
<%= link_to image_tag(track.avatar.url), track_path(track), width: 100, title: track.title %>
<% else %>
<%= link_to image_tag(track.user.avatar.url), track_path(track), width: 100, title: track.title %>
<% end %>
<%= link_to track.user.username, user_path(track.user) %>
</div>
<div class="track_overview">
<h2><%= link_to track.title, track_path(track) %><% if track.explicit == "explicit" %> (explicit)<% end %></h2>
<p class="description"><%= truncate(track.description, length: 160) %></p>
<div class="icons_container">
<div id="favorites">
<%= render 'albums/favorites', :track => track %>
</div>
</div>
</div>
<% end %>
I'm trying to render an edit form when someone clicks on an object in a list.
I made a test action in my controller like this:
def test
respond_to do |format|
format.js
end
end
In my view I made a link like this:
<%= link_to image_tag('icons/edit3.png'),
:remote => true,
:controller => :aliens,
:id => alien.expansion.id,
:ph_id => alien.id,
:action => :test
%>
and in my test.js.erb
console.log('testing');
I also made a custom route
get 'expansions/:id/aliens/:ph_id/test' => 'aliens#test', as: :test
This works great. Everytime I click on an object it prints out in the console.
The problem is that I want the .js.erb to render the form. BUT, if I add this code to the js:
$('.dialog__content').append('<%= j render :partial => 'editform', :formats => :html %>');
or
$('.dialog__content').html("<%= j render(#editform) %>'");
or
$('.dialog__content').html("<%= escape_javascript (render partial: 'editform') %>");
It returns GET "My path" 404 (Not Found)
And If I add variables to my action like this:
def test
#aliens = Alien.all
#expansions = Expansion.all
#expansion = Expansion.find(params[:expansion_id])
#alien = #aliens.find(params[:id])
respond_to do |format|
format.js
end
end
It also returns: GET "My path" 404 (Not Found)
What should I do?
Thanks.
Update:
My editform partial,
Seems like the variables is the problem. I tried rendering a partial with only html in it, and that works fine.
<div class="hidden_form form_holder">
<%=form_for [#expansion, #alien], :remote => true, :html => {:class => "add edit", :multipart => true } do |f| %>
<h2>Rediger Alien </h2>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :difficulty %>
<%= f.select :difficulty, ['Beginner', 'Intermediate', 'Hard']%>
<%= f.label :tokens %>
<%= f.number_field :tokens %>
<div class="clearfix">
<div class="byside">
<%= f.check_box :gamesetup %>
<%= f.label :gamesetup, :class => 'check'%>
</div>
<div class="byside">
<%= f.file_field :avatar %>
</div>
</div>
<%= f.submit %>
<% end %>
</div>
I'm trying to make a simple example on a new form to send the notice of success when creating a new item using ajax.
I'm reciving a response from the server with 500 internal error.
new.js.erb
$("#flash-messages").html("<%= notice %>")
new.html.erb
<h1>New Ajax</h1>
<%= form_for(#ajax, remote: true) do |f| %>
<div id="flash-messages" >
</div>
<% if #ajax.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#ajax.errors.count, "error") %> prohibited this ajax from being saved:</h2>
<ul>
<% #ajax.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
controller
def create
#ajax = Ajax.new(ajax_params)
respond_to do |format|
if #ajax.save
format.html { redirect_to #ajax, notice: 'Ajax was successfully created.' }
format.json { render :show, status: :created, location: #ajax }
format.js { redirect_to new_ajax_path, flash[:notice] = "Fudeu" }
else
format.html { render :new }
format.json { render json: #ajax.errors, status: :unprocessable_entity }
end
end
end
I have found why was bugging my code.
Just nee do remove the flash[:notice] to notice:
Now I`m looking into giving a lifetime to this flash, like 10s and it vanishs
When I have it working I post it here for other people that may strugle as me
My bookmarks index page is essentially a single page application. When I submit the form for a new bookmark at the bottom of my page, I want the page to not have to refresh and display "Bookmark successfully created!" in the form of a flash message at the top of the page.
In my application.html.erb file, I am rendering flash messages:
<!DOCTYPE html>
<html>
<head>
<title>Text Me Later</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= render partial: 'layouts/nav' %>
<% flash.each do |key, value| %>
<% if key == "notice" %>
<%= content_tag :div, value, class: "text-center alert alert-warning" %>
<% elsif key == "alert" %>
<%= content_tag :div, value, class: "text-center alert alert-danger" %>
<% else %>
<%= content_tag :div, value, class: "text-center alert alert-success" %>
<% end %>
<% end %>
<div class="container">
<%= yield %>
<%= debug(params) if Rails.env.development? %>
</body>
</html>
The create method in my bookmarks_controller:
def create
#bookmark = Bookmark.new bookmark_params
#bookmark.user_id = current_user.id
respond_to do |format|
if #bookmark.save
flash[:notice] = 'Bookmark was successfully created.'
format.html {
redirect_to user_bookmarks_path
}
format.json {
render json: #bookmark,
status: :created,
location: #bookmark
}
format.js {}
else
flash[:error] = "Bookmark could not be created."
format.html {
render :index
}
format.json {
render json: #bookmark.errors.full_messages
}
format.js {}
end
end
end
My bookmarks index.html.erbfile:
<h2>All of <%= current_user.first_name %>'s Bookmarks</h2>
<ul id="all-bookmarks">
<% #bookmarks.each do |bookmark| %>
<li class="bookmark-div">
<div><%= bookmark.title %></div>
<div><%= bookmark.image %></div>
<div><%= bookmark.description %></div>
<div><%= bookmark.location %></div>
<div><%= bookmark.time %></div>
<div><%= bookmark.date %></div>
<div><%= bookmark.created_at %></div>
<div><%= bookmark.updated_at %></div>
<div><%= bookmark.url %></div>
<div><%= link_to "Edit", [:edit, bookmark]%></div>
<div><%= link_to "Delete Bookmark", bookmark, :method => :delete, confirm: 'are you sure?'%></div>
<div><%= link_to "Add as a reminder" %></div>
</li>
<% end %>
</ul>
<h2>Add a bookmark below:</h2>
<div id="post-new-bookmark">
<%= simple_form_for [#user, #bookmark], :method => :post, remote: true do |f| %>
<% if #bookmark.errors.any? %>
<div id="errorExplanation">
<h2><%= pluralize(#bookmark.errors.count, "error") %> prohibited this post from being saved:</h2>
<% end %>
<%= f.input :title %>
<%= f.input :image %>
<%= f.input :description %>
<%= f.input :location %>
<%= f.input :date %>
<%= f.button :submit %>
<% end %>
</div>
create.js.erb:
$("<%= escape_javascript(flash[:notice]) %>").appendTo("#flash-notice")
$("<%= escape_javascript render(:partial => 'bookmarks/cbookmark', :locals => { :bookmark => #bookmark }) %>").appendTo("#all-bookmarks")
My question is: Why is the flash message on successful bookmark creation not displaying at the top of the page right after a successful creation? Shouldn't the flash message handling in my application.html.erbtake care of it? Could it be due to a syntax error in my bookmark controller?
I also have a question about flash.now vs flash. Is that relevant in this case since the bookmark submission is an AJAX action?
form of a flash message
Ce ne pas possible avec le flash de Rails
--
The flash forms part of the session cookie that Rails populates between actions. This has been notoriously difficult to parse with Ajax, and indeed remains a difficult pattern to implement (how can Rails repopulate the session when your browser hasn't been refreshed).
The way to go about it is to pass the value through your ajax method, using flash.now. Good ref here (I wrote about it):
#app/controllers/bookmarks_controller.rb
class BookmarksController < ApplicationController
def create
#bookmark = Bookmark.new bookmark_params
#bookmark.user_id = current_user.id
respond_to do |format|
if #bookmark.save
flash.now[:notice] = 'Bookmark was successfully created.'
format.html { redirect_to user_bookmarks_path }
format.json { render json: #bookmark, status: :created, location: #bookmark }
format.js
else
flash.now[:error] = "Bookmark could not be created."
format.html { render :index }
format.json { render json: #bookmark.errors.full_messages }
format.js
end
end
end
end
Using flash.now should allow you to populate the flash through Ajax accordingly:
#app/views/bookmarks/create.js.erb
$("<%=j flash.now[:notice] %>").appendTo("#flash-notice")
I have a view that has a form to create a new post using Ajax, and it also renders all the posts and adds the newly added post to them. The problem is when I post the very first post, the page does not show it unless I refresh, then if I refresh it shows up and when I add more posts Ajax works fine.
Here is the view index.html.erb :
<%= link_to('Logout', destroy_user_session_path, :method => :delete) %>
<%= link_to 'Edit my account', edit_user_registration_path %>
<%= form_tag search_posts_path, method: :get do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", name: nil %>
<% end %>
<b> Study requests </b>
<%= form_for(#post, remote: true) do |f| %>
<%=f.label :Course_name %>
<%=f.select :course_name, options_for_select(course_names) %><br/>
<%=f.label :Course_number %>
<%=f.select :course_number, options_for_select(course_numbers) %> <br/>
<%=f.submit %>
<% end %>
<%= render #posts %>
The partial is _post.html.erb :
div id="post">
<%= post.user_name%>
</div>
Controller :
def index
#posts = Post.all.order('id DESC')
#post = Post.new
end
def create
#post = current_user.posts.build(post_params)
#post.save
respond_to do |format|
format.html { redirect_to #post, notice: "Study request successfully added" }
format.js {}
format.json { render json: #post, status: :created, location: #post }
end
end
And finally my create.js.erb :
$("<%= escape_javascript(render #post) %>").prependTo("#post");
I got it, I only needed to add a new div around my partial rendering like this :
<ul id="container">
<%= render #posts %>
</ul>
And change the create.js to append to this div