Class: Mechanize::Form
- Inherits:
-
Object
- Object
- Mechanize::Form
- Extended by:
- ElementMatcher
- Defined in:
- lib/mechanize/form.rb
Overview
This class encapsulates a form parsed out of an HTML page. Each type of input fields available in a form can be accessed through this object.
Examples
Find a form and print out its fields
form = page.forms.first # => Mechanize::Form
form.fields.each { |f| puts f.name }
Set the input field ‘name’ to “Aaron”
form['name'] = 'Aaron'
puts form['name']
Defined Under Namespace
Classes: Button, CheckBox, Field, FileUpload, Hidden, ImageButton, Keygen, MultiSelectList, Option, RadioButton, Reset, SelectList, Submit, Text, Textarea
Instance Attribute Summary collapse
-
#action ⇒ Object
Returns the value of attribute action.
-
#buttons ⇒ Object
readonly
Returns the value of attribute buttons.
-
#checkboxes ⇒ Object
readonly
Returns the value of attribute checkboxes.
-
#encoding ⇒ Object
Character encoding of form data (i.e. UTF-8).
-
#enctype ⇒ Object
Content-Type for form data (i.e. application/x-www-form-urlencoded).
-
#fields ⇒ Object
(also: #elements)
readonly
Returns the value of attribute fields.
-
#file_uploads ⇒ Object
readonly
Returns the value of attribute file_uploads.
-
#form_node ⇒ Object
readonly
Returns the value of attribute form_node.
-
#ignore_encoding_error ⇒ Object
When true, character encoding errors will never be never raised on form submission.
-
#method ⇒ Object
Returns the value of attribute method.
-
#name ⇒ Object
Returns the value of attribute name.
-
#page ⇒ Object
readonly
Returns the value of attribute page.
-
#radiobuttons ⇒ Object
readonly
Returns the value of attribute radiobuttons.
Instance Method Summary collapse
-
#[](field_name) ⇒ Object
Fetch the value of the first input field with the name passed in ==Example Fetch the value set in the input field ‘name’ puts form.
-
#[]=(field_name, value) ⇒ Object
Set the value of the first input field with the name passed in ==Example Set the value in the input field ‘name’ to “Aaron” form = ‘Aaron’.
-
#add_button_to_query(button) ⇒ Object
This method adds a button to the query.
-
#add_field!(field_name, value = nil) ⇒ Object
Add a field with
field_name
andvalue
. -
#build_query(buttons = []) ⇒ Object
This method builds an array of arrays that represent the query parameters to be used with this form.
-
#button ⇒ Object
:method: buttons_with(criteria).
-
#checkbox ⇒ Object
:method: checkboxes_with(criteria).
-
#click_button(button = buttons.first) ⇒ Object
Submit form using
button
. -
#delete_field!(field_name) ⇒ Object
Removes all fields with name
field_name
. -
#dom_class ⇒ Object
This method is a shortcut to get form’s DOM class.
-
#dom_id ⇒ Object
This method is a shortcut to get form’s DOM id.
-
#field ⇒ Object
:method: fields_with(criteria).
-
#file_upload ⇒ Object
:method: file_uploads_with(criteria).
-
#has_field?(field_name) ⇒ Boolean
(also: #has_key?)
Returns whether or not the form contains a field with
field_name
. - #has_value?(value) ⇒ Boolean
- #hidden_field?(field_name) ⇒ Boolean
- #hiddens ⇒ Object
-
#initialize(node, mech = nil, page = nil) ⇒ Form
constructor
A new instance of Form.
- #keygens ⇒ Object
- #keys ⇒ Object
-
#method_missing(meth, *args) ⇒ Object
Treat form fields like accessors.
-
#pretty_print(q) ⇒ Object
:nodoc:.
-
#radiobutton ⇒ Object
:method: radiobuttons_with(criteria).
-
#request_data ⇒ Object
This method calculates the request data to be sent back to the server for this form, depending on if this is a regular post, get, or a multi-part post,.
- #reset_button?(button_name) ⇒ Boolean
- #resets ⇒ Object
-
#set_fields(fields = {}) ⇒ Object
This method sets multiple fields on the form.
-
#submit(button = nil, headers = {}) ⇒ Object
Submit this form with the button passed in.
- #submit_button?(button_name) ⇒ Boolean
- #submits ⇒ Object
- #text_field?(field_name) ⇒ Boolean
- #textarea_field?(field_name) ⇒ Boolean
- #textareas ⇒ Object
- #texts ⇒ Object
- #values ⇒ Object
Methods included from ElementMatcher
Constructor Details
#initialize(node, mech = nil, page = nil) ⇒ Form
Returns a new instance of Form.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/mechanize/form.rb', line 41 def initialize(node, mech=nil, page=nil) @enctype = node['enctype'] || 'application/x-www-form-urlencoded' @form_node = node @action = Mechanize::Util.html_unescape(node['action']) @method = (node['method'] || 'GET').upcase @name = node['name'] @clicked_buttons = [] @page = page @mech = mech @encoding = node['accept-charset'] || (page && page.encoding) || nil @ignore_encoding_error = false parse end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ Object
Treat form fields like accessors.
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/mechanize/form.rb', line 165 def method_missing(meth, *args) method = meth.to_s.gsub(/=$/, '') if field(method) return field(method).value if args.empty? return field(method).value = args[0] end super end |
Instance Attribute Details
#action ⇒ Object
Returns the value of attribute action.
22 23 24 |
# File 'lib/mechanize/form.rb', line 22 def action @action end |
#buttons ⇒ Object (readonly)
Returns the value of attribute buttons.
24 25 26 |
# File 'lib/mechanize/form.rb', line 24 def @buttons end |
#checkboxes ⇒ Object (readonly)
Returns the value of attribute checkboxes.
24 25 26 |
# File 'lib/mechanize/form.rb', line 24 def checkboxes @checkboxes end |
#encoding ⇒ Object
Character encoding of form data (i.e. UTF-8)
30 31 32 |
# File 'lib/mechanize/form.rb', line 30 def encoding @encoding end |
#enctype ⇒ Object
Content-Type for form data (i.e. application/x-www-form-urlencoded)
27 28 29 |
# File 'lib/mechanize/form.rb', line 27 def enctype @enctype end |
#fields ⇒ Object (readonly) Also known as: elements
Returns the value of attribute fields.
24 25 26 |
# File 'lib/mechanize/form.rb', line 24 def fields @fields end |
#file_uploads ⇒ Object (readonly)
Returns the value of attribute file_uploads.
24 25 26 |
# File 'lib/mechanize/form.rb', line 24 def file_uploads @file_uploads end |
#form_node ⇒ Object (readonly)
Returns the value of attribute form_node.
38 39 40 |
# File 'lib/mechanize/form.rb', line 38 def form_node @form_node end |
#ignore_encoding_error ⇒ Object
When true, character encoding errors will never be never raised on form submission. Default is false
34 35 36 |
# File 'lib/mechanize/form.rb', line 34 def ignore_encoding_error @ignore_encoding_error end |
#method ⇒ Object
Returns the value of attribute method.
22 23 24 |
# File 'lib/mechanize/form.rb', line 22 def method @method end |
#name ⇒ Object
Returns the value of attribute name.
22 23 24 |
# File 'lib/mechanize/form.rb', line 22 def name @name end |
#page ⇒ Object (readonly)
Returns the value of attribute page.
39 40 41 |
# File 'lib/mechanize/form.rb', line 39 def page @page end |
#radiobuttons ⇒ Object (readonly)
Returns the value of attribute radiobuttons.
24 25 26 |
# File 'lib/mechanize/form.rb', line 24 def @radiobuttons end |
Instance Method Details
#[](field_name) ⇒ Object
Fetch the value of the first input field with the name passed in
Example
Fetch the value set in the input field ‘name’
puts form['name']
146 147 148 149 |
# File 'lib/mechanize/form.rb', line 146 def [](field_name) f = field(field_name) f && f.value end |
#[]=(field_name, value) ⇒ Object
Set the value of the first input field with the name passed in
Example
Set the value in the input field ‘name’ to “Aaron”
form['name'] = 'Aaron'
155 156 157 158 159 160 161 162 |
# File 'lib/mechanize/form.rb', line 155 def []=(field_name, value) f = field(field_name) if f f.value = value else add_field!(field_name, value) end end |
#add_button_to_query(button) ⇒ Object
This method adds a button to the query. If the form needs to be submitted with multiple buttons, pass each button to this method.
257 258 259 |
# File 'lib/mechanize/form.rb', line 257 def () @clicked_buttons << end |
#add_field!(field_name, value = nil) ⇒ Object
Add a field with field_name
and value
103 104 105 |
# File 'lib/mechanize/form.rb', line 103 def add_field!(field_name, value = nil) fields << Field.new({'name' => field_name}, value) end |
#build_query(buttons = []) ⇒ Object
This method builds an array of arrays that represent the query parameters to be used with this form. The return value can then be used to create a query string for this form.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/mechanize/form.rb', line 206 def build_query( = []) query = [] @mech.log.info("form encoding: #{encoding}") if @mech && @mech.log successful_controls = [] (fields + checkboxes).sort.each do |f| case f when Mechanize::Form::CheckBox if f.checked successful_controls << f end when Mechanize::Form::Field successful_controls << f end end radio_groups = {} .each do |f| fname = from_native_charset(f.name) radio_groups[fname] ||= [] radio_groups[fname] << f end # take one radio button from each group radio_groups.each_value do |g| checked = g.select {|f| f.checked} if checked.size == 1 f = checked.first successful_controls << f elsif checked.size > 1 raise Mechanize::Error, "multiple radiobuttons are checked in the same group!" end end @clicked_buttons.each { |b| successful_controls << b } successful_controls.sort.each do |ctrl| # DOM order qval = proc_query(ctrl) query.push(*qval) end query end |
#button ⇒ Object
:method: buttons_with(criteria)
Find all buttons that match criteria
Example:
form.(:value => /submit/).each do ||
.value = 'hello!'
end
327 |
# File 'lib/mechanize/form.rb', line 327 elements_with :button |
#checkbox ⇒ Object
:method: checkboxes_with(criteria)
Find all checkboxes that match criteria
Example:
form.checkboxes_with(:name => /woo/).each do |field|
field.check
end
381 |
# File 'lib/mechanize/form.rb', line 381 elements_with :checkbox, :checkboxes |
#click_button(button = buttons.first) ⇒ Object
Submit form using button
. Defaults to the first button.
183 184 185 |
# File 'lib/mechanize/form.rb', line 183 def ( = .first) submit() end |
#delete_field!(field_name) ⇒ Object
Removes all fields with name field_name
.
289 290 291 |
# File 'lib/mechanize/form.rb', line 289 def delete_field!(field_name) @fields.delete_if{ |f| f.name == field_name} end |
#dom_class ⇒ Object
This method is a shortcut to get form’s DOM class. Common usage:
page.form_with(:dom_class => "foorm")
Note that you can also use :class
to get to this method:
page.form_with(:class => "foorm")
98 99 100 |
# File 'lib/mechanize/form.rb', line 98 def dom_class form_node['class'] end |
#dom_id ⇒ Object
This method is a shortcut to get form’s DOM id. Common usage:
page.form_with(:dom_id => "foorm")
Note that you can also use :id
to get to this method:
page.form_with(:id => "foorm")
89 90 91 |
# File 'lib/mechanize/form.rb', line 89 def dom_id form_node['id'] end |
#field ⇒ Object
:method: fields_with(criteria)
Find all fields that match criteria
Example:
form.fields_with(:value => /foo/).each do |field|
field.value = 'hello!'
end
309 |
# File 'lib/mechanize/form.rb', line 309 elements_with :field |
#file_upload ⇒ Object
:method: file_uploads_with(criteria)
Find all file upload fields that match criteria
Example:
form.file_uploads_with(:file_name => /picutre/).each do |field|
field.value = 'foo!'
end
345 |
# File 'lib/mechanize/form.rb', line 345 elements_with :file_upload |
#has_field?(field_name) ⇒ Boolean Also known as: has_key?
Returns whether or not the form contains a field with field_name
57 58 59 |
# File 'lib/mechanize/form.rb', line 57 def has_field?(field_name) fields.find { |f| f.name == field_name } end |
#has_value?(value) ⇒ Boolean
63 64 65 |
# File 'lib/mechanize/form.rb', line 63 def has_value?(value) fields.find { |f| f.value == value } end |
#hidden_field?(field_name) ⇒ Boolean
81 |
# File 'lib/mechanize/form.rb', line 81 def hidden_field?(field_name) hiddens.find{|f| f.name == field_name}; end |
#hiddens ⇒ Object
74 |
# File 'lib/mechanize/form.rb', line 74 def hiddens ; @hiddens ||= fields.select { |f| f.class == Hidden }; end |
#keygens ⇒ Object
76 |
# File 'lib/mechanize/form.rb', line 76 def keygens ; @keygens ||= fields.select { |f| f.class == Keygen }; end |
#keys ⇒ Object
67 |
# File 'lib/mechanize/form.rb', line 67 def keys; fields.map { |f| f.name }; end |
#pretty_print(q) ⇒ Object
:nodoc:
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/mechanize/form.rb', line 383 def pretty_print(q) # :nodoc: q.object_group(self) { q.breakable; q.group(1, '{name', '}') { q.breakable; q.pp name } q.breakable; q.group(1, '{method', '}') { q.breakable; q.pp method } q.breakable; q.group(1, '{action', '}') { q.breakable; q.pp action } q.breakable; q.group(1, '{fields', '}') { fields.each do |field| q.breakable q.pp field end } q.breakable; q.group(1, '{radiobuttons', '}') { .each { |b| q.breakable; q.pp b } } q.breakable; q.group(1, '{checkboxes', '}') { checkboxes.each { |b| q.breakable; q.pp b } } q.breakable; q.group(1, '{file_uploads', '}') { file_uploads.each { |b| q.breakable; q.pp b } } q.breakable; q.group(1, '{buttons', '}') { .each { |b| q.breakable; q.pp b } } } end |
#radiobutton ⇒ Object
:method: radiobuttons_with(criteria)
Find all radio buttons that match criteria
Example:
form.(:name => /woo/).each do |field|
field.check
end
363 |
# File 'lib/mechanize/form.rb', line 363 elements_with :radiobutton |
#request_data ⇒ Object
This method calculates the request data to be sent back to the server for this form, depending on if this is a regular post, get, or a multi-part post,
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/mechanize/form.rb', line 264 def request_data query_params = build_query() case @enctype.downcase when /^multipart\/form-data/ boundary = rand_string(20) @enctype = "multipart/form-data; boundary=#{boundary}" params = query_params.map do |k,v| param_to_multipart(k, v) if k end.compact params.concat @file_uploads.map { |f| file_to_multipart(f) } params.map do |part| part.force_encoding('ASCII-8BIT') if part.respond_to? :force_encoding "--#{boundary}\r\n#{part}" end.join('') + "--#{boundary}--\r\n" else Mechanize::Util.build_query_string(query_params) end end |
#reset_button?(button_name) ⇒ Boolean
79 |
# File 'lib/mechanize/form.rb', line 79 def () resets.find{|f| f.name == }; end |
#resets ⇒ Object
72 |
# File 'lib/mechanize/form.rb', line 72 def resets ; @resets ||= .select { |f| f.class == Reset }; end |
#set_fields(fields = {}) ⇒ Object
This method sets multiple fields on the form. It takes a list of fields
which are name, value pairs.
If there is more than one field found with the same name, this method will set the first one found. If you want to set the value of a duplicate field, use a value which is a Hash with the key as the index in to the form. The index is zero based.
For example, to set the second field named ‘foo’, you could do the following:
form.set_fields :foo => { 1 => 'bar' }
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/mechanize/form.rb', line 121 def set_fields fields = {} fields.each do |name, v| case v when Hash v.each do |index, value| self.fields_with(:name => name.to_s)[index].value = value end else value = nil index = 0 [v].flatten.each do |val| index = val.to_i if value value = val unless value end self.fields_with(:name => name.to_s)[index].value = value end end end |
#submit(button = nil, headers = {}) ⇒ Object
Submit this form with the button passed in
177 178 179 |
# File 'lib/mechanize/form.rb', line 177 def submit =nil, headers = {} @mech.submit(self, , headers) end |
#submit_button?(button_name) ⇒ Boolean
78 |
# File 'lib/mechanize/form.rb', line 78 def () submits.find{|f| f.name == }; end |
#submits ⇒ Object
71 |
# File 'lib/mechanize/form.rb', line 71 def submits ; @submits ||= .select { |f| f.class == Submit }; end |
#text_field?(field_name) ⇒ Boolean
80 |
# File 'lib/mechanize/form.rb', line 80 def text_field?(field_name) texts.find{|f| f.name == field_name}; end |
#textarea_field?(field_name) ⇒ Boolean
82 |
# File 'lib/mechanize/form.rb', line 82 def textarea_field?(field_name) textareas.find{|f| f.name == field_name}; end |
#textareas ⇒ Object
75 |
# File 'lib/mechanize/form.rb', line 75 def textareas; @textareas ||= fields.select { |f| f.class == Textarea }; end |
#texts ⇒ Object
73 |
# File 'lib/mechanize/form.rb', line 73 def texts ; @texts ||= fields.select { |f| f.class == Text }; end |
#values ⇒ Object
69 |
# File 'lib/mechanize/form.rb', line 69 def values; fields.map { |f| f.value }; end |