How to access my instance variable in my partial - ajax

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.

Related

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

ruby, sinatra, Plivo API: render API call as HTML

I am making an API call to Plivo to list available telephone numbers.
I can access the returned response and print the desired elements in my terminal BUT I do not know how to render them as HTML on my web page. This is my problem.
In the terminal, the response to a successful call is:
{"api_id"=>"23f1f0f0-0808-11e3-a442-22000ac6194a",
"meta"=>
{"limit"=>1, "next"=>nil, "offset"=>0, "previous"=>nil, "total_count"=>1},
"objects"=>
[{"group_id"=>"23928520636825",
"number_type"=>"local",
"prefix"=>"646",
"region"=>"New York, UNITED STATES",
"rental_rate"=>"0.80000",
"resource_uri"=>
"/v1/Account/MAZDQ1ZJIYMDZKMMZKYM/AvailableNumberGroup/23928520636825/",
"setup_rate"=>"0.00000",
"sms_enabled"=>true,
"sms_rate"=>"0.00800",
"stock"=>50,
"voice_enabled"=>true,
"voice_rate"=>"0.00900"}]}
"0.00900"
New York, UNITED STATES
646
The Ajax script which generates the response is:
$(".localsearch").click(function() {
var country_iso = $("#local").val();
var region = $("#region").val();
var prefix = $("#prefix").val();
$.ajax({
type: "GET",
url: "/local/data",
data: { 'country_iso' : country_iso, 'region' : region, 'prefix' : prefix },
success: function(data) {
alert(data)
},
});
});
The alert doesn't help and just shows the entire page.
The ruby code is:
get '/local/data' do
country_iso = params[:country_iso]
region = params[:region]
prefix = params[:prefix]
p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
params = {'country_iso' => country_iso, 'region' => region, 'prefix' => prefix, 'limit' => '1'}
response = p.get_number_group(params)
obj = response.last
pp response.last
#region = obj["objects"][0]["region"]
puts #region
#prefix = obj["objects"][0]["prefix"]
puts #prefix
erb :search
end
So, sorry it's long and to summarize, how do I extract elements from the API response and print them as HTML? Many thanks in advance.
In the view I have tried:
<%= #region %> and <%= obj['region'] %> and <%= obj['objects][0]['region'] %>and none of them work.
Yours is a perfect use case of of rendering a partial through a ajax call.
So what you can do is:
Make your Sinatra action return html using rails like render partial functionality like this
http://steve.dynedge.co.uk/2010/04/14/render-rails-style-partials-in-sinatra/
(to get rails like partial functionality in sinatra you can use this gem also https://rubygems.org/gems/sinatra-partial )
Now since now your sinatra action returns a valid html, in your ajax success function you can just write:
$(".localsearch").click(function() {
var country_iso = $("#local").val();
var region = $("#region").val();
var prefix = $("#prefix").val();
$.ajax({
type: "GET",
url: "/local/data",
data: { 'country_iso' : country_iso, 'region' : region, 'prefix' : prefix },
success: function(data) {
$('unique_identifier_of_your_partial_on_the_html_dom').html(response)
}
});
});
another example of rendering partial in sinatra:
Ruby w/ Sinatra: Could I have an example of a jQuery AJAX request?
extract out the html that you want to populate with the response from this ajax call into a a separate erb file lets say , _my_response_partial.html.erb
now suppose this is your search.html.erb file.
#something somrthing
<%= erb(:my_response_partial, locals => {:region => #region, :prefix => #prefix},:layout => false) %> #pass whatever data you want to pass to a partial using locales
# something something
and in your get action replace the last line with:
erb(:my_response_partial, locals => {:region => #region, :prefix => #prefix},:layout => false)
By this way your action will just return the html required to populate that partial.

How to use inline :confirm option for html helpers with AJAX calls?

I am trying to have an AJAX implementation of record deletion associated with a button. The problem is that ajax:success event doesn't seem to be triggered in such case.
I have implemented the suggestion from this post: Rails :confirm modifier callback?) but I am uncertain if it's the preferred way.
I was wondering if communal wisdom could help in this case. What's the right approach here?
app/views/competitions/show.html.haml:
%td= button_to 'Delete', contender, remote: true, method: :delete, class: 'delete_contender', confirm: 'Are you sure?' if owns?
app/assets/javascripts/competitions.js:
$(document).ready(function() {
$('.delete_contender').on('confirm:complete', function(e, res) {
if (res) {
$(e.currentTarget).closest('tr').fadeOut();
}
});
});
app/controllers/contenders_controller.rb:
def destroy
#contender = Contender.find(params[:id])
#competition = #contender.competition
#contender.destroy
respond_to do |format|
format.js
format.html { redirect_to #competition, notice: "Contender #{#contender.sn_name} has been deleted" }
format.json { head :no_content }
end
end
The quick answer is: that is not the right approach. The long answer is below.
Instead of using .delete_contender class as an anchor for action binding, I should have used "form[data-remote]" since *button_to* helper generates a form. Also, there is no need to keep the JS hook inside the asset pipeline, it's better to move it to the views and convert to CoffeeScript. The Rails 3 style solution is:
app/views/competitions/show.html.haml:
%td= button_to 'Delete', contender, remote: true, method: :delete, confirm: 'Are you sure?' if owns?
app/views/competitions/destroy.js.coffee:
jQuery ->
$("form[data-remote]").on "ajax:success", (e, data, status, xhr) ->
$(e.currentTarget).closest('tr').fadeOut()
app/controllers/contenders_controller.rb:
respond_to :js, only: :destroy
def destroy
#contender = Contender.find(params[:id])
#competition = #contender.competition
#contender.destroy
end

When i call ajax function its working first time only in first ajax call i reload the same div from which i m calling ajax request

// main htm page from where aja x call happened
<div id ="vote_count_<%=answer.id %>" >
<%= render :partial => '/votes/count', :locals =>{ :answer => answer} %>//render a partial
<div id="wait" style=" float:center">// for loading image
</div>
</div>
// partial page :- count
<div class ="look6">
<%= image_tag("thumbs_up.jpg", :alt => "like",:value => answer.id,:id => 'like',:class => 'vote')%>// image tag for like reload during ajax call
(<%= Vote.count(answer.id,'like')%>)// no of like vote
| <%= image_tag("thumbs_down.jpg", :alt => "unlike",:value => answer.id,:id =>'unlike',:class => 'vote',:onclick=>"return vote()") %>// image tag for unlike reload during ajax call
(<%= Vote.count(answer.id,'unlike')%>)// no of unlike vote
</div>
// ajax function :-
<script type="text/javascript" >
function showLoadingImage()
{
$('#wait').append('<div id="loading-image"><%= image_tag("ajax-loader.gif", :alt=>"Loading..." )%></div>');// for ajax loading
}
in first page:
//.vote is a claas name
$(".vote").click(function(){
alert("hi");
var answer_id =$(this).attr("value");// for ans id
alert(answer_id);
showLoadingImage();// call loading image function
var result = $(this).attr("id");// whether like or unlike
$.ajax({
cache: false,
//path for controller
url: '/create_vote/'+answer_id,
data: "result="+result,// data for ajax call
complete: function(){
$('#loading-image').remove();// remove loading image
}
});
cache: false;
return false;
});
</script>
//ontroller:
def create_vote
#vote = Vote.new // create new vot
#vote.user_id = current_user.id// user id
#vote.answer_id = params[:id]// answer id
#vote.result = params[:result] == 'like' ? '1':'0'// like or unlike
answer = Answer.find(params[:id])// answer id find
if #vote.save// save vote
#message = "thanks"// message
else
#message = "sorry"// mesage
end
#vote_count = Vote.count(params[:id], params[:result])// total vote
respond_to do |format|
format.js { render '/votes/create_vote.js.erb', :locals => {:result =>params[:result],:answer =>answer}}// result return back
end
end
///votes/create_vote.js.erb
$("#vote_count_<%=#vote.answer_id %>").html("<%= escape_javascript(render :partial => '/votes/count', :locals => {:result => result ,:answer =>answer }) %>")// render js part
//_count partial
<%= image_tag("thumbs_up.jpg", :alt => "like",:value => answer.id,:id => 'like',:class => 'vote')%>
(<%= Vote.count(answer.id,'like')%>)
| <%= image_tag("thumbs_down.jpg", :alt => "unlike",:value => answer.id,:id =>'unlike',:class => 'vote',:onclick=>"return vote()") %>
(<%= Vote.count(answer.id,'unlike')%>)
use:- $(".vote").live("click", function(){
in place of : $(".vote").click(function(){

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