简体   繁体   中英

How to count the number of *visible* rows in an HTML table?

I'm meant to display a (read-only, no filtering, no lazy-loading) table in PrimeFaces (5.2), where the table should extend all the way down to the footer with "empty rows", should there not be enough rows. The footer has a fixed position, and so the table gets a scrollbar if there are too many rows. It seems the standard solution to getting empty rows is to return "fake rows" along with the result. But I do not know how many to return, because the server does not know how many rows the client can see, so I return more then could be reasonably seen (100). My plan was then to remove the unneeded dummy rows with JavaScript, by checking their "visibility", but this proves to be an impossible task. No method of checking visibility I have seen so far work. My table is defined as follow:

<p:dataTable id="tableId" var="orderView" value="#{orderTable.getPaddedOrderViews(100)}" 
          emptyMessage="EMPTY" scrollable="true" scrollHeight="550"
          resizableColumns="true" resizeMode="fit">
    ...

(getPaddedOrderViews(100) should return at least 100 rows, padding with dummy rows if needed)

and the following code should find the visible/invisible rows (so I can change it to remove the invisible dummy rows later):

      function isVisible1(ele) {
          if (ele !== null &&
              ele !== undefined &&
              ele.clientWidth !== 0 &&
              ele.clientHeight !== 0) {
              var style = window.getComputedStyle(ele,null);
              return style !== null &&
                  style !== undefined &&
                  style.opacity !== 0 &&
                  style.visibility !== 'hidden' &&
                  style.display !== 'none';
          }
          return false;
      }
      function isVisible2(ele) {
          return ele !== null &&
              ele !== undefined &&
              ele.clientWidth !== 0 &&
              ele.clientHeight !== 0 &&
              ele.style !== null &&
              ele.style !== undefined &&
              ele.style.opacity !== 0 &&
              ele.style.visibility !== 'hidden' &&
              ele.style.display !== 'none';
      }
      function isVisible3(ele) {
          return ele.offsetWidth > 0 || ele.offsetHeight > 0;
      }
      function countVisibleRows() {
          var count = 0;
          var result1 = 0;
          var result2 = 0;
          var result3 = 0;
          var r;
          for (r in document.getElementById("tableId_data").rows) {
              count++;
              /*
              FAILS BECAUSE window.getComputedStyle(ele,null) says
              argument 1 is not an object
              if (isVisible1(r)) {
                  result1++;
              }*/
              if (isVisible2(r)) {
                  result2++;
              }
              if (isVisible3(r)) {
                  result3++;
              }
          }
          return [count,result1,result2,result3];
      }

        jQuery(document).ready(function () {
            jQuery(document).ready(function () {
                // twice in document.ready to execute after Primefaces callbacks
                try {
                    alert("ROWS: "+countVisibleRows());
                }
                catch(err) {
                    alert(err.message);
                }
            });
        });

But it displays "ROWS: [103,0,0,0]" for a table where I can see about 22 (non empty/dummy) rows (the number I was hoping to get), with more hidden. Some are my dummy rows, but I cannot see any of them in this case. The 103 proves (IMHO), that I am correctly fetching the rows.

isVisible1(ele) fails when calling window.getComputedStyle(ele,null). isVisible2(ele) always returns false because no row has a style property, and isVisible3(ele) also always returns false.

So, why haven't the rows got any 'style', and how can I tell if they are visible without this 'style'?

Many questions/solutions regarding counting the visible rows where only for "filtered" tables, but that does not apply in my case.

If the number of visible rows can somehow be extracted from the table itself, rather then checking the rows, that would solve my problem too.

I based myself on this question to find out how to check visibility.

If I understand properly you want to remove the overflow rows.

Since you are using jQuery can do this fairlry easily by comparing the offset of the rows to the offset of the bottom of the container

var $cont = $('#container')
var contBottom = $cont.height() + $cont.offset().top;

$('tr').filter(function () {
    var $row = $(this),
        top = $row.offset().top,
        ht = $row.height();        
    return (top + ht) > contBottom;
}).remove()

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM