I have a remote form in my Rails 4 application for my Artists model. I have another form for my Shows, and the Shows form has a link that can be clicked if the user wishes to add a new Artist to the database from inside the Shows form. Clicking that link sends a GET request to /artists/new and the ArtistsController assigns @artist a new Artist and then renders new.js.erb, which hides the link to add a new Artist and renders the form for a new Artist in its place.
The form is rendered fine, and when I click submit a POST request is sent and it is routed to the create method in my ArtistsController The server then sends a response back that is in my create.js.erb file, but that response is interpreted by the browser as html. Instead of executing the JavaScript that is in create.js.erb it just displays the code in the browser.
Here is my Shows form
= form_for @show, html: {role: 'form'} do |f|
- if @show.errors.any?
#error_explanation
%h2= "#{pluralize(@show.errors.count, "error")} prohibited this venue from being saved:"
%ul
- @show.errors.full_messages.each do |msg|
%li= msg
.row
= f.label :venue_id
= f.collection_select :venue_id, Venue.all, :id, :name, class: 'form-control'
.row
.col-sm-6
= link_to 'New Artist', new_artist_path, id: :new_artist_link, remote: true
.row.row-centered
.col-sm-6
.form-group
= f.label :date
= f.date_select :show_date, order: [:day, :month, :year], class: 'form-control'
.col-sm-6
.form-group
= f.label :doors_open
= f.time_select :doors_open, class: 'form-control'
.row.row-centered
.col-sm-6
.form-group
= f.label :dinner_starts
= f.time_select :dinner_starts, class: 'form-control'
.col-sm-6
.form-group
= f.label :show_starts
= f.time_select :show_starts, class: 'form-control'
.row.row-centered
.col-sm-6
.form-group
= f.label :dinner_ends
= f.time_select :dinner_ends, class: 'form-control'
.col-sm-6
.form-group
= f.label :show_ends
= f.time_select :show_ends, class: 'form-control'
.form-group
= f.submit 'Save Show', class: 'btn btn-default'
Here is my Artists form
= form_for(@artist, remote: true, authenticity_token: true, format: :js) do |f|
- if @artist.errors.any?
#error_explanation
%h2= "#{pluralize(@artist.errors.count, "error")} prohibited this artist from being saved:"
%ul
- @artist.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name
.actions
= f.submit 'Submit'
Here is my ArtistsController new and create methods
def new
@artist = Artist.new
respond_to do |format|
format.js
end
end
def create
@artist = Artist.new(artist_params)
if @artist.save
respond_to do |format|
format.js
end
end
end
Here is my new.js.erb
$('#new_artist_link').hide().after("<%= j render 'form' %>");
My create.js.erb. I had actual code in here, but removed it, and just replaced it with this until I can figure out the problem.
$('h1').hide();
I spent all day yesterday trying to figure this out and am totally baffled.
EDIT: Writing the following jQuery in my new.js.erb and adding post 'artists/create to my routes allowed me to post the data, the problem was that the accept header of the post was not accepting JavaScript. Is there a way to not have to write the entire ajax request and to just modify the existing one to accept javascript?
Updated create.js.erb
$('#new_artist_link').hide().after("<%= j render 'form' %>");
$('#new_artist_link').remove();
$('#new_artist').submit(function() {
var url = "/artists/create"; // the script where you handle the form input.
$.ajax({
type: "POST",
url: url,
data: $("#new_artist").serialize(), // serializes the form's elements.
accepts: 'application/javascript'
});
return false; // avoid to execute the actual submit of the form.
});