I have some javascript that displays some data from my database on my webpage. I also have a button that when the user clicks it some logic occurs in the controllers and then I want to have the data displayed changed. However, at the momment when they click the button nothing happens (page is not reloaded). Could you guys help me set that up? Here is what I have so far:
controller:
class QtlsController < ApplicationController
require 'json'
require 'uri'
$rollback = nil
def index
logger.debug "\nrollback is: #{$rollback}\n"
render "index"
end
def rollback
$rollback = params[:version].gsub(/"/,'')
redirect_to :action => :index
end
end
view:
<%- if $rollback.nil? %>
generates one type of table
<%- else %>
generates another type of table
<%- end %>
...some other logic and buttons etc...
jQuery(function() {
jQuery( "#rollback").button();
jQuery( "#rollback").click(function() {
var version = getSelectedText('version_selector');
jQuery.ajax({
type: "POST",
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': jQuery('meta[name="csrftoken"]').attr('content')
},
url: "/qtls/rollback",
data: {version: JSON.stringify(version) },
dataType: 'json',
sucess: function() { alert("Success! Rollbacked"); }
});
});
Here is what is in log files when I go to the page and when I click the rollback button:
Started GET "/qtls" for 10.64.229.59 at Tue Jul 17 16:48:52 -0500 2012
Processing by QtlsController#index as HTML
rollback is:
ROLLBACK IS NIL!!!
Qtl Load (2.0ms) SELECT `qtls`.* FROM `qtls`
Rendered qtls/index.html.erb within layouts/application (404.8ms)
Rendered shared/_user_nav.html.erb (1.3ms)
Rendered shared/_nav.html.erb (1.3ms)
Rendered shared/_footer.html.erb (0.6ms)
Completed 200 OK in 544ms (Views: 540.9ms | ActiveRecord: 2.0ms)
Started POST "/qtls/rollback" for 10.64.229.59 at Tue Jul 17 16:48:57 -0500 2012
Processing by QtlsController#rollback as JSON
Parameters: {"version"=>"\"test1\""}
Redirected to http://10.10.136.244:4000/qtls
Completed 302 Found in 3ms (ActiveRecord: 0.0ms)
Started GET "/qtls" for 10.64.229.59 at Tue Jul 17 16:48:58 -0500 2012
Processing by QtlsController#index as JSON
rollback is: test1
Rendered qtls/index.html.erb within layouts/application (37.7ms)
Rendered shared/_user_nav.html.erb (3.3ms)
Rendered shared/_nav.html.erb (4.3ms)
Rendered shared/_footer.html.erb (2.0ms)
Completed 200 OK in 99ms (Views: 97.4ms | ActiveRecord: 0.0ms)
it's a reaaaaaally bad style to use global variables like $rollback!
if you want to store user-data use your session-object.
use the jquery-rails gem to integrate with jQuery in your views and then use the :remote => :true in your form, so that rails can handle the form-submission.
Related
I have found many generic posts suggesting this has to do with redirects. I believe this may be due to how I have a form set up.
On the plans.html.erb page I have a form with four submits, each going to the same place with different params:
<%= form_with url: :affiliate_select_plan, class: "mx-auto" do |f| %>
<!-- Paid Plans -->
<% #plans.each_with_index do |plan, i| %>
<%= f.button 'Select Plan', value: plan[:name], type: 'submit' %>
<% end %>
<% end %>
I have the affiliate_select_plan_path setup in my routes.rb:
devise_scope :affiliate do
post 'affiliate/select_plan', :to => 'affiliates/registrations#select_plan'
end
The form successfully hits the select_plan method in the controller, which redirects it to the new_affiliate_registration_path, passing the needed params.
def select_plan
redirect_to new_affiliate_registration_path(plan: plan_params[:button])
end
The new method in the controller is called, directing the user to the sign up page:
# GET /resource/sign_up
def new
#plan = AffiliatePlan.find_by(nickname: params.permit(:plan)[:plan].downcase)
super
end
From this page, if the back button on the browser is selected, it will bring the user back to the page they were at before being at plans.html.erb.
Could this be related to the redirect_to?
EDIT:
Here are the logs:
Started GET "/" for 127.0.0.1 at 2020-02-25 19:06:02 -0500
Processing by Affiliates::RegistrationsController#plans as HTML
Rendering affiliates/registrations/plans.html.erb within layouts/application
Rendered affiliates/registrations/plans.html.erb within layouts/application (5.2ms)
Rendered layouts/_google_analytics.html.erb (0.5ms)
[Webpacker] Everything's up-to-date. Nothing to do
Rendered layouts/_header.html.erb (1.2ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 195ms (Views: 194.2ms | ActiveRecord: 0.0ms)
Started POST "/partner/select_plan" for 127.0.0.1 at 2020-02-25 19:06:13 -0500
Processing by Affiliates::RegistrationsController#select_plan as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Ck8HGRryriXleQrUjCSKjTrIRLIw273EdSu4WZnFn3kAL1mMmk7jqR1tZgnPniHsMzHFMl81vPBRuvA0/W4uSw==", "button"=>"Local"}
Unpermitted parameters: :utf8, :authenticity_token
Redirected to http://localhost:3000/partners/sign_up?plan=Local
Completed 200 OK in 1ms (ActiveRecord: 0.0ms)
Started GET "/partners/sign_up?plan=Local" for 127.0.0.1 at 2020-02-25 19:06:13 -0500
Processing by Affiliates::RegistrationsController#new as HTML
Parameters: {"plan"=>"Local"}
AffiliatePlan Load (1.2ms) SELECT "affiliate_plans".* FROM "affiliate_plans" WHERE "affiliate_plans"."nickname" = $1 LIMIT $2 [["nickname", "local"], ["LIMIT", 1]]
↳ app/controllers/affiliates/registrations_controller.rb:11
Rendering affiliates/registrations/new.html.erb within layouts/application
Rendered affiliates/registrations/new.html.erb within layouts/application (4.6ms)
Rendered layouts/_google_analytics.html.erb (1.1ms)
[Webpacker] Everything's up-to-date. Nothing to do
Rendered layouts/_header.html.erb (1.2ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 191ms (Views: 187.6ms | ActiveRecord: 1.2ms)
I have a hunch that this might have to do with form resubmission: Forms and the back button tend to be a bit wonky at times.
However, instead of going more in depth with this, let me point you in another direction. I'm doing this because to me, this looks like a classic case of someone trying to find a solution to the wrong problem. I'm saying this because based on the code and log snippets you've provided, you're jumping through hoops to pass a parameter (in your case the name of a plan) via multiple actions – which, if I'm right, is just unnecessary.
Here's what I would do instead:
<% #plans.each do |plan| %>
<%=
link_to 'Select Plan',
new_affiliate_registration_path(plan: plan.downcase),
class: 'some-button-class
%>
<% end %>
This way, you don't have to mess around in your controllers in any way. Also, since there is no POST request, you won't have any issues with form (re)population and such things.
Only on Rails 6 when:
I receives a json response on pages with url like:
www.site.com/foo
and not when url is like:
www.site.com/foo?q=x
to reproduce:
rails new todo
rails scaffold Todo task:string
rails db:migrate
rails server
Create a task
In file show.json.jbuilder you'll see:
json.partial! "todos/todo", todo: #todo
Go to show page (todo/1)
Type on browser's console to se json response:
$.ajax({
url: window.location.href + ".json",
dataType: 'json',
async: false
});
When your url is "todo/1" jbuilder loads ok:
Started GET "/todos/1.json" for ::1 at 2019-10-28 13:55:54 -0300
Processing by TodosController#show as JSON
Parameters: {"id"=>"1"}
Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/todos_controller.rb:67:in `set_todo'
Rendering todos/show.json.jbuilder
Rendered todos/_todo.json.jbuilder (Duration: 1.0ms | Allocations: 125)
Rendered todos/show.json.jbuilder (Duration: 2.2ms | Allocations: 306)
Completed 200 OK in 10ms (Views: 3.9ms | ActiveRecord: 0.3ms | Allocations: 1565)
But if your url is "todo/1?q=foo" you have no data:
Started GET "/todos/1?q=foo.json" for ::1 at 2019-10-28 13:55:44 -0300
Processing by TodosController#show as JSON
Parameters: {"q"=>"foo.json", "id"=>"1"}
Todo Load (0.2ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/todos_controller.rb:67:in `set_todo'
Rendering todos/show.html.erb within layouts/application
Rendered todos/show.html.erb within layouts/application (Duration: 0.7ms | Allocations: 89)
Completed 200 OK in 25ms (Views: 21.3ms | ActiveRecord: 0.2ms | Allocations: 6547)
Obs: I opened this rails github issue
In order to work in rails 6.0.0 we need to explicitly tell to use json format when the url has queries:
todos_controller.rb
change from:
def show
end
to:
def show
respond_to do |format|
format.html
format.json
end
end
This is because the request must be in the following form:
www.site.com/foo.json?q=x
If you want to pass parameters to the request, you can use the data parameter of ajax.
For instance:
$.ajax({
url: "/todos",
type: "GET",
data: {
id: 1,
q: "x"
},
success: function (response) {
console.log(response.data)
}
})
If I have a url like localhost:3000?id=2 what do I need to change to get my AJAX call to use the param?
page_controller.rb
class PageController < ApplicationController
def index
#pId = params[:id]
#p = Plant.where(id: #pId)
respond_to do |format|
format.json { render json: #p.to_json }
format.html
end
end
end
page.coffee
$ ->
$.ajax
dataType: 'json'
url: 'index.json'
success: (data) ->
alert "Data #{JSON.parse(data)} ---"
development.log for one page load
Processing by PageController#index as HTML
Parameters: {"id"=>"2"}
Rendering page/index.html.erb within layouts/application
[1m[36mPlant Load (1.0ms)[0m [1m[34mSELECT "plants".* FROM "plants" WHERE "plants"."id" = $1[0m [["id", 2]]
Rendered page/index.html.erb within layouts/application (3.0ms)
Completed 200 OK in 80ms (Views: 69.5ms | ActiveRecord: 1.0ms)
Started GET "/index.json" for ::1 at 2017-01-26 08:07:18 -0800
Processing by PageController#index as JSON
[1m[36mPlant Load (1.0ms)[0m [1m[34mSELECT "plants".* FROM "plants" WHERE "plants"."id" IS NULL[0m
Completed 200 OK in 5ms (Views: 0.1ms | ActiveRecord: 1.0ms)
This is just a very basic example taken from a much more complicated piece of code. Everything in my original code works except for when I'm trying to access to param.
update 1
routes.rb
Rails.application.routes.draw do
get 'index' => 'page#index'
root "page#index"
end
Your URI for the Ajax request doesn't include the parameter. You're making a call to index.json and not index.json?id=1
I have an HTML table that displays order items. On each table row I have a "Need By Date" field that is standalone(not in a form) input field. Whenever a user changes the date, I post this date to the server to save it against the order.
I am noticing that when I use OrderItem.update or OrderItem.update_attributes from the rails console it works, but when it is triggered from a field change event Rails does not trigger an update to the table.
#JavaScript
$(".order-item.datepicker").change ->
needby_date = $(this).val()
order_item_url = $(this).data("order-item-url")
$.ajax
type: "POST"
url: order_item_url
data:
needby_date: needby_date
My controller -
def update_needby_date
#order_item = OrderItem.find(params[:order_item_id])
#order_item.update_attribute(update_needby_date_params)
respond_to do |format|
format.js { render :nothing => true }
end
end
private
def update_needby_date_params
params.permit(:order_item_id, :needby_date)
end
As you can see in the log file, the update is not being triggered -
Started POST "/order_items/1/update_needby_date" for 127.0.0.1 at 2014-07-08 10:55:10 -0400
Processing by OrderItemsController#update_needby_date as */*
Parameters: {"needby_date"=>"07/23/2014", "order_item_id"=>"1"}
OrderItem Load (0.4ms) SELECT "order_items".* FROM "order_items" WHERE "order_items"."id" = ? LIMIT 1 [["id", "1"]]
(0.4ms) begin transaction
(0.2ms) commit transaction
Rendered text template (0.1ms)
Completed 200 OK in 16ms (Views: 3.3ms | ActiveRecord: 1.0ms)
I'm unable to pass a variable to my controller using the data parameter of an AJAX call. What am I doing wrong?
show.html.erb
var parentStepID = 20;
$.ajax({
url: "/steps/create_branch",
type: 'GET',
data: {parent: parentStepID}
});
controller
def create_branch
parentStepID = params[:parent]
logger.debug("parentStepID: #{parentStepID}")
respond_to do |format|
format.js
end
end
The logger does not seem to get the parentStepID:
Started GET "/projects/20/steps/create_branch" for 127.0.0.1 at 2013-03-06 11:56:44 -0500
Processing by StepsController#create_branch as HTML
Parameters: {"project_id"=>"20"}
Project Load (0.1ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1 [["id", "20"]]
####################################################################
parentStepID:
Rendered steps/create_branch.js.erb (0.1ms)
Completed 200 OK in 16ms (Views: 10.6ms | ActiveRecord: 0.1ms)
Browser console:
20 0:412
/projects/20/steps/create_branch 0:413
Also, I believe the AJAX request is working properly; I created a file called "create_branch.js.erb"' in my steps views folder and put in an alert that is successfully called.