Skip to content

Instantly share code, notes, and snippets.

@ryanbriones
Created February 6, 2014 14:44
Show Gist options
  • Save ryanbriones/8845507 to your computer and use it in GitHub Desktop.
Save ryanbriones/8845507 to your computer and use it in GitHub Desktop.
Is there something in Ruby (in an existing gem?) that will take an HTML String, parse out a form, and return URI-encoded query string of the fields/values a la jQuery's form.serialize?
<form>
<input type="text" name="post[title]" value="Some Title" />
<textarea name="post[body]">This is my post body</textarea>
</form>
post[title]=Some%20Title&post[body]=This%20is%20my%20post%20body
@ryanbriones
Copy link
Author

This is what I've manually coded up:

# Parse the HTML into Nokogiri-searchable nodes
html_nodes = Nokogiri::HTML(html)
name_value_pairs = []
# Find the first form element in the page
html_nodes.search("form").first.tap do |form|
  # Search that form element for form fields
  form.search("input, select, textarea").each do |form_field|
    name = form_field.attributes["name"].to_s
    # Different form fields store their value in different ways...
    value = case form_field.name
            when "input" then form_field.attributes["value"].to_s
            when "textarea" then form_field.text.to_s
            when "select"
              selected_option_fields = form_field.search("option[selected]")
              unless selected_option_fields.size > 0
                raise "No option 'selected' for field '#{name}'"
              end

              selected_option_fields.last.attributes["value"].to_s
            end
    name_value_pairs << [name, URI.encode(value)]
  end
end

# Build up a URI query string of name/value pairs
# param1=someValue&param2=someOtherValue
query = name_value_pairs.map { |pair| pair.join("=") }.join("&")

@jnicklas
Copy link

jnicklas commented Feb 6, 2014

html = Nokogiri::HTML("...")
params = Capybara::RackTest::Form.new(nil, html).params({})
Rack::Utils.build_nested_query(params) #=> yay!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment