I am new to RoR and I am looking for a way to dynamically display values in some text fields depending on the option chosen from a select menu in a form. The associated records are stored in another table. Hopefully in a way AJAX can be used such that it wouldn’t require a page refresh. I have seen examples in which select menus are dynamically changed according to values of select menus but not text fields.
Thanks,
Alex
PS: I am using rails 3.
Here's how I did it. I'm a Rails beginner too, so this may not be the best/most efficient way, but it works:
JS:
$('#select_box_id').live('change', function() {
var select_field_val = $('#select_box_id').val();
if(select_field_val == "") select_field_val = "0";
$.get('/some_controller_action/' + select_field_val, function(data) {
$('#text_field_div').html(data);
});
return false;
});
Controller:
def some_controller_action
#some_processing...
result = whatever
render :partial => "my_partial", :locals => { :text_field_value => result }
end
View:
<div id="text_field_div">
<%= render :partial => 'my_partial', :locals => { :text_field_value => "" } %>
</div>
Partial:
<%= text_field_tag :text_field, text_field_value %>
Related
I created a rails (v5) form with multiple select and collection_select elements.
Then I use Select2-rails (v4.0.3) to allow a nice selection looking like tags.
The search-options are pulled by ajax.
It works fine until one presses the submit-button with missing required fields.
Valid field-content has now been deleted from the field.
Let me give some example-code:
controller:
...
def form
if params[:form_request].nil?
#form_request = FormRequest.new
else
#form_request = FormRequest.new(params[:form_request])
end
end
def request_form
#form_request = FormRequest.new(params[:form_request])
if #form_request.valid?
render :summary
else
render :form
end
end
...
form:
...
<%= bootstrap_form_for(#form_request, url: '/form/request_form') do |f| %>
<%= f.select :field, [], {label: 'Field label'} %>
<%= f.submit "Submit form" %>
<% end %>
:field is for sure a writable field in the model (and data is set fine)
coffee-script:
Query ->
$("#form_request_from").select2({
ajax: {
url: func =(params) ->
filter = params.term
return "/data.json?filter=" + filter;
,
dataType: 'json',
processResults: processData
},
theme: 'bootstrap',
placeholder: 'Enter data here'
});
processData = (data) ->
mapdata = $.map(data, func =(obj) ->
obj.id = obj.id;
obj.text = obj.name;
return obj;
);
return { results: mapdata };
I am thinking of a lot of possibilities, but at the end I am not sure where the field-data comes from. It is inside the object, but it isn't written to the resulting HTML in any way.
And even if the id would be written as a selected option,
the select2 script would need to know how to transform that into the string to show the real data.
Any idea how to achieve that the data is still written into a field after a failing validation?
After trying out some things I found out how to do it.
At first I just changed the empty array to be the :field variable,too.
This doesn't work too well because it only remembers the ID of the value that has been entered before and like this the SELECT2-script could not find the value to that key and nothing is shown.
Then I created a new variable inside the controller in which I place the array with name and id:
field_object = ObjectsModel.find(#form_request.field.to_i)
#form_field = []
if !field_object.nil?
#form_field = [[field_object.name, field_object.id]]
end
And in the view I now use this field to show the available options:
<%= bootstrap_form_for(#form_request, url: '/form/request_form') do |f| %>
<%= f.select :field, #form_field, {label: 'Field label'} %>
<%= f.submit "Submit form" %>
<% end %>
This works perfectly fine for me without the need to touch the SELECT2-script.
The possible values are still fetched by AJAX but already filled out fields will persist upon redirect to another action.
I'm using Rails 4.0.2 with jquery-rails (3.1.0) and jquery-ui-rails (4.1.1) gems. I'm added autocomplete in order to do a specific search based on what user typed and other fields at form.
The form:
<%= text_field_tag :field , some_value, data: { autocomplete_source: select_path( { :id => #order.Id , :type => #order.type } ) } %>
Form.js:
$('#field').autocomplete
minLength: 0
source: $('#field').attr('data-autocomplete-source')
select: ( event, ui ) ->
$('#pedido_venda_CodTransp').val(ui.item.value)
$('#transportadora_escolhido').val(ui.item.label)
this.form.submit()
false
...
The controller:
def select
# retrieve parameters
id_cliente = params[:id]
retira_entrega = params[:type]
term = params[:term]
# do the query, etc...
end
When I run the code, everything is OK. The controller receives all parameters and run the query flawlessly.
The parameter type, however, is based on a SELECT control and, in order to change it, I put the following code in the SELECT control.
<%= f.select :type, options_for_select( [['RETIRA','R'],['ENTREGA','E']] , #pedido.RetiraEntrega ) ,{}, { :onchange => "change_type();" } %>
JS Code function:
function change_type()
{
var e = document.getElementById("type");
var option = e.options[ e.selectedIndex ].value;
var field = document.getElementById("field");
var origem = "type=";
source = field.attributes["data-autocomplete-source"].value;
// pesquisa a string retira_entrega=
index = source.search(origem);
field.setAttribute("data-autocomplete-source", source.substring(0,index+origem.length) + String(option));
}
The JS function is called, the last line is run, the attribute is set (I put an alert at the end retrieving the attribute).
The problem is that the controller never receives the changed value (it always receives the value when the form is created).
So, the question is: how can I change a parameter passed on to autocomplete in order to use it in rails controller?
Not sure if this is what your looking for but I was struggling with the same issue because I had two input fields that I wanted different lists loaded to in the autocomplete widget. So what I did was pass an extra param to the auto complete source like this:
<!-- /_form.html.erb -->
<%= f.text_field :auto1, :size => "100", class: "form-control", data: { autocomplete_source: root_path(:fieldType => "numerouno")} %>
<%= f.text_field :auto2, :size => "100", class: "form-control", data: { autocomplete_source: root_path(:fieldType => "numerodos")} %>
Then in my controller I used that extra param to determine which list I needed to show:
if param[:fieldType] == "numerouno"
format.json { render :json => #unoList}
elsif param[:fieldType] == "numerodos"
format.json { render :json => #dosList }
else
flash[:danger] = "Error loading list for autocomplete!"
end
param[:term] still goes through too!
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 } ))%>')
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?
I am using rails 3 and will_paginate to browse through photos. I have it working except I would also like it so that users can view the next record by clicking the picture rather than the next button in the pagination navigation. Very similar to facebooks image viewing or something like the following: http://exposure.blogocracy.org/demos/demo1.html
I don't know if will_paginate has any parameters to allow this to work... any help or direction would be very much appreciated
controller - image - action: gallery
def gallery
#images = Image.all.paginate(:per_page => 1, :page => params[:page])
end
view image - gallery
<div id="slideshow">
<% #images.each do |image| %>
<%= image_tag("gallery/"+image.path, :alt => "") %>
<% end %>
</div>
view layout - _nav
<%= will_paginate #images, :previous_label => '« ',
:next_label => '»',
:params => { :controller => "images",
:action => "gallery" },
:separator => ' ',
:inner_window => 4,
:outer_window => -1 %>
-----------EDIT--------------
As a work around I decided to use javascript / jquery and link it manual.. it's really really ugly but im using it until i figure out the right way to do it.
`
$(document).ready(function() {
$('div#slideshow img').live('click', function() {
var has_images = '<%= #has_image %>';
if( has_images == 1 ) {
var page = '<%= #next_image.id %>';
var url = '/images/gallery?page='+page
window.location.replace(url);
}
else {
var url = '/images/gallery?page=1'
window.location.replace(url);
}
})
})
`
The example you are linking to is a jQuery plugin called Exposure why don't you just use that?
And i wouldn't recommend Will_paginate for that you want.
Oluf Nielsen