Class: Mechanize::Form
- Inherits:
-
Object
- Object
- Mechanize::Form
- Extended by:
- ElementMatcher
- Defined in:
- lib/mechanize/form.rb,
lib/mechanize/inspect.rb,
lib/mechanize/form/field.rb,
lib/mechanize/form/button.rb,
lib/mechanize/form/option.rb,
lib/mechanize/monkey_patch.rb,
lib/mechanize/form/check_box.rb,
lib/mechanize/form/file_upload.rb,
lib/mechanize/form/image_button.rb,
lib/mechanize/form/radio_button.rb
Overview
Synopsis
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. See GlobalForm for more methods.
Example
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, 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_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.
- #keys ⇒ Object
-
#method_missing(meth, *args) ⇒ Object
Treat form fields like accessors.
- #pretty_print(q) ⇒ Object
-
#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.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/mechanize/form.rb', line 48 def initialize(node, mech=nil, page=nil) @enctype = node['enctype'] || 'application/x-www-form-urlencoded' @form_node = node @action = 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.
154 155 156 157 158 159 160 161 162 163 |
# File 'lib/mechanize/form.rb', line 154 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.
29 30 31 |
# File 'lib/mechanize/form.rb', line 29 def action @action end |
#buttons ⇒ Object (readonly)
Returns the value of attribute buttons.
31 32 33 |
# File 'lib/mechanize/form.rb', line 31 def @buttons end |
#checkboxes ⇒ Object (readonly)
Returns the value of attribute checkboxes.
31 32 33 |
# File 'lib/mechanize/form.rb', line 31 def checkboxes @checkboxes end |
#encoding ⇒ Object
Character encoding of form data (i.e. UTF-8)
37 38 39 |
# File 'lib/mechanize/form.rb', line 37 def encoding @encoding end |
#enctype ⇒ Object
Content-Type for form data (i.e. application/x-www-form-urlencoded)
34 35 36 |
# File 'lib/mechanize/form.rb', line 34 def enctype @enctype end |
#fields ⇒ Object (readonly) Also known as: elements
Returns the value of attribute fields.
31 32 33 |
# File 'lib/mechanize/form.rb', line 31 def fields @fields end |
#file_uploads ⇒ Object (readonly)
Returns the value of attribute file_uploads.
31 32 33 |
# File 'lib/mechanize/form.rb', line 31 def file_uploads @file_uploads end |
#form_node ⇒ Object (readonly)
Returns the value of attribute form_node.
45 46 47 |
# File 'lib/mechanize/form.rb', line 45 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
41 42 43 |
# File 'lib/mechanize/form.rb', line 41 def ignore_encoding_error @ignore_encoding_error end |
#method ⇒ Object
Returns the value of attribute method.
29 30 31 |
# File 'lib/mechanize/form.rb', line 29 def method @method end |
#name ⇒ Object
Returns the value of attribute name.
29 30 31 |
# File 'lib/mechanize/form.rb', line 29 def name @name end |
#page ⇒ Object (readonly)
Returns the value of attribute page.
46 47 48 |
# File 'lib/mechanize/form.rb', line 46 def page @page end |
#radiobuttons ⇒ Object (readonly)
Returns the value of attribute radiobuttons.
31 32 33 |
# File 'lib/mechanize/form.rb', line 31 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']
135 136 137 138 |
# File 'lib/mechanize/form.rb', line 135 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'
144 145 146 147 148 149 150 151 |
# File 'lib/mechanize/form.rb', line 144 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.
241 242 243 |
# File 'lib/mechanize/form.rb', line 241 def () @clicked_buttons << end |
#add_field!(field_name, value = nil) ⇒ Object
Add a field with field_name
and value
100 101 102 |
# File 'lib/mechanize/form.rb', line 100 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.
194 195 196 197 198 199 200 201 202 203 204 205 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 |
# File 'lib/mechanize/form.rb', line 194 def build_query( = []) query = [] @mech.log.info("form encoding: #{encoding}") if @mech && @mech.log (fields + checkboxes).sort.each do |f| case f when Form::CheckBox if f.checked qval = proc_query(f) query.push(*qval) end when Form::Field qval = proc_query(f) query.push(*qval) 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 qval = proc_query(f) query.push(*qval) elsif checked.size > 1 raise Mechanize::Error, "multiple radiobuttons are checked in the same group!" end end @clicked_buttons.each { |b| qval = proc_query(b) query.push(*qval) } query end |
#button ⇒ Object
:method: buttons_with(criteria)
Find all buttons that match criteria
Example:
form.(:value => /submit/).each do ||
.value = 'hello!'
end
311 |
# File 'lib/mechanize/form.rb', line 311 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
365 |
# File 'lib/mechanize/form.rb', line 365 elements_with :checkbox, :checkboxes |
#click_button(button = buttons.first) ⇒ Object
Submit form using button
. Defaults to the first button.
172 173 174 |
# File 'lib/mechanize/form.rb', line 172 def ( = .first) submit() end |
#delete_field!(field_name) ⇒ Object
Removes all fields with name field_name
.
273 274 275 |
# File 'lib/mechanize/form.rb', line 273 def delete_field!(field_name) @fields.delete_if{ |f| f.name == field_name} 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")
95 96 97 |
# File 'lib/mechanize/form.rb', line 95 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
293 |
# File 'lib/mechanize/form.rb', line 293 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
329 |
# File 'lib/mechanize/form.rb', line 329 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
64 65 66 |
# File 'lib/mechanize/form.rb', line 64 def has_field?(field_name) fields.find { |f| f.name == field_name } end |
#has_value?(value) ⇒ Boolean
70 71 72 |
# File 'lib/mechanize/form.rb', line 70 def has_value?(value) fields.find { |f| f.value == value } end |
#hidden_field?(field_name) ⇒ Boolean
87 |
# File 'lib/mechanize/form.rb', line 87 def hidden_field?(field_name) hiddens.find{|f| f.name == field_name}; end |
#hiddens ⇒ Object
81 |
# File 'lib/mechanize/form.rb', line 81 def hiddens ; @hiddens ||= fields.select { |f| f.class == Hidden }; end |
#keys ⇒ Object
74 |
# File 'lib/mechanize/form.rb', line 74 def keys; fields.map { |f| f.name }; end |
#pretty_print(q) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/mechanize/inspect.rb', line 55 def pretty_print(q) 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
347 |
# File 'lib/mechanize/form.rb', line 347 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,
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/mechanize/form.rb', line 248 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
85 |
# File 'lib/mechanize/form.rb', line 85 def () resets.find{|f| f.name == }; end |
#resets ⇒ Object
79 |
# File 'lib/mechanize/form.rb', line 79 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 field 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' } )
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/mechanize/form.rb', line 112 def set_fields(fields = {}) fields.each do |k,v| case v when Hash v.each do |index, value| self.fields_with(:name => k.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 => k.to_s).[](index).value = value end end end |
#submit(button = nil, headers = {}) ⇒ Object
Submit this form with the button passed in
166 167 168 |
# File 'lib/mechanize/form.rb', line 166 def submit =nil, headers = {} @mech.submit(self, , headers) end |
#submit_button?(button_name) ⇒ Boolean
84 |
# File 'lib/mechanize/form.rb', line 84 def () submits.find{|f| f.name == }; end |
#submits ⇒ Object
78 |
# File 'lib/mechanize/form.rb', line 78 def submits ; @submits ||= .select { |f| f.class == Submit }; end |
#text_field?(field_name) ⇒ Boolean
86 |
# File 'lib/mechanize/form.rb', line 86 def text_field?(field_name) texts.find{|f| f.name == field_name}; end |
#textarea_field?(field_name) ⇒ Boolean
88 |
# File 'lib/mechanize/form.rb', line 88 def textarea_field?(field_name) textareas.find{|f| f.name == field_name}; end |
#textareas ⇒ Object
82 |
# File 'lib/mechanize/form.rb', line 82 def textareas; @textareas ||= fields.select { |f| f.class == Textarea }; end |
#texts ⇒ Object
80 |
# File 'lib/mechanize/form.rb', line 80 def texts ; @texts ||= fields.select { |f| f.class == Text }; end |
#values ⇒ Object
76 |
# File 'lib/mechanize/form.rb', line 76 def values; fields.map { |f| f.value }; end |