I want to update Item that are stored in my DB with one click.
For example i have model called Car. It has attribute called "active" which is Boolean so could be 0 or 1 in DB. I want that users have a possibility to change this this attribute with one click for example from index page of their cars. I know that it could be done if i would make this button like the whole form. But i think it is not the best solution and not right. Could i make it in any another way, maybe create special link_to or something like this?
As i understand it should send request to CarsController into update method, but how to do this without form?
You simply need to use link_to with remote: true.
For example in your view:
link_to "Activate", car_path(#car.id), method: :post, remote: true
And in your controller method:
def active
#car = Car.find(params[:id])
#car.update(active: true)
render json: :ok
end
A complete guide present here.
If you are using jquery, you can use jquery ajax method with dataType as JSON.
And you can also use the same restful update method i.e without creating any new method.
View -
<%= button_tag 'Activate', car_id: "22" , id: "activate_car" %>
Controller -
def update
#car = Car.find(params[:id])
respond_to do |format|
if #car.update(car_params)
format.html { redirect_to #car, notice: 'Car was successfully updated.' }
format.json { render :json: 'Successfully update' }
else
format.html { render :edit }
format.json { render json: #car.errors }
end
end
end
private
def car_params
params.require(:car).permit(:active)
end
JS -
$(document).on("click", '#activate_car', function () {
car_id = $(this).attr('car_id')
$.ajax({
url: "/cars/" + car_id,
type: "PUT",
data: {
active: true
},
dataType: "json",
success: function (response) {
alert(response)
}
});
});
I know I'm late but adding this answer for new rails developers
You simply need to use link_to with remote: true. If link_to throws routing error then use button_to instead
For example in your view:
button_to "Activate", car_path(#car.id), method: :patch, remote: true
And in your controller method:
def active
#car = Car.find(params[:id])
#car.update(active: true)
redirect_to cars_path(#cars), status: :see_other
end
And in your routes.rb :
resources :cars do
member do
patch :active
end
end
Related
I have created an app, where I require a form to be submitted remotely. If the form does not pass validation, errors need to be displayed. If it is submitted successfully, the for should be cleared. I am using the Reform gem to strip validation logic out of my models.
I have installed the client_side_validations as well as client_side_validations-simple_form gems as per the installation instructions. For some reason though, validation errors are not displaying and I'm not sure why... I've tried all the debugging options I could think of.
Here is my code:
foo_form.rb
class FooForm < ApplicationForm
property :bar, validates: {
presence: true
},client_validations: { class: 'Foo' }
end
foos_controller.rb
def create
#foo = FooForm.new( Foo.new )
respond_to do |format|
if #foo.validate(params[ :foo ])
#foo.save
format.html { redirect_to root_path }
format.json { render :show, status: :created, location: #foo.model }
else
format.html { render :new }
format.json { render json: #foo.errors, status: :unprocessable_entity }
end
end
end
form.haml
= simple_form_for #foo, url: foos_path, as: :foo, remote: true, validate: true do |f|
.input-field
= f.input :bar
.right-align.card-button
= f.button :submit, class: "waves-light blue", data: { disable_with: "Loading..." }
Could anybody help with identifying what I'm missing? Thanks
i have been trying this from long time but not getting what is the mistake that i am doing,
here is my controller
class UsersController < ApplicationController
puts "before"
def create
puts "hiiiiiiiiiiiiiiiiii"
puts params
User.create(:birthday=> params["dateOfBirth"],:email=> params["emailId"])
end
puts "after"
end
and here is my routes
post '/sign_up', :to => "users#create"
this is giving me a 200 OK response code but not actually entering into the method "create" and storing the values in databse
it is priting "before" and "after" but not "hiiiiii"
looks like i am doing some silly mistake but need help to get it done
thanks.!
This is how i am doing query from client side.
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
}
});
var registration = function(){
var user = {
firstname : $("#firstname").val(),
lastname : $("#lastname").val(),
emailId : $("#email").val(),
password : $("#psw").val(),
dateOfBirth : $("#birthday").val() };
$.post("/sign_up", user, function(data){
console.log(data);
},'json');
};
For really good debug pupposes use gem rails-pry. Add gem 'pry-rails' to your gemfile, run 'bundle install'. Now you can add 'binding.pry' to any place of your code, and when your app reach this line you will have a full access to this code from console. It's better than use 'puts'.
For your In you case it would be:
class UsersController < ApplicationController
puts "before"
def create
binding.pry
User.create(:birthday=> params["dateOfBirth"],:email=> params["emailId"])
end
puts "after"
end
Run application, open your browser and go to url. Than open console and you will be 'inside' create action
UPDATE
Look at my example, I've created it and all works good
Model: User.rb
class User < ActiveRecord::Base
attr_accessible :city, :email, :gender, :name
end
Controller: UsersController.rb
def create
binding.pry
#user = User.new(params[:user])
session[:user] = #user
respond_to do |format|
if #user.save
format.html { redirect_to users_path, notice: 'User was successfully created.' }
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
users.js:
$(function() {
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
}
});
var registration = function(){
alert('a');
var user = {
name : $("#name").val(),
city : $("#city").val(),
gender : $("#gender").val()
};
$.post("/sign_up", user, function(data){
console.log(data);
},'json');
}
$('#but').click(registration);
});
new.html.erb:
<form>
<input id="name">
<input id="city">
</form>
<button id="but">create</but>
routes.rb:
resources :users
post '/sign_up', :to => "users#create"
root :to => 'users#new'
I run application, fill form, open console -> I'm in create action
When the checkbox is ticked, I just want to update the 'Needed'value in the database.
And the script is list below
$('td div').find('input[type=checkbox]').click(function(){
$.ajax({
type: "PUT",
dataType: "script",
url: '/ecs/2',
contentType: 'application/json',
data: JSON.stringify({ ecs:{needed:'N'}, _method:'put' })
}).done(function( msg )
{
alert( "Data Saved: " + msg );
});
});
});
and the controller's code is standard.
# PATCH/PUT /ecs/1
# PATCH/PUT /ecs/1.json
def update
respond_to do |format|
if #ec.update(ec_params)
format.html { redirect_to #ec, notice: 'Ec was successfully updated.' }
format.json { head :no_content }
format.js
else
format.html { render action: 'edit' }
format.json { render json: #ec.errors, status: :unprocessable_entity }
format.js
end
end
end
The EC is the module's name, needed is the column's name. I just want to update a new value in the needed of ec with id=2 .
But right now, I always encountered the BAD REQUEST.
I'm not sure where is the problem.
for your checkbox (make it unobtrusive, it is just a quick example):
... onclick="$.post('/url', {omg_it_is_checked: $(this).attr('checked')})"
in routes.rb:
post '/url' => 'my_controller#my_action'
in controller:
def my_action
#....
#var = some.actions.here.with(params[:omg_it_is_checked]) #or update what you need
respond_to do |format|
format.js{render layout: false}
end
end
than you have to have an appropriate view my_action.js.erb with something like this:
$('#my_uniq_dom_id').html('<%= j render partial: 'new_piece_of_html' %>') #you can render nothing or flash something
and last we need is _new_piece_of_html.html.erb:
<div id="new_ajaxed_content"><%= #var %></div> <!-- or you can render checked checkbox, even with animation, or error message if in some reason it was not saved -->
voila! div#my_uniq_dom_id is updated with div#new_ajaxed_content after controller action
completely different approach - use this gem. it is simple solution for simple needs
cheers!
Rails newbe here. I've got links that do ajax query to server:
<%= link_to g.name, g, :class => 'link link-to-gallery', :remote => true %>
JS view that loads data from partial:
$('#content').html('<%= escape_javascript render("layouts/galleries/show") %>');
And controller that operates with models and renders html and js:
class GalleriesController < ApplicationController
def show
#galleries = Gallery.all
#gallery_to_show = Gallery.find(params[:id])
respond_to do |format|
format.html
format.js
end
end
end
Ajax works fine, but I try to put callback after ajax completed:
jQuery(function() {
$(".link-to-gallery").bind("ajax:complete", function() {
alert(1)
});
});
and alert never shows. What am I doing wrong? Rails version is 3.2.11, Ruby version is 1.9.3p194
Update: When I'm using this code
jQuery(function() {
$(".link-to-gallery")
.on("ajax:before", function () {
alert("before")
})
.on("ajax:complete", function() {
alert("complete")
});
});
"before" alert fires but only once. If I press again I gain nothing. But ajax still works.
I think the problem is with your controller method that is not responding the async call with a success status message, 200.
Try this
def show
#galleries = Gallery.all
#gallery_to_show = Gallery.find(params[:id])
respond_to do |format|
format.html { :status => 200 }
format.js { :status => 200 }
end
end
If that doesn't work, try this.
def show
#galleries = Gallery.all
#gallery_to_show = Gallery.find(params[:id])
respond_to do |format|
format.html { :status => :ok }
format.js { :status => :ok }
end
end
It seems that I'm lame but smart enough to fix this. I had these links:
<%= link_to g.name, g, :class => 'link link-to-gallery', :remote => true %>
in the partial which gets re-rendered after ajax. So the callback functions that were attached to these links were flushed away after ajax. So I put link out of this partial and it works now.
using http://blog.bernatfarrero.com/in-place-editing-with-javascript-jquery-and-rails-3/
The gem uses json to update, but how can I trigger my update.js.erb to update the different parts of my pages?
EDIT
Using this in an invoice page. every item in the invoice has a price field that can be updated with best_in_place.
I need to update the Total Price for line item and amount due for invoice only after field has been updated successfully.
Ended up with something like:
respond_to do |format|
if #item.update_attributes(params[:item])
format.html { redirect_to order_url(#item.order_id), :notice => "Successfully updated item." }
format.js { }
format.json { head :ok }
Edited best_in_place.js line #175
loadSuccessCallback : function(data) {
this.element.html(data[this.objectName]);
// Binding back after being clicked
$(this.activator).bind('click', {editor: this}, this.clickHandler);
if(this.objectName == "item") $.getScript('update.js'); // If its an item, call update.js.erb
},
I wanted to do the exact same thing with best_in_place pcasa. In the current version (1.0.2), the loadSuccessCallback function triggers an ajax:success event. That allows you to do this in your application.js:
$('.best_in_place')
.best_in_place()
.bind('ajax:success', function(e) {
// do your post-json call magic
});
You don't need a view update.js.erb. As ezkl already pointed out, you need to set the respond_to of your controller to json. In addition, you need to activate best-in-place in your public/javascripts/application.js
$(document).ready(function() {
jQuery(".best_in_place").best_in_place()
});
and add it in your view:
<td><%= best_in_place task, :name, :type => :input, :nil => "Click to edit" %></td>
I have a tutorial on Ajax with Prototype and JQuery on my own site - and the JQuery Part uses best-in-place: http://www.communityguides.eu/articles/15
Have you tried something along the lines of:
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to(#user, :notice => 'User was successfully updated.') }
format.json { head :ok }
format.js
else
format.html { render :action => "edit" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
I haven't tested this with the code in the tutorial, but the idea is that you have to tell the controller method to load the Javascript file. I'm not sure how this will interact with the redirect, but the principle is correct.