Skip to content

Instantly share code, notes, and snippets.

/val.diff Secret

Created September 21, 2015 19:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/138d1b6559b3a7f612e8 to your computer and use it in GitHub Desktop.
Save anonymous/138d1b6559b3a7f612e8 to your computer and use it in GitHub Desktop.
diff --git a/lib/Mojo/DOM.pm b/lib/Mojo/DOM.pm
index 43dc64e..57297a6 100644
--- a/lib/Mojo/DOM.pm
+++ b/lib/Mojo/DOM.pm
@@ -159,6 +159,21 @@ sub tree { shift->_delegate(tree => @_) }
sub type { shift->tree->[0] }
+sub val {
+ my $self = shift;
+
+ # "option"
+ my $tag = $self->tag;
+ return $self->{value} // $self->text if $tag eq 'option';
+
+ # "select"
+ return $self->find('option[selected]')->map('val')->to_array
+ if $tag eq 'select';
+
+ # "textarea", "input" or "button"
+ return $tag eq 'textarea' ? $self->text : $self->{value};
+}
+
sub wrap { shift->_wrap(0, @_) }
sub wrap_content { shift->_wrap(1, @_) }
@@ -927,6 +942,29 @@ C<root>, C<tag> or C<text>.
# "text"
$dom->parse('<p>Test</p>')->at('p')->child_nodes->first->type;
+=head2 val
+
+ my $value = $dom->val;
+
+Extract values from C<button>, C<input>, C<option>, C<select> or C<textarea>
+element and return a L<Mojo::Collection> object containing these values. In
+the case of C<select>, find all C<option> elements it contains that have a
+C<selected> attribute and extract their values.
+
+Extract values from C<button>, C<input>, C<option>, C<select> and C<textarea>
+elements or return C<undef> if this element has no value. In the case of
+C<select>, find a C<option> elements with C<selected> attribute and return an
+array reference with all values.
+
+ # "b"
+ $dom->parse('<input name="a" value="b">')->at('input')->val;
+
+ # "c"
+ $dom->parse('<option value="c">Test</option>')->at('option')->val;
+
+ # "d"
+ $dom->parse('<option>d</option>')->at('option')->val;
+
=head2 wrap
$dom = $dom->wrap('<div></div>');
diff --git a/t/mojo/dom.t b/t/mojo/dom.t
index 2a9f6ed..82be8be 100644
--- a/t/mojo/dom.t
+++ b/t/mojo/dom.t
@@ -2173,6 +2173,41 @@ is $dom->at('div pre code')->all_text, "like\n it\n really", 'right text';
is $dom->at('div pre code')->all_text(0), "like\n it\n really",
'right text';
+# Form values
+$dom = Mojo::DOM->new(<<EOF);
+<form action="/foo">
+ <p>Test</p>
+ <input type="text" name="a" value="A" />
+ <input type="checkbox" checked name="b" value="B">
+ <input type="radio" checked name="c" value="C">
+ <select name="f">
+ <option value="F">G</option>
+ <optgroup>
+ <option>H</option>
+ <option selected>I</option>
+ </optgroup>
+ <option value="J" selected>K</option>
+ </select>
+ <select name="n"><option>N</option></select>
+ <select name="d"><option selected>D</option></select>
+ <textarea name="m">M</textarea>
+ <button name="o" value="O">No!</button>
+ <input type="submit" name="p" value="P" />
+</form>
+EOF
+is $dom->at('p')->val, undef, 'no value';
+is $dom->at('input')->val, 'A', 'right value';
+is $dom->at('input:checked')->val, 'B', 'right value';
+is $dom->at('input:checked[type=radio]')->val, 'C', 'right value';
+is_deeply $dom->at('select')->val, ['I', 'J'], 'right values';
+is $dom->at('select option')->val, 'F', 'right value';
+is $dom->at('select optgroup option:not([selected])')->val, 'H', 'right value';
+is $dom->find('select')->[1]->at('option')->val, 'N', 'right value';
+is_deeply $dom->find('select')->last->val, ['D'], 'right values';
+is $dom->at('textarea')->val, 'M', 'right value';
+is $dom->at('button')->val, 'O', 'right value';
+is $dom->find('form input')->last->val, 'P', 'right value';
+
# PoCo example with whitespace sensitive text
$dom = Mojo::DOM->new(<<EOF);
<?xml version="1.0" encoding="UTF-8"?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment