-1

I’m using Rails 4.2.7 with Nokogiri. Is there a way I can tell, with Nokogiri, that one of the options in my select menu contains the word "Results" in its text field (that would be visible to the end user)?

I have:

options = doc.css("#menu_id option")

And I can cycle through all of them, checking the text, but I figured there might be a CSS-selector expression or something similar I can do with Nokogiri that would tell me this answer more quickly.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • Why? You should know whether the menu contains that because you programmed the view. Is this for a unit test? Also, you probably want to adjust something on your system because it's inserting curly-quotes in places that would be syntactically incorrect in code; They're extremely difficult to debug. – the Tin Man Sep 26 '16 at 16:28

2 Answers2

1

This is the generic way to do it:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
  <body>
    <form>
      <select id="menu_id">
        <option value="foo">foo</option>
      </select>
    </form>
  </body>
</html>
EOT

doc.search('#menu_id option').any?{ |option| option.text == 'foo' } # => true

That looks to see if the text, not the value, is "foo".

doc.search('#menu_id option').any?{ |option| option.text['foo'] } # => true

That looks to see if the text, not the value, contains the sub-string "foo".

doc.search('#menu_id option').any?{ |option| option['value'] == 'foo' } # => true

That looks to see if the value parameter matches the word "foo".

Similarly, they'll tell you whether something doesn't match:

doc.search('#menu_id option').any?{ |option| option.text == 'bar' } # => false
doc.search('#menu_id option').any?{ |option| option.text['bar'] } # => false
doc.search('#menu_id option').any?{ |option| option['value'] == 'bar' } # => false

I would probably rely on Nokogiri's implementation of the jQuery extensions that @gmcnaughton mentioned but that's how I am. YMMV.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
0

Nokogiri supports jQuery's :contains selector, which selects nodes with the given content:

doc.css(ā€œ#menu_id option:contains('Results'")

You could also do it with an XPath, which has more power but is more verbose:

doc.xpath('//*[@id='menu_id']//option[contains(text(), "Results")]')

See "Nokogiri: How to select nodes by matching text?".

Community
  • 1
  • 1
gmcnaughton
  • 2,233
  • 1
  • 21
  • 28