I have a form with a hidden field that contains the current date.
I'm trying to figure out how to write a capybara finder to:
Check that the field is there
Check the value of the field
Is this possible with Capybara?
just do this:
find("#id_of_hidden_input", :visible => false).value
the matcher has_field? works with hidden fields as well. no need to do weird gymnastics with find or all in this context.
page.has_field? "label of the field", type: :hidden, with: "field value"
page.has_field? "id_of_the_field", type: :hidden, with: "field value"
the key here is setting the :type option to :hidden explicitly.
why use a label with a hidden field? this comes in handy if you're using a js library, like flatpickr, that cloaks your original text field to hide it. not coupling your behavior tests to specific markup is always a good thing.
You could also instruct Capybara to not ignore hidden elements globally in your spec_helper.rb or equivalent. The default behaviour can be overridden:
# default behavior for hidden elements
# Capybara.ignore_hidden_elements = false
# find all elements (hidden or visible)
page.all(".articles .article[id='foo']")
# find visible elements only (overwrite the standard behavior just for this query)
page.all(".articles .article[id='foo']", :visible => true)
# changing the default behavior (e.g. in your features/support/env.rb file)
Capybara.ignore_hidden_elements = true
# now the query just finds visible nodes by default
page.all(".articles .article[id='foo']")
# but you can change the default behaviour by passing the :visible option again
page.all(".articles .article[id='foo']", :visible => false)
Examples taken from this article.
its simple you can do it by using find_by_css or by using xpath as follow
page.find_by_css('#foo .bar a') #foo is the id the foo has .bar class
page.find('/table/tbody/tr[3]') #path of the element we want to find
Related
Using globalize gem to manage translations with autocomplete, there is a situation where a number of hooks need to be properly set. Note: this does not use hstore AFAIK. I have not managed to find a way to do so. The most productive set-up to date has
controller:
autocomplete :nation, :name, :full => true
Nation
translates :name
view
<%= autocomplete_field_tag 'nation_name', '', autocomplete_nation_name_itins_path, size: 35, :id_element => 'nation_id' %>
There is no inherent reference to nation_translations database table created by Globalize as of yet. As this image suggests, there is a problem:
Issue 1: The input remains binded to the base table's attribute value (I have not yet cleared them out as the Globalize gem suggests. Otherwise I'd be getting blanks). can is actually ready all values of canin master table... Typing in other locales, like cyrillic say Канада has naturally no effect as that value is not part of the Nation table.
What is interesting is that the drop-down values are being populated by Rails automatically, extracting the translation values of what is input.
Issue 2: I'd rather pass the parameter 'nation_id' which is naturally part of the nation_translations table with the form data. although I can append , :extra_data => [:nation_id] to the controller it is not being submitted (example in cyrillic where the input is given without any autocomplete)
{"utf8"=>"✓", "nation_name"=>"Канада", "commit"=>"..."}
Rails.logger.info :extra_data returns:
extra_data
Now the second issue can be overcome because a query like
Nation::Translation.where('name = ?', "Канада").pluck('nation_id')
returns a proper result. But that point is moot if the autocomplete is not playing ball with the user's input.
How can this be configured to have user input autocomplete with the current local translations?
this does get solved by creating an entirely new class with attributes nation_id, name, locale and can thus be called symbolically.
The query call is not that straightforward however. As the gem suggests, the method need to be tweaked
def autocomplete_nation_name
term = params[:term].downcase
locale = params[:locale]
nationtranslations = Nationtranslation.where('locale = ? AND name LIKE ?', locale, "%#{term}%").order(:name).all
render :json => nationtranslations.map { |nationtranslation| {:id => nationtranslation.id, :label => nationtranslation.name, :value => nationetranslation.name} }
end
intervening on the action method itself provides all the leeway desired...
I use Rails 5 and simple_form gem with Bootstrap preconfigured on installation (if its matter).
The problem is: on form render first field that has error should be focused. In case if there's no errors let's focus the first row.
This gem has ability to use autofocus: true on fields, but putting this attribute at every field in form view destroys simplicity of 'simple_form'. The only solution I found is to override check for autofocus field attribute and force to set it when the field has an error and autofocus attribute is not set:
module SimpleForm
module Helpers
module Autofocus
private
def has_autofocus?
options[:autofocus] == true || has_errors?
end
end
end
end
For the case when form has no errors I use explicitly set autofocus on first field:
= simple_form_for object do |f|
= f.input :to, autofocus: true
= f.input :cc
= f.input :subject
= f.input :body, input_html: {rows: 10}
So, the question is: is there a better way to set autofocus attribute dynamically, without overriding this getter? (No JS please, let's play with plain HTML attributes) I couldn't find a way to implement this scenario using form builders (like builders that simple_form generates at config/initializers), but maybe there's a solution with tricky composition of builders? Or maybe there can be a simpler and less dangerous override?
As there is no suitable solution to this issue I came up with a small but hacky solution.
At first you need to enable the inclusion of custom components in your simple_form initializer config/initializers/simple_form.rb :
# Uncomment this and change the path if necessary to include your own
# components.
# See https://github.com/heartcombo/simple_form#custom-components to know
# more about custom components.
Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
Still in the initializer add the autofocus_on_error component:
# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
...
config.wrappers :default, class: :input,
...
# If a form has invalid fields, automatically set the focus on the first
# field with an error
b.use :autofocus_on_error
end
end
Now create the actual component in lib/components/autofocus_on_error_component.rb:
module AutofocusOnErrorComponent
def autofocus_on_error(wrapper_options = nil)
if has_errors? && !inputs_with_autofocus_present?
input_html_options[:autofocus] = true
end
nil
end
private
def inputs_with_autofocus_present?
#builder.template.output_buffer.include?('autofocus="autofocus"')
end
end
SimpleForm.include_component(AutofocusOnErrorComponent)
Finally restart your webserver to reflect the changes.
I want to test my models on ActiveAdmin by creating them manually. On one of my model, a field says 'Must contain specific value' whatever i write in it. This attribute can only contain a value from a list which is predefined. I suppose this field should not be a text field but a combobox filed with the values of this list. I looked for it on Google but can't find the answer.what I have tried upto is bellow
f.input :modele, :as => :select, :collection => proc{current_route.modele.all}
but it doesn't work and worse I don't understand what I'm doing.
I have a field in my database called property_types which has a string value and the values can be "Condo" or "Single Family Home" or "Commercial". I want to display each property type in the user's search form with a check box next to each property type so the user can select which property types should be included in their search results.
But if the property_type field is not a boolean and it has several possible values how do I do this using check_box_tag which can only have a true or false value?
EDIT:
I added this checkbox code to properties/index where the search form is and the search results are displayed:
<%= check_box_tag(:condo, value = "1", checked = true) %>
In properties_controller I added this:
#properties = #properties.where(:property_type => "Condo") if params[:condo].present?
Ofcourse it doesn't work because I haven't got a clue what I'm doing but is this along the right lines or not?
Well, looking at you requirements i would suggest you to leave the values at true and false, and on your controller, when you persist the object, you check all possibilities that are checked (true) and put you project_types attribute together.
project_types += 'condo&' if params[:condo]
project_types += 'commercial&' if params[:commercial]
...
Of course the & i put in the examples are just for demonstration, as i don't know how you would create this string.
EDIT:
Well, maybe you should refactor your model. I believe it would be easier if the project_types attribute didn't exist, and instead, you had several boolean attributes named after your strings. Then you can search like this:
#properties.where(:condo => params[:condo], :commercial => params[:commercial])
And it would be easier to understand the code.
I have a form. Many of the labels need to have a different name than they are given in the model.
attr_accessible :pin
Simpleform view:
= f.input :pin, :label => "Secret Code"
When validation fails, the error uses the model's name for the field ("Pin"), rather than the label I set in the view ("Secret Code"). The user will be confused on what field has the error.
Currently I have a helper that changes the label:
def fix_pin_errors(msg)
msg.gsub!('Pin', 'Secret Code')
end
If I am doing this for many fields, however, it becomes tedious and not DRY.
What is the best way to have errors match labels that differ from the names the model gives them?
I18n is your friend. Read this guide. It will explain how to globally convert these so they get picked up everywhere you need.
For your example, it might look something like this:
In en.yml:
en:
activerecord:
attributes:
your_model_name:
pin: 'Secret Code'