Ajax/Rails create action not working - ruby-on-rails

Hello and thanks in advance. Rails noob here :)
I have a simple rails app where a user can create an article through ajax. When the "Create article" is clicked _article_form.html.erb and new.js.erb are rendered, but when i click submit form nothing happens. No article is created. Here is new.js.erb
m = $('.modal');
m.html('<%= j(render partial: 'article_form', locals: { articles: #articles }) %>');
m.modal('show');
Here is my ArticlesController
def new
#article = Article.new
end
def create
#article = Article.create(article_params)
#articles = Article.all
end
private
def article_params
params.require(:article).permit(:title, :body)
end
Here is the home.html.erb
...
<div id="article_list">
<%= render partial: 'articles/article_list' %>
</div>
<div class="modal fade" role="dialog"></div>
And my partials _article_form
<div class="modal-dialog">
<div class="modal-body">
<%= simple_form_for #article, class: 'clearfix', remote: true do |f| %>
<%= f.input :title %>
<%= f.input :body %>
</div>
<div class="modal-footer">
<%= f.submit 'Save', class: 'btn btn-primary' %>
<% end %>
</div>
</div>
and _article_list
<% if #articles.empty? %>
<span class="text-warning">
There are no articles yet!
</span>
<% else %>
<div class="panel panel-default">
<div class="panel-heading">Articles</div>
<div class="panel-body">
<ul class="list-group">
<% #articles.each do |article| %>
<li class="list-group-item">
<%= article.title %></br>
<%= article.body.truncate(25, separator: ' ') %>
</li>
<% end %>
</ul>
</div>
</div>
<% end %>
Lastly, my create.js.erb
$('#article_list').html('<%= j(render partial: 'articles/article_list') %>');
$('.modal').modal('hide');
I have been searching/trying to figure this out for 2 days but with no luck.

If you inspect the html of your form you will notice that the submit button is out of scope of form tag. that's why when you click on submit button, no action happens.
Change your html in partial _article_form as following:
<div class="modal-dialog">
<%= simple_form_for #article, class: 'clearfix', remote: true do |f| %>
<div class="modal-body">
<%= f.input :title %>
<%= f.input :body %>
</div>
<div class="modal-footer">
<%= f.submit 'Save', class: 'btn btn-primary' %>
</div>
<% end %>
</div>

Related

Undefined local variable or method `form' for class when passing locals: form:form through a partial

I currently have 3 separate views, two using AJAX to create/edit tasks.
I'm trying to set a date that the task is due, and would like to present some options to the user for today, one week from today, two weeks for today, all contained within one partial that I can use across all three forms.
I thought I'd do this using AJAX, and simply update that one area of the form to change the default value of the variable, however, I can't render the form.
If there is a better way of doing this instead please let me know.
I get the following error:
ActionView::Template::Error (undefined local variable or method `form' for #<#<Class:0x00007fe8a4ccd8e8>:0x00007fe8a4b64df8>
Did you mean? for
fork):
1: $("#date-container").html(" <%= j render partial: "goal_tasks/set_due_date", locals: { task: #goal_task, form: form } %>");
edit.html.erb (with extra fields snipped):
<%= render 'layouts/pagetitle', title: "Edit Task" %>
<%= form_for([#goal_task.goal, #goal_task]) do |form| %>
<div class="form-group col-md-10 col-md-offset-1">
<%= render 'layouts/errors', object: #goal_task %>
<div class="form-group col-md-12" id="date-container">
<%= render partial: "goal_tasks/set_due_date", locals: { task: #goal_task, form: form } %>
</div>
<div class="form-group col-md-12">
<%= form.submit class:"btn btn-success", value: "Edit Task" %>
</div>
</div>
<% end %>
routes:
resources :goals do
resources :goal_tasks do
member do
get :set_task_due_date
end
end
_set_due_date.html.erb:
<% if local_assigns[:date] %>
<%= form.hidden_field :taskduedate, value: date %>
<% elsif local_assigns[:due_date] %>
<div class="control-label col-sm-3">
<%= form.label :taskduedate, "Task due:" %>
</div>
<div class="col-sm-9 form-align-left">
<%= form.date_select(:taskduedate, selected: due_date) %>
</div>
<% elsif task.taskduedate.present? %>
<div class="control-label col-sm-3">
<%= form.label :taskduedate, "Task due:" %>
</div>
<div class="col-sm-9 form-align-left">
<%= form.date_select :taskduedate %>
</div>
<% else %>
<div class="control-label col-sm-3">
<%= form.label :taskduedate, "When is your task due? " %>
</div>
<div class="col-sm-9 form-align-left">
<%= form.date_select :taskduedate %>
</div>
<% end %>
<span class="p-4">
<%= link_to "Today", set_task_due_date_goal_goal_task_path(task.goal, task, :due_date => Date.today), remote: true %> |
<%= link_to "Next week", set_task_due_date_goal_goal_task_path(task.goal, task, :due_date => Date.today + 7.days), remote: true %> |
<%= link_to "Two weeks", set_task_due_date_goal_goal_task_path(task.goal, task, :due_date => Date.today + 14.days), remote: true %>
</span>
set_task_due_date.js.erb:
$("#date-container").html(" <%= j render partial: "goal_tasks/set_due_date", locals: { task: #goal_task, form: form } %>");
controller:
def set_task_due_date
due_date = params[:due_date]
respond_to do |format|
format.js
end
end
The solution, thanks to Muhammad Abdullah Khalil via a Rails slack channel is that I had to declare the form inside of the partial.

Submitting two forms in Rails sharing a same param

I have a form like that:
<%= form_for #report do |f| %>
<div class="row">
<div class="col-sm-9">
<h3 class="page-header">
Children
</h3>
<div class="row">
<% students.each do |student| %>
<div class="col-xs-4 col-md-2">
<div class="std_container">
<%= check_box_tag "student_ids[]", student.id, nil, {id: "check_#{student.id}", class: "student_check"} %>
<%= label_tag "check_#{student.id}" do %>
<div class="std_label"><%= student.name %></div>
<div class="std_img thumbnail"><img src="http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg" alt=""></div>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
<%= render "form_categories", f: f, report_notes: #report.report_notes %>
<%= render "messages/form", ????? %>
</div>
</div>
</div>
<% end %>
And I need to render these two partials on the bottom. The 'messages' partial is a form that responds to a different controller but needs to use the "student_ids[]" parameter present on the #report form together with its own parameters. This partial is:
<%= form_for #message do |f| %>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<%= f.hidden_field :professor_id, :value => current_user.professor.id %>
<%= f.label :text, "Texto" %>
<%= f.text_area :text %>
<%= f.submit "Enviar", class: "btn btn-default" %>
</div>
</div>
<% end %>
How do build this "messages" partial in a way that I can use the "student_ids[]" and submit it to its controller?
It is not possible. I solved this problem by using javascript.

Rails show error message of another model

I have a html partial that displays errors:
shared/model_errors.html.erb
<% model.errors.full_messages.each do |msg| %>
and I render it at top of each html file like
<%= render partial: 'shared/model_errors',locals: {model: #model_to_check_errors}%>
This is working fine for most of them.
Let's say that I'm on the show.html.erb template of the ConversationsController, and I have there a form_tag which submits messages to the MessagesController. If the submitted message is empty, the MessagesController won't allow it to be saved, because it has validation errors. How do I display those validations errors in my show.html.erb, considering I don't have access to the #message object of the create action of the MessagesController. Is there any way to add the error message to the ConversationsController? They will be displayed that way.
Edit:
show.html.erb of the ConversationsController
<div class="container nav_exp">
<%= render partial: 'shared/model_errors',locals: {model: #???}%>
<div class="ch-body">
<div class="col-md-12 bg-white ">
<div class="chat-message">
<ul class="chat" id="messages">
<% if #messages != nil %>
<%= render partial: 'conv_message', collection: #messages,:as => :message%>
<% else %>
<div class="panel-body hidden"></div>
<%end%>
</ul>
</div>
<%=form_tag(messages_path, :method=>'post',authenticity_token: true,remote: true) do%>
<div class="chat-box bg-white">
<div class="input-group">
<%= text_field_tag :body,"", id:"message_body",class: "form-control border no-shadow no-rounded", placeholder: "Type your message here"%>
<%= hidden_field_tag :conversation_id, #conversation.id %>
<%= hidden_field_tag :receiver, #other.id %>
<span class="input-group-btn">
<%= submit_tag 'Submit', class: "btn btn-success no-rounded" %>
</span>
</div><!-- /input-group -->
</div>
<% end %>
</div>
</div>
</div>
The create method of the MessagesController - messages_path
def create
message = Message.new(message_params)
message.user = current_user
if message.save
...
else
puts 'not working'
'I think 1 solution would be to add here flash messsages'
end
end
private
def message_params
params.permit(:body, :conversation_id, :receiver)
end

how to refresh a partial after an edit has been made in rails

I am making an ecommerce website page.It consists of two parts.A sidebar having a list of all products and a right column where the details of the product is shown once the product is selected from the list.
I am making ajax calls to load the various partials of the application. The sidebar having all the products is index,the one on right having the details of products is show which shows the details of the product selected.
Now when I edit the product(through a modal) how do I automatically reload the respective partials so that the new changes are reflecte.For me to see the changes I have to refresh the pages currently,how do i ensure the partials are automatically loaded once I click submit on the edit modal.
My index.html.erb looks like
<div class="container">
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-4 sidebar-offcanvas" id="sidebar" role="navigation">
<div class="well sidebar-nav">
<ul class="nav">
<div class="jumbotron well">
<h3>Product Listing Application</h3>
</div>
<%= link_to "New Product", new_product_path, remote: true, class: "btn btn-primary" %>
<div class="list-group">
<%= render "index" %>
</div>
</ul>
</div><!--/.well -->
</div><!--/span-->
<div class="col-xs-10 col-sm-8">
<div id="page-content-wrapper">
<div class="page-content">
<div class="col-md-12 product-info" id="product-details">
</div>
</div>
</div>
<div id="product-modal" class="modal fade"></div>
</div>
</div><!--/row-->
</div>
My _index.html.erb is
<% #products.each do |product| %>
<%= link_to product_path(product), remote: true, class: "list-group-item" do %>
<h4 class="list-group-item-heading"><%= product.name %></h4>
<p class="list-group-item-text"><%= number_to_currency product.price %></p>
<% end %>
<% end %>
My _edit.html.erb is
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3><%= "Editing #{#product.name}" %></h3>
</div>
<%= render "form" %>
</div>
</div>
My _form.html.erb is
<%= form_for #product, remote: true, html: { class: "form-horizontal", style: "display:inline;" } do |f| %>
<div class="modal-body">
<ul class="errors"></ul>
<div class="control-group">
<%= f.label :name, class:"control-label" %>
<div class="controls">
<%= f.text_field :name %>
</div>
</div>
<div class="control-group">
<%= f.label :price, class: "control-label" %>
<div class="controls">
<%= f.text_field :price %>
</div>
</div>
</div>
<div class="modal-footer">
<%= f.submit class: "btn btn-primary" %>
<%= link_to "Cancel", "#", class: "btn", data: {dismiss: "modal"} %>
</div>
<% end %>
You can use
location.reload();
on your js.erb for refresh your partial, or for your instance vaiable
you can directly use
#post = #post.reload # in palce of #post you can your instance variable
create a js file same name as your page
add below code in it
edit.js.erb
$("<%= escape_javascript render(:partial => 'ur_partial_page_name') %>").dialog();
$('#new_comment_link').hide();`
in your edit page form where u r calling modal dialog
<%= link_to "edit", edit_product_path (#product, :format => :js), :remote => true %>
In your product controller
def edit
#source = Product.find(params[:id])
respond_to do |format|
format.html # edit.html.erb
format.xml { render :xml => #product }
format.js
end
end
and in your partial form
<%= form_for (#product, :remote => true) do |f| %>

Submit button does not work unless I refresh the page form_for Rails

I have an app that has a problem model and when I go to create a record the submit button does nothing. No errors given it just simply doesnt execute, unless I refresh the page and attempt add it again. The same happens when I go to update a record.
Here is my controller
class ProblemsController < ApplicationController
include Concerns::Votes
def index
#problems = Problem.all
end
def show
#problem = find_problem
end
def new
#problem = Problem.new
end
def edit
#problem = find_problem
end
def create
#problem = current_user.problems.new(problem_params)
#problem.save
redirect_to #problem
end
def update
#problem = find_problem
if #problem.update_attributes(problem_params)
redirect_to #problem
else
redirect_to #problem
end
end
private
def find_problem
#problem = Problem.find(params[:id])
end
def problem_params
params.require(:problem).permit(:name, :description, :url)
end
end
Here is my _form.html.erb partial that I am rendering on new.html
<div class="row">
<div class="large-12 columns">
<%= form_for #problem do |f| %>
<label>Name</label>
<%= f.text_field :name, placeholder: "Name your problem!" %>
</div>
<div class="large-8 columns">
<%= f.text_field :url, placeholder: "Link to any supporting material" %>
</div>
<div class="large-12 columns">
<%= f.text_area :description %>
</div>
<div class="large-12 columns">
<%= f.submit "Create" %>
</div>
</div>
<% end %>
I have resources :problems in my routes.
Here for good measure is my show.html.erb as well.
<%= div_for #problem do %>
<%= link_to 'Edit', edit_problem_path(#problem) %>
<h2><%= #problem.name %> (<%= #problem.cached_votes_score %>)</h2>
<a =href"<%= #problem.url %>"><%= #problem.url %></a>
<p><%= #problem.description %><p>
By <%= #problem.user.name %></br>
<a class="button"<%= link_to 'Up', {:controller => 'problems', :action => 'up_vote'}, {:method => :post } %></a>
<a class="button"<%= link_to 'Down', {:controller => 'problems', :action => 'down_vote'}, {:method => :post } %></a>
<%= link_to 'Edit', edit_problem_path(#problem) %> |
<%= link_to 'Back', problem_path %>
<% end %>
Here is my index.html.erb
<div class="row">
<div class="large-12 columns">
<% #problems.each do |problem| %>
<h1><small><%= problem.cached_votes_score %></small> <%= link_to problem.name, problem %></h1>
<% end %>
</div>
<%= link_to 'New Problem', new_problem_path %>
</div>
I really cant understand why it works if i refresh the page but otherwise it doesnt work at all.
Your HTML is invalid, the submit button is actually not nested under the form tag. Try changing your view code to this:
<div class="row">
<div class="large-12 columns">
<%= form_for #problem do |f| %>
<label>Name</label>
<%= f.text_field :name, placeholder: "Name your problem!" %>
<div class="large-8 columns">
<%= f.text_field :url, placeholder: "Link to any supporting material" %>
</div>
<div class="large-12 columns">
<%= f.text_area :description %>
</div>
<div class="large-12 columns">
<%= f.submit "Create" %>
</div>
<% end %>
</div>
</div>
I had same issue
Before
<%= simple_form_for(:schedule_list, url: schedulelists_create_with_block_path, :html => { novalidate: false}) do |f| %>
<div class="row">
<div class="col-md-12">
<%= f.button :submit, class: 'pull-right' %>
<%end%>
</div>
</div>
After
<%= simple_form_for(:schedule_list, url: schedulelists_create_with_block_path, :html => { novalidate: false}) do |f| %>
<div class="row">
<div class="col-md-12">
<%= f.button :submit, class: 'pull-right' %>
</div>
</div>
<%end%>

Resources