How can I easily pass the value I get from the auto_complete textfield to a partial.
<%= text_field_with_auto_complete :participant, :name, {}, {:url => {:controller => "contentcom/discussions", :action => :get_users_for_auto_complete}, :method => :get, :param_name => 'search'} %>
<%= button_to_function(:OK) do |page|
page.insert_html :top, :participants, :partial => 'participant', :locals => end %>
Bye,
Nico
First of all you need to know that the helpers text_field_with_auto_complete and button_to_function not really handle user actions, but only generate HTML and javascript code. Only generated javascript code can interact with the user. In this case text_field_with_auto_complete generates the following (approximately):
<input type="text" id="participant_name" name="participant[name]" size="15" />
<div id="participant_name_auto_complete" class="auto_complete"> </div>
<script type="text/javascript">
var participant_auto_completer = new Ajax.Autocompleter (
'Participant',
'Name',
'/contentcom/discussions/get_users_for_auto_complete',
{method: 'GET', param_name: 'search'}
);
</script>
The above code is that the user gets in his browser.
If you read the documentation for text_field_with_auto_complete, then you will see that we can use the option :after_update_element. This option allows us to specify the name of the JavaScript function that will be called when the user selects one of the proposed values.
What we need to do:
write a JavaScript function that
will display anywhere user-selected
value from autocomplete field.
call text_field_with_auto_complete
with :after_update_element
That's how the template will look like:
<ul id="selected_participant_container"></ul>
<%= text_field_with_auto_complete :participant, :name, {}, {
:url => {:controller => "contentcom/discussions", :action => :get_users_for_auto_complete},
:method => :get,
:param_name => 'search',
:after_update_element => 'afterParticipantSelected'
}%>
<script type="text/javascript">
function afterParticipantSelected (el, value) {
var container = document.getElementById ('selected_participant_container');
container.innerHTML = value;
}
</ Script>
Now, when a user selects a value in the autocomplete field, it will be displayed in the element with id = selected_participant_container
Of course, you can use methods that are proposed by tokland.
But I would Recommend you first learn the basics of HTML and Javascript.
Note first that the block of button_to_function (and its partial, of course) is generated server-side, so it has no way to know the value of the autocomplete in the client. You have 2 ways to accomplish what you want: create a RJS action for the auto_complete (if that's possible) or 2) use Javascript/AJAX and connect to the auto_complete URL, get the value and modify the DOM accordingly (also in JS).
Related
For example, I use data remote for the pagination like this :
<%= paginate #products, :remote => true %>
It works. But the problem is I have multiple lists to paginate in one page. So, I need a way to send the call to a separate files so I can render the appropriate content. How can I do this?
My index.js.erb :
<% if params[:list] %>
$('#products').html('<%= escape_javascript render(#products) %>');
$('#paginator').html('<%= escape_javascript(paginate(#products, remote: true, param_name: 'list' ).to_s) %>');
<% end %>
For this you need to add another param with paginate.
<%= paginate #products, :remote => true, :param_name => param_name %>
This params name will pass as parameter to controller so you can control which ajax pagination you are calling.
If you are calling same action then on the basis of param name you can change the value of #products also. One more thing you need to consider in your xxxx.js.erb file you need to render paginate object also.
In your js file you can change html on the basis of param also.
- if params[:xxx]
$('#xxx').html('#{escape_javascript render(:partial =>"partial_name",:locals => { :posts => #products, :param_name => 'xxx'})}');
$('#xxx #paginator').html('#{escape_javascript(paginate(#products, :remote => true, :param_name => 'xxx').to_s)}');
- if params[:yyy]
$('#yyy').html('#{escape_javascript render(:partial =>"partial_name",:locals => { :posts => #products, :param_name => 'yyy'})}');
$('#yyy #paginator').html('#{escape_javascript(paginate(#products, :remote => true, :param_name => 'yyy').to_s)}');
In your controller you should use param_name instead of params page
I have a controller "mainpage", with a correspondingly named view. The controller creates a #myLocalSuites variable, and the view includes the following line:
<li class="active"><%= link_to "Perforce", :action => 'renderp4', :remote => true, :localSuites => #myLocalSuites %></a></li>
Routing is defined such that clicking this link_to calls renderp4.js.erb to render a partial within the mainpage view:
$('#MainPage').replaceWith('<%= escape_javascript render "perforce_sync/perforceSync" %>')
where _perforceSync partial includes:
<%= select_tag "perforceSuites", options_for_select(*MYOPTIONSVARIABLE*), {:class => 'form-control', :size => "20", :multiple => true} %>
Where *MYOPTIONSVARIABLE* needs to be myLocalSuites as cascaded down from the mainpage view/controller.
Having tried everything I can think of, and failed - can someone please show how to modify the above snippets to use the required variable in the PerforceSync partial? Everything I've tried seems to produce something along the lines of:
ActionView::Template::Error (undefined method `map' for nil:NilClass):
An example of what I've tried. I don't think I'm a million miles off, but...
<li class="active"><%= link_to "Perforce", :action => 'renderp4', :remote => true, :localSuites => #myLocalSuites %></a></li>
$('#MainPage').replaceWith('<%= escape_javascript render "perforce_sync/perforceSync", :suitesLocally => params[:localSuites]%>')
<%= select_tag "perforceSuites", options_for_select(params[:suitesLocally]), {:class => 'form-control', :size => "20", :multiple => true} %>
Thanks! :)
In response to your comment, there are two things you can do here. One way is to simply render some dynamic JS on page load, and then use javascript to show that data at a later point.
If this data however is to depend on user actions after the page has loaded, you must make another request to the server using AJAX.
The first way might look like this:
<script>
var my_data = "<%= #some_data %>";
//#some_data could be set by the controller action for example
$('button').click(function() {
$('div.content_container').text(my_data);
});
</script>
The second way would look like this:
<script>
$('button').click(function() {
$.ajax({
url: '/some_resource/id.json',
data: {param1: 'some_user_data'}
}).done(function(data) {
$('div.content_container').text(data);
});
});
</script>
The data option for the ajax call allows you to pass parameters back to the server, so you can send some data provided by the client. Documentation for jquery ajax is here if you want to see other options.
The .done callback gets fired when the client receives a response from the server, and the function parameter is the data returned.
Right now I can call a method using ajax (:remote=> 'true') at awisprotect_path by simply clicking on the "x" in this link
<%= link_to "x",
awisprotect_path,
:remote => true,
:method => :post,
%>
The controller action renders jquery so the response is included into the html in the view
<div class="awishanswer">
</div>
That's all working fine. However, instead of having an "x" to click, I wanted the user to click a button and get the same result. So I essentially just wanted to put the link info
<%= link_to "x",
awisprotect_path,
:remote => true,
:method => :post,
%>
into this button
<button class="btn small primary" >
check
</button>
So I created this form and put it in a partial
<%= form_tag(:controller => "sessions", :action => "awisprotect", :remote => true, :method => "post") do %>
<button type="submit" class="btn small secondary">check awis</button>
<% end %>
but the problem is that the controller action that renders js is not putting the result of the action into the html div. Instead, it's redirecting to a blank page and then printing the jquery method with the result that I was checking for with the controller action. the blank page just shows this...
$('div.awishanswer').html(' html to be inserted in div');
Can anyone explain?
In the url it says
http://localhost:3000/awisprotect?method=post&remote=true
in the view file
<div class="awishanswer" id="awishanswer">
<% form_remote_tag :url => {:controller => "sessions", :action => "awisprotect"},
:html => {:method => "post"}, :update => "awishanswer" do %>
<input type="submit" class="btn small primary" value="check" />
<% end %>
</div>
in the action
def awisprotect
#flag = params[:flag] // suppose sending parameter flag from form
// do something
render :partial => 'partial file containing html to send to view'
end
The form will be submitted when the submit button is clicked.
the action will send the html contained in partial file.
the form will update the div with id provided in form with the html code send back from action.
EDIT:partial file
<%if #flag%>
// include some html
<%else%>
// include some other html
<%end%>
The reason your getting a problem is probably because of your usage of the form_tag helper uses the :remote and :method values inside the url generation instead of being handled be the form. The correct usage would probably be like this:
<%= form_tag({:controller => "sessions", :action => "awisprotect"},
:remote => true,
:method => "post")
However, Rails already has a helper method to create a button to submit data called button_to. It basically takes the exact same arguments as the link_to helper so I would probably use it like this in your case:
<%= button_to "x", awisprotect_path, :remote => true, :method => :post %>
The :method argument could possibly even be left out because I think the button_to helper defaults to the POST protocol.
You can disguise a link as a button, using some CSS. Here's a nice article.
This might be better than all these experiments with partials and forms. :-)
I'm thinking you didn't wrap the options for form_tag properly. Try something like this:
form_tag( { :controller => :sessions, :action => :awisprotect, :method => post }, { :remote => true } ) do ....
It may or may not also help to use button_tag.
I am trying to create a form which loads upon a user clicking a date in a calendar, the form then is passed the date that is clicked through the URL and the controller assigns that date to the #date variable. I then create a date_select element and assign it the #date variable. This works fine but since I do not want the user to be able to edit the date in the form I want it to be hidden.
I pass these html options to the form but it doesn't seem to ever effect the HTML:
<%= f.date_select :date, :default => #date, :type => "hidden" %>
Am I missing something? I also tried passing it in an HTML hash :html => { :type = "hidden" } but that doesn't work either. Even when I try something different like :class => "something" it doesn't change the HTML. Is there something special about the date_select helper?
date_select accepts the options discard_day, discard_month and discard_year to do exactly what you are trying to achieve.
<%= f.date_select :date, { :discard_day => true, :discard_month => true, :discard_year => true } %>
Behind the scenes, it generates the following HTML code:
<input id="record_date_3i" name="record[date(3i)]" type="hidden" value="5" />
<input id="record_date_2i" name="record[date(2i)]" type="hidden" value="1" />
<input id="record_date_1i" name="record[date(1i)]" type="hidden" value="2012" />
No CSS tricks, no changes in your controllers.
Per the name, date_select generates <select> elements. In no version of (X)HTML does the select element support the type attribute. If you want a hidden form field then you should use the hidden_field helper, which generates <input type="hidden"> elements.
(To answer your implied question about using e.g. :class => 'something', the problem is that the options and html_arguments parameters must be two separate hashes, but if you do something like this:
<%= f.date_select :date, :default => #date, :class => 'something' %>
..the Ruby interpreter assumes that you have supplied a single hash, i.e. { :default => #date, :class => 'something' } (and really, can you blame it?), and since class isn't a valid key for the options hash it's ignored. Instead you have to make it obvious to Ruby that these are two separate parameters by doing something like this instead:
<%= f.date_select :date, :default => #date, { :class => 'something' } %>
<%# Hey Ruby, this is a different Hash! ----^ %>
See the difference? Of course you could go bonkers and be really obvious, e.g.:
<%= f.date_select(:date, { :default => #date }, { :class => 'something' }) %>
..but that's ugly and egregious so don't bother.)
You can put it inside a hidden div:
<div style="display: none;">
<%= f.date_select :date, :default => #date, :type => "hidden" %>
</div>
That will allow you to have all the fields and hidden you can also use for date and time select:
<div style="display: none;">
<%= f.datetime_select :date, :default => #date, :type => "hidden" %>
</div>
i have used observed_field for arrays of data... but i am having trouble making a simple, one field application of it work. i must be missing a very simple detail. have searched extensively for basic syntax and cannot find anything that applies. when i change the selection, the change is not saved and there is no error msg.
<% form_for :team, :url => update_item_leader_group_path do |f| %>
<%= f.select :item_id, #selection_collection %>
<span id="trigger_spinner" style="visibility: hidden;">
<img src="/images/spinner.gif" alt="Loading..." />
</span>
<%= observe_field 'group_item_id',
:url => { :controller => :group, :action => :update_item },
:method => :put,
:with => "'trig=' + $('group_item_id').value" %>
:loading => "$('trigger_spinner').setStyle({visibility: 'visible'});",
:complete => "$('trigger_spinner').setStyle({visibility: 'hidden'});" %>
<% end %>
The onchange event may not be observed until you leave the focus of the select field. To watch some field changes instantly your only option is to use a form observer.
BTW: The dom id of your field is probably not item_id due to usage of the form builder. #Swards already pointed that out.
The id of the field is usually something like id='group_item_id', could this be the issue?
corrected syntax above
1. form path
2. observer "url"
3. observer "with"
there was also a routing problem. i had to move update_item from a map.resources member to collection