How to get data from input field using ruby on rails - ruby-on-rails

How to get data from an HTML text field and use it in RoR?
For example, let's say I enter a word in the text field and RoR prints how many characters are in said word.

Best way to do that is using the JAVASCRIPT but you insist for ROR use observe_field
<%= text_field :users, :word, :value=>'', :autocomplete=>'off' %><br>
<span id="word_message" style="color :red; font-size: 9px;"></span>
<%= observe_field :users_word, :url => { :action => :word_length, :id=>1 },
:on=>"blur",
:frequency => 0.25,
:with => "'word='+value" %>
In Controller
def word_length
word = params[:word]
render :update do |page|
page.replace_html 'word_message', "#{word.length} characters"
end
end

Related

How can you auto-generate placeholder text based on the field name in Rails?

I have a reusable field template, called _field.html.haml, that looks like (in haml):
= f.label field
= f.send(field_type, field, :class => field_type)
The advantage of this is that it can be called from a parent form template and provides reusability. This lets me dynamically render form fields based on a field type. The calling template looks like:
= form_for(#model) do |f|
= render :partial => 'field', :locals => { :field => :first_name, :field_type => :text_field }
= render :partial => 'field', :locals => { :field => :last_name, :field_type => :text_field }
How could I add auto-generating of the placeholder text based on the label text to this _field.html.haml template? Maybe the correct question is what is the code that the label hdlper uses to convert the field name to an capitalized english phrase?
I.e. code would look like:
= f.send(field_type, field, :class => field_type, :placeholder => #INSERT CODE HERE to get friendly placeholder text)
the label_tag method uses `String#humanize" to make it look nicer (http://api.rubyonrails.org/classes/String.html#method-i-humanize). So in your example you could do:
= f.send(field_type, field, :class => field_type, :placeholder => field.to_s.humanize)
As previously mentioned in the comments, you should have a look at available form-builders. They abstract a lot of pain associated with making nice forms. Some links are:
https://github.com/plataformatec/simple_form
https://github.com/justinfrench/formtastic

Rails: How to render repetitive form block?

In order to not repeat myself, I would like to create a function that render a form block (text field or text area) in a specific way. I want a result like this one (using Haml, and twitter-bootstrap):
.form-block.input-prepend
%span.add-on>
%i.icon.icon-home
= f.text_field :name, :value => #store.name, :placeholder => 'Company Name'
To do that, I created a file views/layouts/_form-block.html.haml where I inserted the following code:
.form-block.input-prepend
%span.add-on>
%i{ :class => "icon icon-#{icon}" }
= yield
And I call the block in my view using:
- render :template => 'layouts/_form-block', :locals => { :icon => 'home' } do
= f.text_field :name, :value => #store.name, :placeholder => 'Company Name'
But It doesn't work. I have the following error 'nil' is not an ActiveModel-compatible object that returns a valid partial path.
Do you have any idea? Is this the best way to do?
Thanks in advance.
If you want to use = yield to pass a block, you need to render as a layout. Use render :layout => instead of render :template =>.

convert string in a field name rails

a need how convert string value in field name valid:
Example:
<%="price.list_"+current_user.price.to_s%>
so
price.list_1
then is my real field name. this name.this field will use it to do more operations in my view.
I think I understood your question. You will need to use the send function
<%= price.send("list_#{current_user.price}".to_sym) %>
That should work but you can also do
<%= "price.list_#{current_user.price.to_s}" %>
OR
<p>
price.list_<%= current_user.price.to_s %>
</p>
UPDATE: I misunderstood the question. This is going to require some Javascript or AJAX, depending on your exact application.
JS:
:onchange => 'update(this.value)'
function update(new_value) {
var update_me = document.getElementById('update_this_field');
update_me.value = new_value;
}
AJAX on RAILS
:onchange => remote_function(:url => {:action => 'update'}, :with => 'Form.element.serialize(this)'), :name => 'foo'
def update
bar = params[:foo]
render :update do |page|
page.replace_html 'update_this_field', "price.list_" + bar
end
end

Ajax observe_field not working on ruby on rails

I am trying to create some kind of search in my ruby on rails application and I want to add ajax support. I want when a user types in a search box a word, ajax automatically generates the results. And I have searched almost all internet and I couldn't find answer to following question:
When I type into my text area nothing happens. It is like ajax is not working at all.
Tre problem is in observe_field which should observe my id= 'query' but it seem like it not doing anything
I am using Prototype 1.6.1 and the newest version of rails.
The code I wrote is:
viewer:
<form name="sform" action="" style="display:inline;">
<label for="item_name">Filter on Property No : </label>
<%= text_field_tag(:query, params['query'], :size => 10, :id => 'query' ) %>
</form>
<%= image_tag("/images/system/blue_small.gif",
:align => "absmiddle",
:border => 0,
:id => "spinner",
:style =>"display: none;" ) %>
</p>
<%= observe_field 'query', :frequency => 1,
:update => 'table',
:before => "$('#spinner').show()",
:success => "$('#spinner').hide()",
:url => {:action => 'list'},
:with => 'query' %>
<div id="table">
<%= render :partial => "items_list" %>
</div>
And my controler is:
def list
sort = case params['sort']
when "Title" then "title"
when "address" then "address"
when "close date" then "close_date"
when "property_no_reverse" then "property_no DESC"
when "address_reverse" then "address DESC"
when "close_date_reverse" then "close_date DESC"
end
conditions = ["title LIKE ?", "%#{params[:query]}%"] unless params[:query].nil?
#total = Message.count(:conditions => conditions)
#accounts = Message.paginate :page => params[:page], :per_page => 10, :order => sort, :conditions => conditions
if request.xml_http_request?
render :partial => "items_list", :layout => false
end
end
I would greatly appreciate any help I can get!
You said your using the newest version of Rails, if that is Rails 3.0.0 then observe_field and the way they are doing javascript is definitely different. Either downgrade to Rails 2.3.8 (I would not), learn the new way, or use the old way in Rails 3.0.0
New Way in Rails 3.0.0: http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/
Old way in Rails 3.0.0: http://github.com/rails/prototype_legacy_helper
If you want 2.3.8 I can show you observe field, just let me know...

Ruby on Rails Country/State Select Enigma

I am trying to implement something seemingly very simple, and I have been beating my head against it for days at this point.
My desired end result is a Country select drop-down, tied to a State select drop-down, in such a way that when a given country is selected, IF states are known THEN those states are displayed in a select drop down, and if NO states are known for that country, then a text field is displayed instead.
I feel like I am almost there. At this point the interface will actually generate that list of states based on the persons' country, except it is refusing to update the drop-down dynamically.
The portion of my view where country and state location is gathered looks like:
# _person_setup.html.erb
<td>
<%= f.label :country, 'Select your country' %>*<br />
<%= f.select :country, Carmen::country_names, {},
{:style => 'width: 200px',
:id => 'country_select',
:onchange => remote_function(
:url => {:action => 'update_states'},
:with => "'country='+value")} %>
</td><td>
<p>
<div id="states_div">
<%= render :partial => 'states',
:object => Carmen::states(
Carmen::country_code(
#person.country)),
:locals => {:form => f} %>
</div>
</p>
</td>
The partial being referenced in the DIV is as follows:
# _states.html.erb
<% unless states.nil? or states.empty? %>
<%= form.label :state, 'Select your state' %>*<br />
<%= form.select :state, states.collect{|s| [s[0], s[0]]} %>
<% else %>
<%= form.label :state, 'Please enter state or province' %>*<br />
<%= form.text_field :state %>
<% end %>
Finally, the controller code which is intended to update the list of states dynamically:
def update_states
puts "Attempting to update states..."
q = params[:country]
states = Carmen::states(Carmen::country_code(q))
puts "Country = #{q}, states = #{states.collect{|s| s[0]}.join(", ")}."
render :update do |page|
page.replace_html "states_div",
:partial => 'states',
:object => states,
:locals => {:form => form_for(#person)}
end
puts "OK"
end
Now, this code is being called at the proper time and generating the appropriate lists of states. For example, when the user clicks Australia, "Attempting to update states... Country = Australia, states = Australian Capital Territory, New South Wales, Northern Territory, Queensland, South Australia, Tasmania, Victoria, Western Australia" shows up in the server process. However it doesn't update the page, and won't print the "OK" at the end. In short the line which is failing is undoubtedly
page.replace_html "states_div",
:partial => 'states',
:object => states,
:locals => {:form => form_for(#person)}
Note that replacing this line with
page.replace_html 'states_div', "<b>is it working</b>"
properly replaces the div, but of course not with anything useful.
Can someone help me understand what is going on here?
It looks like you're assuming that the #person variable is still available from your original action. This could be set up by a filter for the current person but you don't show that in your question.
If you do need to lookup the #person again you'll have to pass the id through in your remote_function I think.
Ryan Bates has a Railscast that shows how to select a category for a product or create a new category by typing the name. It sounds like a similar scenario to what you have, so you might want to check it out: Create Model Through Text Field.
This took me a full day to figure out something that would at least "work". I am also using Carmen and also messing with the select tag in a form_for model form (actually, fields_for nested within forms_for...which adds additional complications).
I would think there is a better solution but this worked for me. The select needs to be referenced by the form but the options don't. Thus, first time through, I use the Carmen state_select method which populates the select tag correctly and all the nested options tags. The second time through, I just replace the options. Take a look:
In the view, I chose to use an observe_field method since I do other things besides update the states (some other localization changes) but this should work for remote_function and others, too:
<%= address_form.country_select :country, {:prompt => "--Select One--"} %>
Don't be confused by the id (user_address_attributes_country) it is just my silly forms_for/fields_for implementation)
<%= observe_field :user_address_attributes_country, :url => { :action => :changecountry }, :with => 'new_country' %>
<%= address_form.state_select :state, #user.address.country, {:prompt => "--Select One--"}, :style => 'width: 90px' %>
Then in my controller, it just looks like this:
def changecountry
c = params[:new_country]
respond_to do |format|
format.html
format.js {
render :update do |page|
page['user_address_attributes_state'].innerHTML = \
"<option>--Select One--</option>" + state_options_for_select(nil, c)
end
}
end
end
Note: state_options_for_select is also from Carmen. I could not get it to work unless I put it inside the respond_to block where I guess the view helpers are available. Also, I hard code user_address_attributes_state which is my nested id generated from the form_for/fields_for address_form.state_select rendering call in the view.
I hope this helps. If anyone can do it better, believe me, I'm all ears. I'll change the design in time...but needed something that just worked today and this was the best I could figure out in a limited time.

Resources