Rendering from another controller with AJAX - ruby-on-rails

I have query to the db, where I ask for specific entries. This is the controller:
def index
#contributions = Contribution.all
#number1 = params[:number1]
#number2 = params[:number2]
#itemsok = Contribution.where("first_item_id = ?",#number1).where("first_item_grade = ?",#number2)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #contributions }
end
Ok and I have a form in the view wich allows me to pass data from the user input
<%= form_tag(contribution_path, :method => "get") do %>
<%= label_tag(:number1, "First Item Id") %>
<%= text_field_tag(:number1) %>
<%= label_tag(:number1, "First Item Grade") %>
<%= text_field_tag(:number2) %>
<%= submit_tag("Do it!" , :remote => true) %>
<% end %>
That works perfectly, but now I want to render this function from the main page index (display_controller, display index.html.erb). I gave all the properties to the display_controller like this:
class DisplayController < ApplicationController
def index
#items = Item.all
#contributions = Contribution.all
#number1 = params[:number1]
#number2 = params[:number2]
#itemsok = Contribution.where("first_item_id = ?",#number1).where("first_item_grade = ?",#number2)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #contributions }
end
end
end
And I have the same form in the display view that is in the contributions view....
Right now what It does is that it redirects me to the contributions part, what I want t achive is to render the results in the display view...
Any thoughts? Thank you very much.
Sorry for my terrible english.
#
I got it
Got it the answer was to change in view the form to selected action
<%= form_tag(contribution_path, :method => "get") do %>
<%= label_tag(:number1, "First Item Id") %>
<%= text_field_tag(:number1) %>
<%= label_tag(:number1, "First Item Grade") %>
<%= text_field_tag(:number2) %>
<%= submit_tag("Do it!" , :remote => true) %>
<% end %>
Change it to
<%= form_tag(display_path, :method => "get") do %>
<%= label_tag(:number1, "First Item Id") %>
<%= text_field_tag(:number1) %>
<%= label_tag(:number1, "First Item Grade") %>
<%= text_field_tag(:number2) %>
<%= submit_tag("Do it!" , :remote => true) %>
<% end %>
In my case this was not working at the beginning but now I figured that it was because I have my display_path as the root_path so I changed it to...
<%= form_tag(root_path, :method => "get") do %>
<%= label_tag(:number1, "First Item Id") %>
<%= text_field_tag(:number1) %>
<%= label_tag(:number1, "First Item Grade") %>
<%= text_field_tag(:number2) %>
<%= submit_tag("Do it!" , :remote => true) %>
<% end %>
And now it works perfectly.
Can someone change this question to answered, I have like 21 of reputation and can't answer my own question. Tanks.

For better code quelity you should avoid repititions of code and make reusable, move that formm to a common partial view and use :url =>{:action => 'my_action'} in the form tag then you can use it any controller index view. While form action it will take the default controller from which it will be rendered.
share/_form.erb.html
<%= form_tag(:url =>{:action => 'my_action'}, :method => "get") do %>
<%= label_tag(:number1, "First Item Id") %>
<%= text_field_tag(:number1) %>
<%= label_tag(:number1, "First Item Grade") %>
<%= text_field_tag(:number2) %>
<%= submit_tag("Do it!" , :remote => true) %>
<% end %>
and in controller respective index view
index.erb.html
<%= render :partial 'share/form' %>
you can even declare variables for action and controller in your index method like
def index
// do something
#action = 'new_action'
#controller = 'new_controller'
// do some more thing
end
and then in form
:url =>{:controller => #controller, :action => #action}

Related

create.js.erb is called only one time after form submit

I have a simple_form_for in my project. My goal is to alert people when their email is already in database thanks to an alert and ajax to reload the form if there is an error. When I send my form for the first time, I get the good respond from create.js.erb. But if I send the form a second time without reloading the page with the browser, my controller create method code is taken into account but not my create.js.erb code. For example, if I put an alert in the create.js.erb file, it doesn't pop the second time I send the form by clicking on the button again. Can you help me to figure why ?
pages_controller.rb
def create
#email = waiting_list_params[:email]
#waiting_user = WaitingList.new(waiting_list_params)
respond_to do |format|
if #waiting_user.save
UserMailer.welcome(#email).deliver_now
format.html { redirect_to concours_path }
format.js
else
format.html { render 'pages/concours' }
format.js { flash[:error] = #waiting_user.errors.full_messages[0] }
end
end
end
create.js.erb
function refreshForm(innerHTML) {
const newForm = document.getElementById("concours-form");
newForm.innerHTML = innerHTML;
}
<% if #waiting_user.errors.any? %>
refreshForm('<%= j render "pages/concours_form" %>');
confPopup.style.display = "none";
<% else %>
confPopup.style.display = "flex";
<% end %>
_form.html.erb
<%= simple_form_for #waiting_user, {id: 'concours-form', url: concours_path, remote: true} do |f| %>
<%= f.error_notification %>
<%= f.text_field :email,
class: "landing-form-input",
autocomplete: "off",
required: true,
pattern: '[^#]+#[^#]+\.[a-zA-Z]{2,6}',
placeholder: "Renseignez ton email ici"
%>
<i class="fa fa-envelope"></i>
<%= f.hidden_field :concours_city,
value:'',
id: 'c-choosen-city'
%>
<%= f.hidden_field :source,
value: params[:source]
%>
<%= f.button :submit,
class: "landing-form-button",
value: "Je tente ma chance !"
%>
<% end %>
routes.rb
get 'concours', to: 'pages#concours'
post 'concours', to: 'pages#create'

First argument in form cannot contain nil or be empty form_for :method=>"get"

I'm getting an error "First argument in form cannot contain nil or be empty" for
<%= form_for #assessment, :method=>"get", :url => url_for(:action => 'new') do |f| %>
I get the error when re-rendering the :options page after an invalid submission. What's wrong with the way I've set this up?
Step 1: User needs to choose a template and a patient_id in Assessment#Options
def options
#assessment = current_user.assessments.new
#patients = current_user.patients.sort_by{|e| e.first_name.downcase}
#patient = current_user.patients.new
#templates = Template.all
end
Assessment#options view:
<%= form_for #assessment, :method=>"get", :url => url_for(:action => 'new') do |f| %>
<% if #assessment.errors.any? %>
<div>
<%= pluralize(#assessment.errors.count, "error") %> prevented the account from being created:
<ul>
<% #assessment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
...
<%= f.submit "Create Assessment", :class => "btn btn-primary", :style=>"width:100%;", :id=>"options-submit" %>
<% end %>
On submit, I GET this action:
def new
if params[:assessment][:template_id].present? && params[:assessment][:patient_id].present?
#assessment = current_user.assessments.new
#assessment.template = Template.find(params[:template_id])
#assessment.patient = current_user.patients.find(params[:patient_id])
else
render :options
end
end
You need #assessment to be instantiated. You can move it outside the condition.
def new
#assessment = current_user.assessments.new
if params[:assessment][:template_id].present? && params[:assessment][:patient_id].present?
#assessment.template = Template.find(params[:template_id])
#assessment.patient = current_user.patients.find(params[:patient_id])
else
render :options
end
end
The line
render :options
does not execute the action options in your controller. It only renders the view using the variables in the new action. As a result none of your instance variables are actually being being set, so your form craps out.
Try moving the stuff in the options method into your if-then loop.

How can I make the input field empty after ajax submit?

I implemented a chat system to my app.
It refreshes the list of comments partially when after new comment was submit.
So new added comment pops up without reloading whole page.
It's working fine but the problem is, it won't make input field empty(initialize) after submit :(
How can I make it empty if it succeeded at submitting?
5 seconds Auto-refreshing will be another issue that's preventing.
So I have to care about it, too.
and If possible I want to pop up flash alert 'you cant spam' when the user tried to submit comment within 10 seconds.
Let's assume as if I'm trying to submit comment from Users#show page
views/users/show.html.erb
<%= javascript_tag do %>
jQuery(document).ready(function () {
refreshPartial();
setInterval(refreshPartial, 5000)
});
function refreshPartial() {
$.ajax({
url: "<%= show_user_path(#user) %>/refresh_part",
type: "GET",
dataType: "script",
});
}
<% end %>
......
<span id="chat">
<%= render 'users/comment' %>
</span>
<%= render 'users/comment_input' %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>PIC</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #comments.each do |comment| %>
<tr id="<%= dom_id(comment) %>">
<td><%= comment.id %></td>
<td>
<% if comment.comment_icon? %>
<ul class="thumbnails">
<%= image_tag(comment.comment_icon.url(:thumb),:height => 100, :width => 100, :style => 'border:3px double #545565;' ) %>
</ul>
<% end %>
</td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>
<%= button_to 'destroy', polymorphic_path([#user, comment]), :data => {:confirm => 'Are you sure?'}, :method => :delete, :disable_with => 'deleting...', :remote => true, :class => 'btn btn-danger' if current_user && current_user.id == comment.user_id %>
</td>
</tr>
<% end %>
</table>
<%= paginate #comments, :window => 4, :outer_window => 5, :left => 2, :right => 2 %>
views/users/_comment_input.html.erb <= This is input form!!!!!
<%=form_for(([#user, #comment]), :remote => true) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments_controller.rb
def create
commentable = #community_topic||#community||#user
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = Comment.build_from(commentable, current_user.try(:id), params[:comment][:body])
#comment.comment_icon = params[:comment][:comment_icon]
if #user
#following_users = #user.all_following(order: 'updated_at DESC')
#followed_users = #user.followers
#communities_user = #user.get_up_voted(Community).order("updated_at ASC").page(params[:page]).per(5)
elsif #community
end
last_comment = Comment.where(:user_id => current_user.id).order("updated_at").last
if last_comment && (Time.now - last_comment.updated_at) <= 10.second
flash[:notice] = "You cannot spam!"
render :template => template_for(commentable)
elsif #comment.save
#if #community_topic.empty?
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = commentable.comment_threads.build
respond_to do |format|
format.html { redirect_to [#community, commentable].uniq, :notice => "comment added!" }
format.js do
if #community.present?
render 'communities/refresh_part'
elsif #community_topic.present?
render 'community_topics/refresh_part'
elsif #user.present?
render 'users/refresh_part'
end
end
end
else
render :template => template_for(commentable)
end
end
views/users/refresh_part.js.erb
$('#chat').html("<%= j(render(:partial => 'users/comment')) %>")
Well I assume this is the "body" input you want to empty so basically, just add an id to it like this :
<%= f.text_field :body, :id => "body_input" %>
And in your views/users/refresh_part.js.erb, you can add something like :
$('#body_input').val('');
This should work only if it succeded at submitting because from what I saw, your template is rendered only if the comment is saved.

Passing parsed variables into different models form

I have a products scaffold set up, and I just created a new foo controller and view. In my foo controller I parse a url, and get back an arry of objects. How can I pass each of these variables into the products form as defaults?
my controller:
require 'net/http'
require 'json'
def index
if params[:commit] == "Add Product"
#productId = params[:q]
#resultsReceived = true
if
url = URI.parse("url" + params[:q].to_s)
#response = JSON.parse(Net::HTTP.get_response(url).body)
end
else
#resultsReceived = false
#response = []
end
respond_to do |format|
format.html
end
end
end
My current index
<%= form_tag("/foo", :method => "get") do %>
<%= label_tag(:q, "Enter Product Number") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Add Product") %>
<% end %>
<% if #resultsReceived == true %>
Title: <%= #response["product"]["title"] %> </br>
ID_Str: <%= #response["product"]["id_str"] %> </br>
Image Url: <%= #response["product"]["image_url"] %> </br>
Base Item Price: <%= #response["product"]["base_item_price"] %> </br>
Current Item Price: <%= #response["product"]["price"] %> </br>
Seller Name: <%= #response["product"]["mp_seller_name"] %> </br>
Description: <%= #response["product"]["descr"] %> </br>
<% end %>
I want the variable above to be passed to my already existing products from.
I think you have to move the access of the other data from your index action to either your your new action, or an action you create 'new_prefilled' possibly. It would helpful if the attributes matched (the stuff you get from the url has the same attribute names as your product model)
i.e.
def new_prefilled
if url = URI.parse("url" + params[:oid].to_s)
#response = JSON.parse(Net::HTTP.get_response(url).body)
end
#product = Product.new(#response['product'])
render 'new'
end
Then you'd have to add a route,
get '/products/new/:oid' => 'products#new_prefilled'
Then in your index action, you would do this:
if params[:commit] == "Add Product"
redirect_to "/products/new/#{params[:q]}"
end
So you would render your new products view, but it would be pre-filled with that data you got from the other site.

Ruby on rails variable AJAX

What I want to do is pass a the value of the fields in the form to the controller so I can make a custom query in the db. I think something is missing but I just can't see what.
This is my controller
def index
#contributions = Contribution.all
#number1 = params[:number1]
#number2 = params[:number2]
#itemsok = Contribution.where("first_item_id = ?",#numer1).where("first_item_grade = ?",#numer2)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #contributions }
end
This is the view
<%= form_tag(contribution_path, :method => "get") do %>
<%= label_tag(:number1, "Number 1:") %>
<%= text_field_tag(:number1) %>
<%= label_tag(:number1, "Number 2:") %>
<%= text_field_tag(:number2) %>
<%= submit_tag("Searcs") %>
<% end %>
And this is the line in the routes.rb
get 'contribution' => 'contributions#index', :as => 'contribution'
Thank you very much.
Add :remote => true to the form tag to make it submit via ajax, and make sure to respond_to format.js in the controller action.
<%= form_tag(contribution_path, :remote => true) %>

Resources