I have an app of reservations. The thing is that admins can view reservations by date. This is done by an input with has appended datepicker. Each time the user picks a date, the view is updated (that's the idea). However, until now I don't know how to update the view with the new data. This are my methods:
def index
#reserva = Reserva.new
#reservas = Reserva.all.joins(:user).where.not(:user_id => session[:user_id])
#mis_reservas = Reserva.where(:user_id => session[:user_id])
end
def actualizar_por_fecha
if params[:fecha] != nil
#mis_reservas = Reserva.find_by_fecha(params[:fecha])
#reservas = Reserva.find_by_fecha(params[:fecha])
respond_to do |format|
format.html { render 'reservas/index' }
end
end
end
And the CoffeeScript code is the following:
$("input#ver_reservas_fecha").on "change", (e) ->
$.ajax
url: "actualizar_lista_de_reservas_por_fecha"
data:
fecha: $("#ver_reservas_fecha").val()
success: (data) ->
console.log(data)
return
return
Thanks in advance
Refer to this question to know how to create a partial and refresh the div after ajax call.
How do I render partial via ajax in rails3 and jQuery
Also refer to this to understand it a bit more
http://richonrails.com/articles/basic-ajax-in-ruby-on-rails
Related
I have new and create actions like this:
def new
#foo = Foo.new
end
def create
#foo = Foo.new(foo_params)
respond_to do |format|
if #foo.save
format.html { redirect_to root_path }
else
format.html { render :new } //**this line I want to send params**
end
end
end
I have a jbuilder file to new action like this:
new.json.jbuilder
json.foo do
json.a "Some important info"
json.b "Some important info"
end
And rails can't read this file after create's validation fails. How to render a view template (like render :new) and send some json data in this view?
I have a js calling like this:
var json_url = window.location.href + ".json";
var foo;
$.ajax({
url: json_url,
dataType: 'json',
async: false,
success: function(data) {
foo = data.foo;
}
});
If you want Rails to render a file, you'll need to remove the call to redirect_to as it will effectively prevent any rendering.
Furthermore, if you don't want the controller to respond to different formats, it's better to skip the call to respond_to, too.
If you just call render action: :new, the view template will have access to all controller instance variables (like #foo):
json.foo do
json.a #foo.a
json.b #foo.b
end
Hey everyone I am having an issue setting up my app. It uses the shopify API and essentially what it does is grab some data via a view and sends it to the controller but I am having issues passing it to another method in the controller to use the API to save the data.
Here is my code :
Controller
class BuilderController < ShopifyApp::AuthenticatedController
def index
urlval = request.fullpath
#urlCheck = urlval.split('/').last
end
def show
url = request.fullpath
#urlID = url.split('/').last
#customers = ShopifyAPI::Customer.search(query: "id:"+ #urlID)
#need to get a way to retrieve the ajax call info here to pass into the update
end
def updateCustomer(notes)
#customers.each do |cus|
cus.note = notes
cus.save()
end
end
def new
notes = params[:notes]
updateCustomer(notes)
render json: notes
end
end
View
<button id="test">TEST</button>
<script>
var butt = document.getElementById('test');
butt.addEventListener("click",function(){
$.ajax({
url: "/builder/new",
type: "GET",
data: {
"notes": [
"test",
"test2"
]
},
success: function(data,text,xhr) {
console.log(text);
console.log(xhr);
console.log(data);
alert('successfully');
},
error: function(data,error){
console.log(data);
console.log(error);
alert("help");
}
});
});
</script>
Rather than a fully separate method, have you looked into the
respond_to method? http://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to
You could do (assuming html is the primary request type, change if it isn't):
def index
respond_to do |format|
format.html { actions }
format.json { actions }
end
end
This the method we use to accommodate different request types within the same action. Please let me know if I've misinterpreted your question.
you can use this
update_all(updates) public
Updates all records with details given if
they match a set of conditions supplied, limits and order can also be
supplied. This method constructs a single SQL UPDATE statement and
sends it straight to the database. It does not instantiate the
involved models and it does not trigger Active Record callbacks or
validations.
http://apidock.com/rails/v4.0.2/ActiveRecord/Relation/update_all
def new
notes = params[:notes]
#customer.update_all({note: notes})
respond_to do |format|
format.html {}
format.json { json: #customer.json }
end
end
In my customer index view if I click on delete customer button, the following actions take place in my Customers controller delete method.
Customers_controller.rb
class CustomersController < ApplicationController
.
.
def destroy
if Customerarticle.where(author_id: params[:id]).count > 0
#####I need the logic here to display a modal window on my index page of customers here#####
else
Customer.find(params[:id]).destroy
flash[:success] = "Customer deleted"
# debugger
redirect_to customers_path
end
So based on my condition if it's true means customer can't be deleted, and that message to be displayed in a modal pop up window on Customers index page itself, how to achieve it ?
I suggest you issue an ajax request when the button was clicked and make it redirect to your destroy action. Then, within the controller do your logic and simply return a true/false (or whatever else you need) and use it in your JS callback.
For example:
In your view.js
$(document).ready(function(){
$("#delete_button").click(function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "/URL/TO/CONTROLLER",
data: { id: someID},
success: function(result){
if(result == true) {
// Do something
} else {
window.location.replace(result);
}
}});
});
});
In your controller:
def destroy
if Customerarticle.where(author_id: params[:id]).count > 0
return true
else
Customer.find(params[:id]).destroy
flash[:success] = "Customer deleted"
return customers_path
end
end
This should work just fine. Remember, it definitely needs some re-work and adjustments :)
Within a rails 4 app, I am using a link_to to send an upvote on posts via json.
Here is what I have in my posts controller:
def upvote
#post = Post.find(params[:id])
#post.liked_by current_user
respond_to do |format|
format.html {redirect_to :back }
format.json { render json: { count: #post.get_upvotes.size } }
end
end
Here is what I have in my view
<%= link_to like_post_path(post), method: :put, class: 'vote', remote: true, data: { type: :json } do %>
<%= image_tag('vote.png') %>
<%= content_tag :span, post.get_upvotes.size %>
<% end %>
<script>
$(document)
.on('ajax:send', '.vote', function () { $(this).addClass('loading'); })
.on('ajax:complete', '.vote', function () { $(this).removeClass('loading'); })
.on('ajax:error', '.vote', function(e, xhr, status, error) { console.log(status); console.log(error); })
.on('ajax:success', '.vote', function (e, data, status, xhr) {
$(this).find("span").html(data.count);
$(this).find("img").attr("src", '<%= asset_path 'voted.png' %>');
});
</script>
When I click on the link, the vote goes through as a JSON request, I see this in my log:
Processing by PostsController#upvote as JSON
But for some reason, my snipped of javascript is not working. Neither the counter or the icon update. How can I fix this? Does this have to do with turbolinks, does it have to do with where I am placing the javascript?
In Rails you can perform a similar task by having a JavaScript response. Add in your respond_to a format.js similar to format.html then have a view upvote.js.erb that looks like:
(function() {
var postId = "#post-<%= #post.id %>";
$(postId).find(".vote").find("span").text("<%= #post.get_upvotes.size %>");
$(postId).find(".vote").find("img").attr("src", "<%= asset_path "voted.png" %>");
})();
I changed your call to .html to .text since you're not actually setting any HTML inside the element, there is no reason to call .html.
This post also assumes there is some mechanism to identify the post the vote link belongs to (in the example the parent post element has an ID of "post-#" where # is the ID of the post object).
EDIT
Two changes I'd make if I were working on this project. First I would attach the voted.png path to the .vote element as a data attribute. data-voted-image-src="<%= asset_path "voted.png" %>". Next, I would never pass a number in the return as there is no reason to do so. When the vote is clicked you can handle everything on the front end by assuming the request is successful. Which saves all this potential nastiness. While I realize that changing from what you current have to adding the data attribute isn't a huge leap I just find it more semantic than having it in the JavaScript.
The click action on the vote link then becomes:
// Assume all posts have a class 'post'
// I'm also using 'one' because once they vote they don't need to anymore
$(".post").find(".vote").one("click", function(e) {
var count = parseInt($(this).find("span").text()),
votedSrc = $(this).data("voted-image-src");
$(this).find("img").attr("src", votedSrc);
$(this).find("span").text(count + 1);
});
Now no response from the server is necessary, and you can change your JSON response to {success: true} or something simple.
jQuery is the default rails javascript library. The default rails javascript library used to be prototype, so old tutorials/docs use it. This is what the ajax looks like with jQuery:
app/controllers/static_pages_controller.rb:
class StaticPagesController < ApplicationController
def show_link
end
def upvote
respond_to do |format|
format.json {render json: {"count" => "10"} }
end
end
end
app/views/static_pages/show_link.html:
<div>Here is an ajax link:</div>
<%= link_to(
"Click me",
'/static_pages/upvote',
'remote' => true, #Submit request with ajax, and put text/javascript on front of Accept header
data: { type: :json }) #Put application/json on front of Accept header
%>
<div>Upvotes:</div>
<div id="upvotes">3</div>
<script>
$(document).ready( function() {
$(this).ajaxSuccess( function(event, jqXHR, ajaxInfo, data) {
//var js_obj = JSON.parse(jqXHR.responseText);
//$('#upvotes').html(js_obj["count"]);
//Apparently, the fourth argument to the handler, data,
//already contains the js_obj created from parsing the
//json string contained in the response.
$('#upvotes').html(data["count"]);
});
});
</script>
config/routes.rb:
Test1::Application.routes.draw do
get 'static_pages/show_link'
get 'static_pages/upvote'
...
end
url to enter in browser:
http://localhost:3000/static_pages/show_link
See jquery docs here:
http://api.jquery.com/ajaxSuccess/
Response to comment:
You could also do the following in your controller:
def upvote
#upvotes = 2 #Set an #variable to the number of upvotes
respond_to do |format|
format.js {} #By default renders app/views/static_pages/upvote.js.erb
end
end
Then:
app/views/static_pages/upvote.js.erb:
$('#upvotes').html(<%= #upvotes %>)
I would like to change a Workorder.wostatus_id based on data in html.
In my index html, I have the wostatus.id stored like this:
<span id="woid">4</span>
I would like to update the workorder.wostatus_id = 4
This is in the workorders.js.coffee - but, it's not working:
$.ajax
type: 'POST'
url: 'http://localhost:5000/workorders'
data:
workorder:
wostatus_id: $("#woid").val()
Maybe I'm not getting to the right workorder record?
Even doing this didn't update the workorder.wostatus_id
$.ajax
type: 'POST'
url: "http://localhost:5000/workorders"
data:
workorder:
wostatus_id: '3'
This didn't work either:
$.ajax
type: 'POST'
url: "http://localhost:5000/workorder/17"
data:
wostatus_id: '7'
I'm missing something big time.
Does the ajax POST execute this code in the workorder controller????
# PUT /workorders/1
# PUT /workorders/1.json
def update
#workorder = Workorder.find(params[:id])
respond_to do |format|
if #workorder.update_attributes(params[:workorder])
format.html { redirect_to #workorder, notice: 'Workorder was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #workorder.errors, status: :unprocessable_entity }
end
end
UPDATE:
I added this to the workorder controller:
def changestatus
#workorder = Workorder.find(params[:id])
#workorder.update_attribute :wostatus_id, '4'
render nothing: true
end
I added this to the routes:
resources :workorders do
member { put :changestatus }
end
This is currently in the js.coffee:
$.ajax
type: 'PUT'
url: "http://localhost:5000/workorders/11/changestatus"
data:
wostatus_id: 4
(I'm hard coding things until I get the next step working.)
SO - this works, workorder 11 gets wostatus_id changed to 4.
But, now I'm having trouble getting the right information from the html.
The html contains 2 data fields I need - one for which workorder and the other is what the wostatus_id is.
Here is the html for the update url:
<div class="false" data-change-url="http://localhost:5000/workorders/16/changestatus">
I thought this would get that url - but, it doesn't work:
$(this).data('change-url')
If I understand correctly, then I think your sending a single value while your controller expects an array, and you're using different param names (wostatus_id on client, workorder on server).
Perhaps what you want is this:
$.ajax
type: 'POST'
url: $('#sort2').data('update-url')
data:
workorder: $('#sort2 span').map((i, el) ->
el.text()
) // Change the selector to the elements that holds the ID
Found out I didn't need any new controller code - I could just use update.
This is for jquery-ui sortable.
receive: (event, ui) ->
str_id = $(ui.item).attr('id')
woid = str_id.split('_')[1]
$.update "/workorders/" + woid,
workorder:
wostatus_id: $(this).data('wostatus-id')
Thanks for the help - you got me going in the right direction.