i need two buttons in my view but only one should use remote, so i decided to use a link and a submit button in the following way:
view
<%= form_for(#new_word , :url => {:action => "create"}) do |f| %>
... skipped code ...
<%= link_to("build word", '#', :class => "build", "data-button" => "build") %>
... skipped code ...
<div id="build_name"></div>
<%= submit_tag l(:btn_save), :name => 'btn_save' %>
<% end %>
<script type="text/javascript">
jQuery(".build").click(function(){
var form_value = jQuery('#new_nc_project').serialize();
var button = $(this).data("button");
var content = $('#nc_project_keyword_tokens').val();
if(button == "build"){
$.ajax({
type:'POST',
url: '<%= url_for :action => 'build' %>',
data: $.param({keyword_tokens: content})
});
}
});
</script>
controller
def build
#response = {resp: "text"} //just example text for testing
respond_to do |format|
format.json { render json: #response }
format.js { render js: #response }
end
end
build.js.erb
$('#build_name').append('<p><%= #response[:resp] %></p>');
If I look at my server console, I see no listing from "build.js.erb" file.
What am I doing wrong, is there a other way to make the "#respond" visible in at view?
Thanks, dot
To render build.js.erb you should do this
respond_to do |format|
format.json { render json: #response }
format.js # this will render build.js.erb by default.
end
Related
my route.rb
post 'home/create'
get 'home/create'
my HomeController
def create
#review_n = Review.create(review_params)
if #review_n.errors.empty?
respond_to do |format|
format.js { render 'create', locals: {review_name: #review_n.review_n, review_body: #review_n.review_body} }
end
else
render 'index'
end
end
my create.js.erb
$(function() {
$(".wrap-body").append("<div> tmp </div>");
});
rails say: ActionController::UnknownFormat in HomeController#create
I want send data in my html.erb without reload page. Help me, please!
UPD:
my html.rb
<%= form_tag home_create_path, :method => 'post', :remote => true do %>
<%= text_area_tag 'review[review_body]', nil %>
<%= text_field_tag 'review[review_name]', nil %>
<%= submit_tag 'send' %>
<% end %>
Is your code hitting the render 'index' call that is outside of the respond_to block?
Normally you would put all render calls inside the respond_to block, so it's obvious that all paths of your logic can respond to all expected formats:
def create
#review_n = Review.create(review_params)
respond_to do |format|
if #review_n.errors.empty?
format.js { render 'create', locals: {review_name: #review_n.review_n, review_body: #review_n.review_body} }
else
format.js { render 'index' }
end
end
end
This requires having both a create.js.erb and an index.js.erb (for the error case).
Also, as #sahil recommended, your routes.rb should not declare get 'home/create' - this action modifies data, so it isn't safe to make it accessible via GET.
I'm following the jquery file upload video from RailsCast but I can't get the images to show up without refreshing the page.
My photo is being uploaded through this form:
<%= simple_form_for #upload, html: { multipart: true, id: 'add_new_project_photos' } do |f| %>
<%= f.simple_fields_for :project_images, ProjectImage.new, child_index: ProjectImage.new.object_id do |ff| %>
<%= ff.file_field :photo, multiple: true, name: "project[project_images_attributes][][photo]" %>
<% end %>
<% end %>
I also created a create.js.erb file.
<% if #project.project_images.new_record? %>
alert("Failed to upload painting: <%= j #painting.errors.full_messages.join', ').html_safe %>");
<% else %>
$("#added_photos").append("<%= j render(#project) %>");
<% end %>
My controller
class ProjectsController < ApplicationController
#... other methods
def create
#project = Project.new(trip_params)
#upload = Project.create(trip_params)
if request.xhr?
redirect_to root_url
else
redirect_to :back
end
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
end
My coffee script file
jQuery ->
$('#add_new_trip_photos').fileupload
dataType: "script"
You need to respond to js as well. In your create method you are only responding to html and json
format.js
Should be placed inside your respond_to block
I am following section 4 (Server Side Concerns) to set up ajax on a page. I've copied the tutorial text completely (replacing the model names with my own) and it creates and saves my "Participants" record and refreshes the partial....but it posts this weird code below the just submitted form:
$("
\n\n Helper:sampleemail#sample.com \n<\/li>\n\n").appendTo("#participants");
This seems to be some sort of weird mash-up of my partial information and my creat.js. It's not really an error...just extra code.
Here's my code
class ParticipantsController < ApplicationController
def new
#participant = Participant.new
#participants = #participants.recently_updated
end
def create
#participant = Participant.new(participant_params)
respond_to do |format|
if #participant.save
format.html { redirect_to #participant, notice: 'Helper Invited!' }
format.js {}
format.json { render json: #participant, status: :created, location: #participant }
else
format.html { render action: "new" }
format.json { render json: #participant.errors, status: :unprocessable_entity }
end
end
end
_form.html.erb
<ul id="participants">
<%= render #participants %>
</ul>
<%= form_for(#participant, remote: true) do |f| %>
<%= f.label :email %><br>
<%= f.email_field :email %>
<%= f.submit 'SUBMIT' %>
<script>
$(document).ready(function() {
return $("#new_participant").on("ajax:success", function(e, data, status, xhr) {
return $("#new_participant").append(xhr.responseText);
}).on("ajax:error", function(e, xhr, status, error) {
return $("#new_participant").append("<p>Oops. Please Try again.</p>");
});
});
</script>
<script>
$(function() {
return $("a[data-remote]").on("ajax:success", function(e, data, status, xhr) {
return alert("The helper has been removed and notified.");
});
});
</script>
_participant.html.erb
<li >
<%= participant.email %> <%= link_to participant, remote: true, method: :delete, data: { confirm: 'Are you sure?' } do %>REMOVE<% end %>
</li>
create.js.erb
$("<%= escape_javascript(render #participant) %>").appendTo("#participants");
destroy.js.erb
$('#participants').html("<%= j (render #participants) %>");
It seems like you are both responding with a js.erb file and listening for the ajax:success event. You should only need to do one. Right now the ajax:success listener is appending the response to the form and the response is javascript code. Remove that listener and you should get the desired results.
I have a rails app, in which my Posts model has Comments and the comments are votable. I'm using acts_as_votable.
I currently have the voting on the comments working. Now I'm trying to implement some javascript so that the page does not have to refresh every time someone votes on a comment, so that the vote goes through.
Here is what I had before(which was working):
In my comments controller:
def upvote_post_comment
#post = Post.find(params[:post_id])
#comment = #post.comments.find(params[:id])
#comment.liked_by current_user
respond_to do |format|
format.html {redirect_to :back}
end
end
And in my view:
<% if user_signed_in? && current_user != comment.user && !(current_user.voted_for? comment) %>
<%= link_to image_tag(‘vote.png'), like_post_comment_path(#post, comment), method: :put %> <a>
<%= "#{comment.votes.size}"%></a>
<% elsif user_signed_in? && (current_user = comment.user) %>
<%= image_tag(‘voted.png')%><a><%= "#{comment.votes.size}"%></a>
<% else %>
<%= image_tag(‘voted.png')%><a><%= "#{comment.votes.size}"%></a>
<% end %>
And this is what I now have:
In my comments controller:
def upvote_post_comment
#post = Post.find(params[:post_id])
#comment = #post.comments.find(params[:id])
#comment.liked_by current_user
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: #comment.liked_count } }
end
end
And in my view:
<% if user_signed_in? && current_user != comment.user && !(current_user.voted_for? comment) %>
<%= link_to image_tag(‘vote.png'), like_post_comment_path(#post, comment), method: :put, class: 'vote', remote: true %>
<a><%= "#{comment.votes.size}"%></a>
<script>
$('.vote')
.on('ajax:send', function () { $(this).addClass('loading'); })
.on('ajax:complete', function () { $(this).removeClass('loading'); })
.on('ajax:error', function () { $(this).after('<div class="error">There was an issue.</div>'); })
.on('ajax:success', function (data) { $(this).html(data.count); });
</script>
<% elsif user_signed_in? && (current_user = comment.user) %>
<%= image_tag(‘voted.png')%><a><%= "#{comment.votes.size}"%></a>
<% else %>
<%= image_tag(‘voted.png')%><a><%= "#{comment.votes.size}"%></a>
<% end %>
This shows me the error message: "There was an issue"
And when I refresh the page, I see that the vote went through and I see this in my terminal:
Started PUT “/1/comments/1/like" for 127.0.0.1 at 2014-04-06 18:54:38 -0400
Processing by CommentsController#upvote_post_comment as JS
Parameters: {"post_id"=>”1”, "id"=>”1”}
How do I get the voting to work via Javascript? So that the vote goes through, the vote count updates and the vote icon updates to voted.png instead of vote.png?
Your log says the request is formatted as JS.
Processing by CommentsController#upvote_post_comment as JS
Add data: { type: :json } to the link_to method to request a JSON format like so,
<%= link_to image_tag('vote.png'), like_post_comment_path(#post, comment), method: :put, class: 'vote', remote: true, data: { type: :json } %>
This will tell the controller you want a JSON response not a Javascript response.
Edit - updates from the comments.
Update controller to use,
format.json { render json: { count: #comment.likes.size } }
Update JS to use,
.on('ajax:success', function(e, data, status, xhr) { $(this).html(data.count); });
rails 3 form partial
<%= form_for(answer, :remote => true) do |f| %>
<% if answer.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(answer.errors.count, "error") %> prohibited this answer from being saved:</h2>
<ul>
<% answer.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.hidden_field :conduct_evaluation_id, :value => conduct_evaluation.id %>
</div>
<div class="field">
<%= f.hidden_field :question_id, :value => question.id %>
</div>
<div class="field">
<%= f.hidden_field :program_block_id, :value => conduct_evaluation.program_block_id %>
</div>
<div class="field">
<%= f.radio_button :answer, true, :onchange => "$(this.form).trigger('submit.rails');" %>yes<br/>
<%= f.radio_button :answer, false, :onchange => "$(this.form).trigger('submit.rails');" %>no<br/>
</div>
<div class="actions">
<%= f.submit "Answer" %>
</div>
<% end %>
controller actions
# POST /answers
# POST /answers.json
def create
#answer = Answer.new(params[:answer])
#answer.user = current_user
#answer.conduct_evaluation = ConductEvaluation.find(params[:answer][:conduct_evaluation_id])
respond_to do |format|
if #answer.save
format.js { }
format.html { redirect_to #answer, notice: 'Answer was successfully created.' }
format.json { render json: #answer, status: :created, location: #answer }
else
format.js { }
format.html { render action: "new" }
format.json { render json: #answer.errors, status: :unprocessable_entity }
end
end
end
# PUT /answers/1
# PUT /answers/1.json
def update
#answer = Answer.find(params[:id])
respond_to do |format|
if #answer.update_attributes(params[:answer])
format.js { }
format.html { redirect_to #answer, notice: 'Answer was successfully updated.' }
format.json { head :no_content }
else
format.js { }
format.html { render action: "edit" }
format.json { render json: #answer.errors, status: :unprocessable_entity }
end
end
end
Can anyone tell me what I am doing wrong to make the javascript submit via ajax? When I use the submit button, the request is sent via ajax. If I use the onchange event for the radio button and attempt to submit the form via javascript, it thinks the request is HTML.
Any help would be much appreciated!
-J
EDIT:
So when I use the form submit button, the request is slightly different:
Processing by AnswersController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IcJkV1GnIOEGRs7kaRuVQsp0sTNtHQw0Q+HMM7m/mV0=", "answer"=>{"conduct_evaluation_id"=>"15", "question_id"=>"1", "program_block_id"=>"1", "answer"=>"true"}, "commit"=>"Answer"}
versus using the onchange javascript to trigger a rails.submit event:
Processing by AnswersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IcJkV1GnIOEGRs7kaRuVQsp0sTNtHQw0Q+HMM7m/mV0=", "answer"=>{"conduct_evaluation_id"=>"15", "question_id"=>"1", "program_block_id"=>"1", "answer"=>"true"}}
Does anyone know why this may be occurring? Do I need to specify additional parameters when triggering the submit.rails event? Please help! :-D
EDIT 2:
So I found a workaround. It works if I bind the change event for the radio buttons to actually clicking the submit button. This is not the ideal solution, but at least it works.
EDIT 3:
I have decided on the following coffeescript:
$(document).ready ->
$('#my_form input:submit').hide()
$('#my_form input:radio').change ->
$.ajax
type: $(this.form).attr('method')
url: $(this.form).attr('action')
data: $(this.form).serialize()
dataType: 'script'
This allows the corresponding js action file to be returned as the response and be automatically executed on success.
Using onchange() bypasses Rails magic so it won't submit the form as you wish. Write your own change method, f.e.:
$('input.radio_button_selector').change( function() {
$.ajax({
url: $('#my_form').attr('action'),
data: $('#my_form').serialize()
});
});