diff --git a/lib/Mojo/DOM.pm b/lib/Mojo/DOM.pm
index 927d5e8..e982333 100644
--- a/lib/Mojo/DOM.pm
+++ b/lib/Mojo/DOM.pm
@@ -176,6 +176,25 @@ sub type {
   return $self;
 }
 
+sub val {
+  my $self = shift;
+
+  # Element
+  return $self->_val unless $self->type eq 'form';
+
+  # Form
+  my ($form, $val) = ({});
+  for my $e ($self->find('select, textarea')->each) {
+    $form->{$e->{name}} = $val if defined($val = $e->_val);
+  }
+  for my $e ($self->find('input')->each) {
+    next if +(grep { $_ eq $e->{type} || '' } qw( radio checkbox )) && !defined $self->{checked};
+    $form->{$e->{name}} = $val if defined($val = $e->_val);
+  }
+
+  return %$form ? $form : undef;
+}
+
 sub wrap         { shift->_wrap(0, @_) }
 sub wrap_content { shift->_wrap(1, @_) }
 
@@ -353,6 +372,25 @@ sub _text {
   return $text;
 }
 
+sub _val {
+  my $self = shift;
+
+  # "option"
+  return $self->{value} // $self->text if $self->type eq 'option';
+
+  # "textarea"
+  return $self->text if $self->type eq 'textarea';
+
+  # "select"
+  if ($self->type eq 'select') {
+    my @values = map { $_->val } $self->find('option[selected]')->each;
+    return !@values ? undef : @values == 1 ? $values[1] : \@values;
+  }
+
+  # "input"
+  return $self->{value};
+}
+
 sub _wrap {
   my ($self, $content, $new) = @_;
 
@@ -824,6 +862,22 @@ This element's type.
   # List types of child elements
   say $dom->children->type;
 
+=head2 val
+
+  my $value = $dom->val;
+
+Extract values from C<form>, C<input>, C<select>, C<option> and C<textarea>
+elements or return C<undef>.
+
+In case of C<select> this method will find all the C<option>s that is selected.
+Returns a plain string if only one option was found, returns C<undef> if no
+options was found and returns an array ref if more than one option was found.
+
+In case of C<form> it will fetch the values from all the form field elements
+that is checked, selected or has a value and return them in a hash ref
+structure, where the keys are field names and the values are as described
+above.
+
 =head2 wrap
 
   $dom = $dom->wrap('<div></div>');