Clearing my ajax form in rails - javascript

I'm trying to clear the form if its submitted but the problem is my controller handles all the validation.
The AJAX response in contact.js.haml simply makes use of flashes not being defined if its invalid data.
/contact.js.haml
$("#new_message").replaceWith("#{j(render partial:'contact_mailer/contact_me', locals: {object: #message, notice: #notice} )}")
The controller sets the notice if needed
class MessagesController < ApplicationController
def contact
#message = Message.new(params[:message])
respond_to do |format|
if #message.valid?
flash.now[:notice] = 'Message was sent successfully.'
ContactMailer.contact_me(#message)
format.html { redirect_to contact_path, notice: 'Message was sent successfully.' }
format.js
else
format.html { redirect_to contact_path }
format.js
end
end
end
end
The issue is on a successful message send, the form still has the same data, allowing the user to spam it
I know this can be solved with JSON or XML to send the data but is there a way without!
*edit screenshot of reset() not working

- if !#message.errors.any?
$(':input').not(':button, :submit, :hidden').val('')
haml didn't work before so I assumed it wouldn't but it did.

A little cleaner: just reset the form (a plain javascript function).
In short:
$('form')[0].reset
This resets the first form on the page.
However, see this answer:How come form.reset() doesn't work after postback on this page? It will reset the form to the values it received. And you send it from the server, with values!!!!
So the fix is dead-easy, in your MessagesController write
def contact
#message = Message.new(params[:message])
respond_to do |format|
if #message.valid?
flash.now[:notice] = 'Message was sent successfully.'
ContactMailer.contact_me(#message)
#message = Message.new
format.html { redirect_to contact_path, notice: 'Message was sent successfully.' }
format.js
else
format.html { redirect_to contact_path }
format.js
end
end
end
So before rendering, start with a fresh, new message, and your form will be ok :)
On a general note: your naming and grouping is generally very confusing and not very structured. You should work on that.

Related

How to execute JS after saving a model in DB in Rails 6?

I’m Rails beginner and I’m a bit overwhelmed by the quite simple problem. I would like to do something like this:
Users fills in a form.
Taps on the submit button
Model is saved into database.
If the save operation was successful, execute a javascript.
The questions is: how to accomplish that in the best way possible in Rails 6? Should I use .js.erb files? Or should I have javascript put into webpacker?
I tried so far the following code, but without any success:
controller/jobs_controller.rb
def create
#job = current_user.jobs.build(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Success!' }
format.js {}
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
views/jobs/create.js.erb
alert('hello');
As it was pointed out by #max-pleaner I was missing remote: true in the form tag.

Rails respond_to throw ActionController::UnknownFormat

So, I'm trying to respond to an action with a js file.
def my_schedule
respond_to do |format|
format.js
end
end
In my view, I have 'my_schedule.js.erb' but it's not even executed, rails broke in the controller and throw me an error : ActionController::UnknownFormat, where I have the respond_to.
I tried to add
respond_to :js, :json, :html
at the beginning of my controller out of the actions but still not working.
Need help to debug this and understand how respond_to really works.
format.js will only respond to an xhr request. You can't trigger this response by just navigating to the route that points to this controller and method.
You can test the js.erb execution by changing the respond_to block to
def my_schedule
respond_to do |format|
format.html
format.js
end
end
Then create a my_schedule.html.erb file in the same view folder as the js.erb with the following contents
<%= link_to 'Test', my_schedule_path, data: { remote: true } %>
Note that you may need to adjust that path, I'm just guessing on that.
Then navigate to the same path you were trying to before. You should see a link which, when clicked, will fire the js response.

How do I properly handle a remote link to in Rails 4? JSON?

I have the following code:
= link_to "#{icon('heart')} Props".html_safe, vote_picture_path(picture), class: 'tiny radius secondary button vote', method: :put, remote: true
Which goes here:
# VOTE /pictures/1.json
def vote
respond_to do |format|
if #picture.toggle_vote(current_user)
format.json { render json: #picture }
else
format.json { render json: #picture }
end
end
end
And what I'm trying to do is update the total count of votes on a picture via:
$ ->
$(".vote").on "ajax:success", (e, data, status, xhr) ->
vote_count_size = $(".vote-count .size").html()
vote_count_size_integer = parseInt(vote_count_size)
console.info data
However the part that confuses me is the console.info data. It seems to be returning something from a source I can't tell. I'm editing /pictures/show.json.jbuilder but it's not affecting what's coming in from data. I want to return a json structure with the total votes in data so I can update the count on the page from the success callback.
Firstly, your respond_to block can be refactored dramatically:
# VOTE /pictures/1.json
respond_to :json
def vote
#picture.toggle_vote(current_user)
respond_with #picture
end
This should return a JSON object for your #picture var. You'll have to detail what data you're getting in your console? If you provide the data you're receiving back, it will be a huge help!
You should respond with a javascript file (vote.js.erb) within this you can mix javascript and erb expressions to change the desired page element:
$('.vote-count .size').html('<%=#picture.vote_count%> votes');
your controller would look like:
# VOTE /pictures/1.js
def vote
respond_to do |format|
#picture.toggle_vote(current_user)
format.js
end
end

Rails Edge Guides, AJAX example- why use both 'format.js' and 'format.json'?

In the "Working With Javascript" section of the Rails Edge Guides, an example is given of how to structure a 'create' action inside a 'User' controller, in order to integrate AJAX into the creation action:
# app/controllers/users_controller.rb
# ......
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.js {}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I've read here that both 'format.js' and 'format.json' are needed, because Javascript and JSON are different types of response. My question is, if both formats are specified in the first half of the 'create' action's if statement, why aren't both also needed in the 2nd half? Does this mean that Javascript uses the 'create.js.erb' file on success, but not on failure?
Yes, you are correct. Based on skimming the guide, it looks like you don't want to do anything with js in the case of failure. If you were to put
format.js {}
in the failure block as well, then it would try to execute the render #user portion, which would probably cause an error anyway.
If you really did want to execute a js block in the event of failure, you could just do it the same way as for the other formats.

Rails 3 - respond_to as JS and flash message

After send a form I will process a data from form and wanna to render an action as JS. This work me.
But + this functionality I would like to add a flash message yet. I try to do it as follows:
respond_to do |format|
if #save.update_attributes(params[:data])
format.js {
flash[:notice] = 'The article was successfully updated.'
render :update do |page|; page << "$('#my_div').html('#{escape_javascript(render(:partial => 'article'))}');" end
}
format.html {}
else
format.html { render :action => "edit" }
format.xml { render :xml => #data.errors, :status => :unprocessable_entity }
end
Now the flash message is not displayed. Could anyone help me, why not? I tried the line with flash[:notice] move to out of format.js block, but the is still not displayed...
Could you help me, please, why?r
I guess you can use the point 2.2.10 of the documentation :
http://guides.rubyonrails.org/layouts_and_rendering.html#using-render
render :js => "$('#my_div').html('#{escape_javascript(render(:partial => 'article'))}');"

Categories