Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions pyquery/pyquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,11 @@ def val(self, value=no_default):
['you', 'hou']

"""
def _option_value(option):
# Missing value attr uses option text (HTML / jQuery).
val = option.attr('value')
return option.text() if val is None else val

def _get_value(tag):
# <textarea>
if tag.tag == 'textarea':
Expand All @@ -1012,13 +1017,15 @@ def _get_value(tag):
selected = self._copy(tag)('option[selected]')
# Rebuild list to avoid serialization error
return list(selected.map(
lambda _, o: self._copy(o).attr('value')
lambda _, o: _option_value(self._copy(o))
))
selected_option = self._copy(tag)('option[selected]:last')
if selected_option:
return selected_option.attr('value')
else:
return self._copy(tag)('option').attr('value')
return _option_value(selected_option)
first = self._copy(tag)('option:first')
if first:
return _option_value(first)
return None
# <input type="checkbox"> or <input type="radio">
elif self.is_(':checkbox,:radio'):
val = self._copy(tag).attr('value')
Expand Down
21 changes: 21 additions & 0 deletions tests/test_pyquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,27 @@ def test_val_for_multiple_elements(self):
self.assertEqual(d('#second').val(), '42')
self.assertEqual(d('#third').val(), '42')

def test_val_select_option_without_value_attr(self):
d = pq('<select><option>a</option><option selected>b</option></select>')
self.assertEqual(d.val(), 'b')
d = pq('<select><option>first</option><option>second</option></select>')
self.assertEqual(d.val(), 'first')
d = pq('<select><option selected value="">empty</option></select>')
self.assertEqual(d.val(), '')
d = pq(
'<select multiple>'
'<option selected>a</option>'
'<option selected>b</option>'
'</select>'
)
self.assertEqual(d.val(), ['a', 'b'])
form = pq(
'<form><select name="s">'
'<option>t1</option><option selected>t2</option>'
'</select></form>'
)
self.assertEqual(form.serialize_pairs(), [('s', 't2')])

def test_val_checkbox_no_value_attribute(self):
d = pq('<input type="checkbox">')
self.assertEqual(d.val(), 'on')
Expand Down
Loading