rails + escape_javascript + locales - ruby-on-rails

I have the below jquery script and I can't pass i value into locales=> :val
$(document).ready(function(){
var i = 1
function more(){
var information= $("<%= escape_javascript(render :partial => 'info', :locals => { :val => i }) %>");
i = i+1;
}
});
Please guide me how to pass javascript variable to rails.
Thanks

If possible values of the variable i are limited, you could generate javascript for every possible value of i. e.g.: (i is in range 1..10)
$(document).ready(function(){
var i = 1
var informationArray = new Array();
<% (1..10).each do |num| %>
informationArray[<%= num %>] = $("<%= escape_javascript(render :partial => 'info', :locals => { :val => num }) %>");
<% end %>
function more(){
var information = informationArray[i];
i = i+1;
}
});
Otherwise, if variable i is not limited in a specific small range, you should use AJAX to send the parameter to the server and retrieve the information for that value.

Related

Refresh div with gmaps4rails (AJAX)

I'm using Rails 3.0.9 version, and jquery.
I've been using this gem without a database. It is used only for map display, and display KML file on it. For this I used:
<div id='ajax_map'>
<% #kmlurl="http://mysite/file1.kml" %>
<%= gmaps( :kml => { :data => "[{ url: #{#kmlurl.inspect}}]" } ) %>
</div>
All great shows.
I want to do that after you change the links (# kmlurl), and click on the button, the map updated with this new KML file. I use a separate action js.erb with the following code:
$('#ajax_map').html('<%= #kmlurl="http://mysite/file2.kml" %>'+'<br />'+'<%= gmaps( :kml => { :data => "[{ url: #{#kmlurl.inspect}}]" } ) %>');
But he does not update the DIV. "js.erb" rendered normally, without using the method of gmaps () it normally returns # kmlurl. I tested this same code in the ". Html.erb" in the tags , it loads a new file, but, of course, just when the page loads.
How can I solve this problem?
Solved the problem as follows (in js.erb):
$('#ajax_map').html('<%= escape_javascript( gmaps({:last_map => false}) ) %>');
Gmaps.map = new Gmaps4RailsGoogle();
Gmaps.load_map = function() {
Gmaps.map.map_options.maxZoom = 15;
Gmaps.map.initialize();
Gmaps.map.kml = [{ url: '<%= "#{#kmlurl}" %>'}];
Gmaps.map.create_kml();
Gmaps.map.adjustMapToBounds();
Gmaps.map.callback();
};
Gmaps.loadMaps();
First I would refactor things just a bit.
Say that first bit of code were in your index page. I'd move the setting of #kmlurl into the corresponding controller action:
def index
#kmlurl = "http://mysite/file1.kml"
end
Then (assuming index?) your index view would be simply:
<div id="ajax_map">
<%= gmaps( :kml => { :data => "[{ url: #{#kmlurl}}]" } ) %>
</div>
Then to add a link that will update the map:
<%= link_to 'Other Map', '/othermap', :remote=>true %>
Now you'd create a route in routes.rb:
match '/othermap' => 'foo#othermap'
Then in foo_controller.rb:
def othermap
#kmlurl = "http://mysite/file2.kml"
end
Then create othermap.js.erb:
$('#ajax_map').html(
'<%=
escape_javascript(
gmaps( :kml => { :data => "[{ url: #{#kmlurl}}]" } )
)
%>'
)
That's a quick fix, but what I would REALLY do is strive to make your view code as simple as possible, and do all the real work in the controller. Ideally your view would just be:
<div id="ajax_map">
<%= gmaps( :kml => { :data => #mapdata } ) %>
</div>
set up #mapdata as appropriate in your controller. You've got too much stuff that really belongs in a controller embedded in your view code! Your othermap.js.erb should be equally simplified. i.e.
$('#ajax_map').html('<%= escape_javascript(gmaps( :kml => { :data => #mapdata } ))%>')

Adding an onclick option to link_to method in rails?

I want to add an onclick option to link_to method for loading an modal dialog box...i am using rails version 2.3.8 and i searched on google and could not do it. Plz anybody help me?
My link_to method as follows.
<%= link_to 'All countries',{:controller=>'countries', :action=>'new'}, :remote => true %>
If you are using 2.3.8, you don't have :remote => true. You need to use link_to_remote if you are try to do an ajax action.
So it would look something like:
<%= link_to_remote 'All countries', :url => {:controller => 'countries', :action => 'new'}%>
<div id="populate_me"></div>
and your new method would have to handle the ajax request with something like
countries_controller.rb
def new
<do something>
render :update do |page|
page.replace_html 'populate_me', :partial => 'whatever'
end
end
UPDATED
If you want the onclick in addition to the ajax action, you can just pass it into the html options:
<%= link_to_remote 'All countries', :url => {:controller => 'countries', :action => 'new'}, :html => {:onclick => 'alert("some javascript executed before ajax")'} %>
You can add this to the link:
, :class => "pop light", :id => "modal_link"
Then, your JS shows something ilke this:
<script type="text/javascript">
$(document).ready(function() {
$('a.poplight[href^=#]').click(function() {
var popID = $(this).attr('rel'); //Get Popup Name
var popURL = $(this).attr('href'); //Get Popup href to define size
var query= popURL.split('?');
var dim= query[1].split('&');
var popWidth = dim[0].split('=')[1]; //Gets the first query string value
$('#' + popID).fadeIn().css({ 'width': Number( popWidth ) }).prepend('');
$('a.close').hide();
var popMargTop = ($('#' + popID).height() + 80) / 2;
var popMargLeft = ($('#' + popID).width() + 80) / 2;
$('#' + popID).css({
'margin-top' : -popMargTop,
'margin-left' : -popMargLeft
});
$('body').append('<div id="fade"></div>');
$('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
return false;
});
$('a.close').live('click', function() {
$('#fade , .popup_block').fadeOut(function() {
$('#fade, a.close').remove();
});
return false;
});
$('#modal_link').click();
});
</script>

Ruby on Rails - drop down box on change event

I have two drop down boxes in my application.
Based on the value selected in 1st combobox, the values in 2nd drop down box should be populated.And these values should come from Database.
Please help me.
here's a clean approach using jquery-ujs (https://github.com/rails/jquery-ujs)
In your view:
<%=
select_tag
:first_select, # name of selectbox
options_from_collection_for_select(#myrecords, "id", "name"), # your options for this select box
:'data-remote' => 'true', # important for UJS
:'data-url' => url_for(:controller => 'MyController', :action => 'getdata'), # we get the data from here!
:'data-type' => 'json' # tell jQuery to parse the response as JSON!
%>
<%=
select_tag
:second_select, # name of selectbox
"<option>Please select something from first select!</option>"
%>
Your Controller:
class MyController < ApplicationController
def getdata
# this contains what has been selected in the first select box
#data_from_select1 = params[:first_select]
# we get the data for selectbox 2
#data_for_select2 = MyModel.where(:some_id => #data_from_select1).all
# render an array in JSON containing arrays like:
# [[:id1, :name1], [:id2, :name2]]
render :json => #data_for_select2.map{|c| [c.id, c.name]}
end
end
In your application.js:
$(document).ready(function() {
// #first_select is the id of our first select box, if the ajax request has been successful,
// an ajax:success event is triggered.
$('#first_select').live('ajax:success', function(evt, data, status, xhr) {
// get second selectbox by its id
var selectbox2 = $('#second_select');
// empty it
selectbox2.empty();
// we got a JSON array in data, iterate through it
$.each(data, function(index, value) {
// append an option
var opt = $('<option/>');
// value is an array: [:id, :name]
opt.attr('value', value[0]);
// set text
opt.text(value[1]);
// append to select
opt.appendTo(selectbox2);
});
});
});
You could take inspiration from what I have in a project of mine. It updates the state given the country selected.
It makes use of Carmen a great gem listing countries, states etc...
View:
<p>
<label>Country <span>*</span></label>
<%= profile_form.select(:country,Carmen.countries, {:include_blank => 'Select a Country'}, :id => "profile_country") %>
</p>
<p>
<label>State <span>*</span></label>
<%= profile_form.select(:state, "" , {:include_blank => 'Select a Country first'}, :id => "profile_state") %>
</p>
Jquery code:
$('#profile_country').change(function() {
if ($(this).val() == '')
{
$('#profile_state').html( $('<option>No state provided for your country</option>'));
}
else {
$.ajax({
type: "GET",
url: "/remote/get_states/" + encodeURIComponent($(this).attr('value')),
success: function(data){
if (data.content == 'None') //handle the case where no state related to country selected
{
$('#profile_state').empty();
$('#profile_state').append( $('<option>No state provided for your country</option>'));
}
else
{
$('#profile_state').empty();
$('#profile_state').append( $('<option>Select your State</option>'));
jQuery.each(data,function(i, v) {
$('#profile_state').append( $('<option value="'+ data[i][1] +'">'+data[i][0] +'</option>'));
});
}
}
});
}
});
Controller:
def states
begin
render :json => Carmen::states(CGI::unescape(params[:country]))
rescue
render :json => {"content" => "None"}.to_json
end
end
This is how I did it. Works in Rails 3.2
View:
<%= select_tag :major_category_select_id, options_from_collection_for_select(#majorcategories, 'id', 'name'), :'data-remote' => 'true', :'data-url' => url_for(:controller => 'listings', :action => 'submit_major_category', format: 'js') %>
Controller method:
def submit_major_category
#major_category = MajorCategory.find(params[:major_category_select_id])
#minor_categories = #major_category.minor_categories
respond_to do |format|
# format.html { render partial: 'minor_categories_select' }
format.js
end
end
Routes:
get "listings/submit_major_category"
Then create a submit_major_category.js.erb file that gets responded to.

Stagger the rendering of multiple partials using Rails

I've got the following situation:
1. Using a javascript function to begin an AJAX call
$(".toggle").click(function() {
var currentId = $(this).attr('id');
$(this).find(".loadingDiv").show();
$(this).find(".matchingsDiv").load("<%= matches_companies_url %>?id=" + currentId, null, function(){
$('.loadingDiv').hide();
});
return false;
});
2. Rendering matches.js.erb
<% #matchings.each_with_index do |match, index| %>
<%= (render :partial => 'companies/matching', :locals => {:match => match, :project => #project}) %>
<% end %>
The above code works. Here's a little question: how can I stagger the rendering of each matching?
i.e. Can I make the first matching render immediately, the next matching after 200ms, the third after 400ms, and so on?

two sortable lists need to get serialize parameters using jquery-ui

Can you help me with these codes:
app/views/admin/articles/position.html.haml
- form_tag update_position_admin_articles_path do
.grid_5.alpha{:id => 'article-container'}
%h3 Articles
%ul#articles.connectedSortable
- for article in #articles
= content_tag(:li, article[0], :id => article[1], :class => 'ui-state-default')
.grid_5.omega{:id => 'feature-container'}
%h3 Featured Articles
%ul#features.connectedSortable
- for feature in #features
= content_tag(:li, feature[0], :id => feature[1], :class => 'ui-state-highlight')
%br.clear
= submit_tag "Update Position"
public/application.js
$(function() {
$("#articles, #features").sortable({
connectWith: '.connectedSortable',
update: function(event, ui) {
console.log($(this).sortable("serialize"));
}
})
});
It's two sortable lists and I need to get the serialize parameter of those lists to be passed when I click the submit button but I always get "(an empty string)" on console.log(). I'm using jQuery-ui for this functionality.
Just in case anyone bumped into this same problem.
Solved this problem with this code:
app/views/admin/articles/position.html.haml
- form_tag update_position_admin_articles_path do
.grid_5.alpha{:id => 'article-container'}
%h3 Articles
%ul#articles.connectedSortable
- for article in #articles
= content_tag(:li, article[0], :id => article[1], :class => 'ui-state-default')
.grid_5.omega{:id => 'feature-container'}
%h3 Featured Articles
%ul#features.connectedSortable
- for feature in #features
= content_tag(:li, feature[0], :id => feature[1], :class => 'ui-state-highlight')
= hidden_field_tag 'sort[articles]', ''
= hidden_field_tag 'sort[features]', ''
%br.clear
= submit_tag "Update Position"
public/application.js
$(function() {
$("#articles, #features").sortable({
connectWith: '.connectedSortable',
update: function(element, ui) {
var result = $(this).sortable('toArray');
var data = {};
data[this.id] = result;
document.getElementById('sort_' + this.id).value = result;
}
})
});

Resources