I want to count all table rows which class name is subjectField and to stop counting if some row's class name is separator.

HTML:

<div id="household" class="block">

<div class="block_title"> … </div>
<table class="color_table">
    <thead> … </thead>
    <tbody>
        <tr class="first_row"> … </tr>
        <tr class="subjectField" style="display:none"> … </tr>
        <tr class="odd_row"> … </tr>
        <tr class="subjectField" style="display:none"> … </tr>
        <tr class="even_row"> … </tr>
        <tr class="subjectField" style="display:none"> … </tr>
        <tr>
            <td class="separator" rowspan="1" colspan="10">
            </td>
        </tr>
        <tr class="even_row"> … </tr>
        <tr class="subjectField" style="display:none"> … </tr>
    </tbody>
</table>
</div>

My code:

def countRows
    @subjects = 0
    @f.div(:id => 'household').table(:class => 'color_table').tbody.trs.find do |tr|            
    if tr.td(:class => "separator").exists? == true
        break
    elsif tr(:class => "subjectField").exists? == true
        @subjects = @subjects + 1
    end         
end
return subjects
end

This does not work for me. It says that tr on line 6 is undefined method.

Does anybody know how to solve this problem?

有帮助吗?

解决方案

Issue 1 - Checking row class

You are passing tr parameters, which is why Ruby thinks it is a method. In this case, tr is actually an element that is selected for the current iteration of the loop. To check the current tr's class attribute, the elsif statement should be:

elsif tr.class_name == "subjectField"

Issue 2 - Iterating rows

Note that you will also have a problem with the line:

@f.div(:id => 'household').table(:class => 'color_table').tbody.trs.find

The find method will iterate through the trs until the block evaluates as true. Since the block will always evaluate to true or break, you will only get 0 or 1 subjects. Use each instead:

@f.div(:id => 'household').table(:class => 'color_table').tbody.trs.each

Putting it together

Putting the above fixes together, the method could be written as:

def countRows
  @subjects = 0
  table = @f.div(:id => 'household').table(:class => 'color_table')
  table.tbody.trs.each do |tr|            
    break if tr.td(:class => "separator").exists? == true

    @subjects += 1 if tr.class_name == "subjectField"
  end         
  @subjects
end

其他提示

This is how i would do that (untested code):

def count_rows
  @f.div(:id => 'household')
    .table(:class => 'color_table')
    .trs
    .take_while {|row| !row.td(:class => "separator").exists? }
    .select {|row| row.class_name =~ /subjectField/}
    .size
end
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top