How to pass back using information ajax POST request - ruby

Currently I'm working on the slider, each slide is certain state using state machine. Now from one page I'm making post request with the data, which gets sent, if it passes validation, I would like to return "name of the state" to my view page, so I can move the slide ?
Is this better way of doing this ? The reason I chose slides as state so I can run query to figure out how many of my client made to certain slide.
So currently I'm making ajax post request.. (Ignore done for part)
$.post("/xxx/tracks", { name: "xx", time: "xx", pa: "xx" }).done(function(data) {
alert("Data Loaded:" + data);
});
So now in my controller
def tracks
binding.pry
# some condition determining val accordingly
respond_to do |format|
format.json { head :ok } #return val somehow
end
end
so my question is how do I return some value back ?

You can pass html, text or just the response header if you want to render nothing.
Html for example, just render the view you want:
def tracks
binding.pry
# some condition determining val accordingly
render 'tracks' #tracks.html.erb
end
$.post("/xxx/tracks", { name: "xx", time: "xx", pa: "xx" }, function(data) {
$("selector").append(data)
}).error(function(response, data){
alert('error processing the request')
})
For Text:
def tracks
binding.pry
# some condition determining val accordingly
if expression
render text: 'success', status: :ok
else
render text: 'Error processing your request', status :bad_request
end
end
$.post("/xxx/tracks", { name: "xx", time: "xx", pa: "xx" }, function(response, data) {
alert(data.responseText)
}).error(function(response, data){
alert(data.responseText)
})
To render just the headers
def tracks
binding.pry
# some condition determining val accordingly
if expression
head :created
else
head :unprocessable_entity
end
end
$.post("/xxx/tracks", { name: "xx", time: "xx", pa: "xx" }, function() {
alert('seccess')
}).error(function(){
alert('error')
})
you can render too json data.

Related

Chartkick Datepicker/Range Selector - Possibility to choose dates to show data

I am using ahoy gem to track visits & chartkick gem to show the data to users.
In users dashboard page, I have around 3-4 charts and each of them show different data to user.
As of today, my charts only displays last 7 days & I do it by group_by_day(:started_at, last: 7).
= area_chart Visit.where(user: current_user).group_by_day(:started_at, last: 7).sum(:price), label: '$'
How can I add datepicker so users can select two dates (start & end date) and display data between selected/giving dates?
UPDATE:
I have created charts_controller.rb and get the charts from this controller & routes.
For instance:
class ChartsController < ApplicationController
def visits
result = Visit.where(user: current_user).group_by_day(:started_at, last: 7).count
render json: [{name: 'Visits', data: result}]
end
My routes.rb:
resources :charts, only: [] do
collection do
get 'visits'
end
end
My view:
= area_chart visits_charts_path
You can create a datepicker and add an onchange listenner on it, then you send the start and end date using ajax to a controller that renders your chart:
$(".end_at").change(function(e){
end_at = $(e.target).val();
start_at = $(".start_at").val();
$.ajax({
type: "POST",
url: "/charts",
data: {
start_at: start_at,
end_at: end_at,
},
success: function (data) {
$(".chart-container").html(data);
},
});
});
In your controller :
class ChartsController < ApplicationController
def visits
start_at = params[:start_at].to_date
end_at = params[:end_at].to_date
render :inline => "<%= area_chart Visit.where(user: current_user).group_by_day(:started_at, range: start_at..end_at).sum(:price), label: '$' %>"
end
end

How to access my instance variable in my partial

I'm having trouble accessing my instance variable. My code is as follows:
# controllers/locations_controller.rb
def index
if request.xhr?
neLat = data.dig('northeast', 'lat').to_f
neLng = data.dig('northeast', 'lng').to_f
swLat = data.dig('southwest', 'lat').to_f
swLng = data.dig('southwest', 'lng').to_f
#markers = Location
.where("lat <= ?", neLat)
.where("lng <= ?", neLng)
.where("lat >= ?", swLat)
.where("lng >= ?", swLng)
end
respond_to do |format|
format.html
format.json {render :json => #markers}
format.js
end
end
# view/locations/_map.html.erb
$.ajax({
url: '/location.json',
type: 'GET',
contentType: "application/json; charset=utf-8",
data: {
"northeast": bounds.getNorthEast().toJSON(),
"southwest": bounds.getSouthWest().toJSON(),
}
})
.done(function(data) {
// EDIT HERE
console.log(data)
console.log(<%= #markers %>)
// END OF EDIT
$('.results').html("<%= j render 'locations/location_results' %>")
});
When I console.log(data) after my ajax has successfully completed I'm getting my anticipated results, however when I console.log(<%= #markers %>) I'm getting empty results. How do I get access to my instance variable?\
EDIT:
So I ended up passing a hash from my controller to my view like this:
# controller
renderPartial = render_to_string :partial => 'locations/location_results.html.erb'
respond_to do |format|
format.html
format.json {render :json => {markers: #markers, partial: renderPartial}}
end
# view
.done(function(data) {
if (data) {
$('.results').html(data.partial)
return addMarkers(data.props)
}
})
This let me render my partial and have access to my instance variable with erb and also use the callback variable in javascript.
I dont think you can with the current code.
You jQuery ajax is out of context, meaning, you are firing an ajax from client and the server returns some data using => format.json {render :json => #markers} hence the data returned from the server will be available to you in you done callback like you have already done.
There are two things you could do
Render partial from your action which will have access to the instance variable
def index
# Logic here
render :partial => "locations/location_results"
end
Or you can create a view for each format you want to support
def index
# Logic goes here
end
# Create a file with js extension in your views folder of the corresponding controller
# index.js.erb
# index.html.erb
# etc
When you do this, rails tries to render a view with the corresponding request format. So if the request is of type js which ajax is, it renders index.js.erb.
And in your index.js.erb you could do this console.log('<%= #markers %>'). Basically you can write javascript in this file to manipulate your html. For example in index.js.erb I could also do this
$('.results').html("<%= j render 'locations/location_results' %>")
console.log('<%= #markers %>')
Hope that helps :)
So I ended up passing a hash from my controller to my view like this:
# controller
renderPartial = render_to_string :partial => 'locations/location_results.html.erb'
respond_to do |format|
format.html
format.json {render :json => {markers: #markers, partial: renderPartial}}
end
# view
.done(function(data) {
if (data) {
$('.results').html(data.partial)
return addMarkers(data.props)
}
})
This let me render my partial and have access to my instance variable with erb and also use the callback variable in javascript.

rails 4 , Ajax request , can I get a response with html AND a json objects?

I am currently requisition an html partial to be inserted into a modal
$('#user-addTool').on('click', function(e) {
$('#userModal div.modal-content').html('');
var ajaxUrl = "http://" + window.location.host + "/users/new";
e.preventDefault();
e.stopPropagation();
$.get(ajaxUrl, function(data){
$('#userModal div.modal-content').html(data);
initGroupSelector();
initRoleSelector();
$('#role-selector').multiselect('disable');
}, "html");
$('#userModal').modal('show');
});
served by a rails app :
# GET /users/new
# GET /users/new.json
def new
#user = User.new
#user.profile = Profile.new
authorize #user
render partial: 'users/form', layout: false
end
I wonder if I can return both, the partial form html AND a son object ( groups and roles to be used in the client js script ?
thanks for feedback
UPDATE 1 --
Can I send a JSON response this way ?
format.json {
#response = {
"html": { "form": <%= (render partial: 'users/form').to_json.html_safe %> },
"data": { "groups": <%= #groups %> , "roles": <%= #roles %> }
}
render(json: #response, status: :success )
}
In which #group is an Array of Arrays and #roles a Hash of Hashes ?
thanks for advices

Clean up Django Ajax JSON GET Request

So I'm trying to use AJAX to load some data. I can get the data to load but it's stuck in json. How do I make it so it's cleaner & more human readable?
//jquery
$.get("/get_artwork", function(data) {
var obj = jQuery.parseJSON(data)
$('.result').append("<br/> " + data + " ");
});
#Views.py
def get_artwork(request):
if request.is_ajax():
artwork = Artwork.objects.all()[1:]
if request.method == 'GET':
data = serializers.serialize("json", artwork, fields=('name','updated'), indent=2, use_natural_keys=True)
return HttpResponse(data,mimetype='application/javascript')
elif request.method == 'POST':
message = "This is an XHR POST request"
# Here we can access the POST data
print request.POST
else:
message = "Hello"
return HttpResponse(message)
and this is what renders:
[ { "pk": 3, "model": "artworks.artwork", "fields": { "updated": "2013-01-20T06:46:24Z" } }, { "pk": 2, "model": "artworks.artwork", "fields": { "updated": "2013-01-17T23:44:26Z" } }, { "pk": 1, "model": "artworks.artwork", "fields": { "updated": "2013-01-17T23:43:22Z" } } ]
How would I make this more human-readable? Thanks!
Based on the comments you've left.. it seems your issue is downstream in the client (e.g. web browser). It is not clear what you mean by stuck in JSON. If you are using JavaScript to parse the JSON, you will need to use JSON.parse() to turn it into a native JavaScript object. If you are using jQuery and the $.ajax() method, you will need to set the mimetype to application/json for it to automatically parse it as JSON.
UPDATE
If you want to control how the JSON data is rendered in the browser, I suggest you parse the JSON response into a native JavaScript object and then iterate over objects and fields you want to render in the page. As an example, using jQuery:
$.ajax({
url: '/some-url/',
dataType: 'json',
success: function(resp) {
var i, k, li, obj, fields;
for (i = 0; i < resp.length; i++) {
obj = resp[i];
// render obj pk or model name here... now iterate over fields
fields = obj.fields;
for (k of obj.fields) {
li = $('<li>').text(k + ': ' + obj.fields[k]);
// append the li to some element..
}
}
}
});

RoR - Retrieve a data from controller and display using AJAX

I have a controller that assign to pass a value to ajax but when in execution no value are printed, here are my code:
:User Controller
def search_name
#nama = params[:name] //Get a value from user input
#user = User.select(:name).where(['name = ?', params[#nama]]).all
respond_to do |format|
format.json {render :json => #user}
format.html { render :json => #user}
end
end
:my.js
$.ajax({
url: '/users/search_name/',
type:'get',
data:{
name:nama
},
dataType:'json',
success:function(puser){
var userName = '';
for(x in puser){
userName += 'Name here"'+ puser[x]['user']['name'] +'";
}
$('.search-result').html(userName);
}
})
to debug this js issue, please use your browser to visit: /users/search_name , to see what the result is.

Resources