2021年3月6日 星期六

jQuery Mobile 學習筆記 (十九) : 表格

上回在疫苗登記專案中要顯示受試者表格時頗傷腦筋, 因為當欄位太多時, 由於手機螢幕寬度限制, jQuery Mobile 會將每列紀錄先逐欄再逐列以 key:value 方式 一一條列, 這就失去了表格讓人對資料一目瞭然的用意, 所幸後來參考了網路上一篇文章的做法後才順利搞定表格問題, 參考 : 


不過今天在下面這兩本書中找到了正統的解決方案 : 


原來 jQuery Mobile 對於 table 元素有提供 data-role="table" 這個屬性, 但只有用這屬性也無作用, 還需搭配 data-mode=columntoggle 屬性, 以及在 th 元素中設定 data-priority 才算完整, 以下是測試紀錄. 參考 :


本系列測試文章索引參考 :


由於懶得打資料, 所以從 2014 年的測試文章中拿現成股票表格資料來用, 參考 : 




<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
  </head>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>表格測試</h1>
      </header>
      <article data-role="content">
        <table data-role="table">
          <thead>
            <tr>
              <th>股票名稱</th>
              <th>股票代號</th>
              <th>收盤價 (元)</th>
              <th>成交量 (張)</th>
              <th>股東會日期</th>
              <th>董監改選</th>
              <th>類股</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>台積電</td>
              <td>2330</td>
              <td>123</td>
              <td>4425119</td>
              <td>2014-06-04</td>
              <td>0</td>
              <td>半導體</td>
            </tr>
            <tr>
              <td>中華電</td>
              <td>2412</td>
              <td>96.4</td>
              <td>5249</td>
              <td>2014-06-15</td>
              <td>0</td>
              <td>通信</td>
            </tr>
            <tr>
              <td>中碳</td>
              <td>1723</td>
              <td>192.5</td>
              <td>918</td>
              <td>2014-07-05</td>
              <td>0</td>
              <td>塑化</td>
            </tr>
            <tr>
              <td>創見</td>
              <td>2451</td>
              <td>108</td>
              <td>733</td>
              <td>2014-06-30</td>
              <td>0</td>
              <td>模組</td>
            </tr>
            <tr>
              <td>華擎</td>
              <td>3515</td>
              <td>118.5</td>
              <td>175</td>
              <td>2014-07-20</td>
              <td>0</td>
              <td>主機板</td>
            </tr>
            <tr>
              <td>訊連</td>
              <td>5203</td>
              <td>97</td>
              <td>235</td>
              <td>2014-05-31</td>
              <td>0</td>
              <td>軟體</td>
            </tr>
          </tbody>
        </table>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
  </body>
</html>

此例只是在 table 元素上添加了 data-role="table", 瀏覽結果如下 :




這與一般對表格的理解差距實在太大, 失去表格資料統整的作用. 此例測試網頁 QR code 為 :




要讓表格以桌上型瀏覽器的效果呈現, 還需在 table 元素中添加 data-mode="columntoggle" 與 class="ui-responsive" 屬性, 例如 : 


測試 2 : 表格測試 (搭配 data-mode 與 class 等屬性才有效果) [看原始碼]

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
  </head>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>表格測試</h1>
      </header>
      <article data-role="content">
        <table data-role="table" border="1" class="ui-responsive"  data-mode="columntoggle" data-column-btn-text="欄位選擇">
          <thead>
            <tr>
              <th>股票名稱</th>
              <th>股票代號</th>
              <th>收盤價 (元)</th>
              <th>成交量 (張)</th>
              <th data-priority="3">股東會日期</th>
              <th data-priority="2">董監改選</th>
              <th data-priority="1">類股</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>台積電</td>
              <td>2330</td>
              <td>123</td>
              <td>4425119</td>
              <td>2014-06-04</td>
              <td>0</td>
              <td>半導體</td>
            </tr>
            <tr>
              <td>中華電</td>
              <td>2412</td>
              <td>96.4</td>
              <td>5249</td>
              <td>2014-06-15</td>
              <td>0</td>
              <td>通信</td>
            </tr>
            <tr>
              <td>中碳</td>
              <td>1723</td>
              <td>192.5</td>
              <td>918</td>
              <td>2014-07-05</td>
              <td>0</td>
              <td>塑化</td>
            </tr>
            <tr>
              <td>創見</td>
              <td>2451</td>
              <td>108</td>
              <td>733</td>
              <td>2014-06-30</td>
              <td>0</td>
              <td>模組</td>
            </tr>
            <tr>
              <td>華擎</td>
              <td>3515</td>
              <td>118.5</td>
              <td>175</td>
              <td>2014-07-20</td>
              <td>0</td>
              <td>主機板</td>
            </tr>
            <tr>
              <td>訊連</td>
              <td>5203</td>
              <td>97</td>
              <td>235</td>
              <td>2014-05-31</td>
              <td>0</td>
              <td>軟體</td>
            </tr>
          </tbody>
        </table>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
  </body>
</html>

此例給 table 元素添加了下列三個屬性 :
  1. class="ui-responsive" : 使表格具有自適應性, 可隨欄位多寡自行調節寬度
  2. data-mode="columntoggle" : 可選擇要顯示之次要欄位 (th 添加 data-priority 屬性者)
  3. data-column-btn-text="選擇欄位" : 設定欄位挑選按鈕上的文字
其中 data-mode 屬性會在表格右上方設置一個欄位挑選按鈕, 預設文字為 "Column...", 可用 data-column-btn-text 屬性更改. 另外 th 欄位可添加 data-priority 屬性表示當螢幕寬度夠大時會被保留的優先權, 其值範圍 1~6 (1 優先權最高), 無 data-priority 者為必須顯示之欄位. 結果如下 :




可見因為螢幕寬度夠, 所以優先權最高的 "類股" 欄位被保留顯示, 優先權 2/3 者則被隱藏. 按右上方的欄位選擇鈕可以手動切換要顯示哪些有設 data-priority 屬性的欄位 :




勾選顯示全部欄位 : 

 


可見由於添加了 class="ui-responsive" 樣式類別, 當顯示更多欄位時會自動調整各欄寬度以便容納全部資料. 此例測試網頁 QR code 如下 :




利用樣式設定可以讓表格外觀更豐富, 例如隔列交替變換底色等, 可使用純 CSS 設定, 但使用 jQuery 更簡單, 只要利用偽類選擇器選取偶數列之後呼叫 addClass() 套用樣式即可, 參考 :




<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
  </head>
  <style>
    table {border: 1px solid #007108;
           border-collapse: collapse;
           background-color: #d9ffdc}
    th {border: 1px solid #007108; 
        padding:6px; 
        background-color: #a16128;
        color: white;}
    td {border: 1px solid #007108; padding:6px;}
    .altrow {background-color: #a5e5aa;}    
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>表格測試</h1>
      </header>
      <article data-role="content">
        <table data-role="table" border="1" class="ui-responsive ui-shadow"  data-mode="columntoggle" data-column-btn-text="欄位選擇">
          <thead>
            <tr>
              <th>股票名稱</th>
              <th>股票代號</th>
              <th>收盤價 (元)</th>
              <th>成交量 (張)</th>
              <th data-priority="3">股東會日期</th>
              <th data-priority="2">董監改選</th>
              <th data-priority="1">類股</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>台積電</td>
              <td>2330</td>
              <td>123</td>
              <td>4425119</td>
              <td>2014-06-04</td>
              <td>0</td>
              <td>半導體</td>
            </tr>
            <tr>
              <td>中華電</td>
              <td>2412</td>
              <td>96.4</td>
              <td>5249</td>
              <td>2014-06-15</td>
              <td>0</td>
              <td>通信</td>
            </tr>
            <tr>
              <td>中碳</td>
              <td>1723</td>
              <td>192.5</td>
              <td>918</td>
              <td>2014-07-05</td>
              <td>0</td>
              <td>塑化</td>
            </tr>
            <tr>
              <td>創見</td>
              <td>2451</td>
              <td>108</td>
              <td>733</td>
              <td>2014-06-30</td>
              <td>0</td>
              <td>模組</td>
            </tr>
            <tr>
              <td>華擎</td>
              <td>3515</td>
              <td>118.5</td>
              <td>175</td>
              <td>2014-07-20</td>
              <td>0</td>
              <td>主機板</td>
            </tr>
            <tr>
              <td>訊連</td>
              <td>5203</td>
              <td>97</td>
              <td>235</td>
              <td>2014-05-31</td>
              <td>0</td>
              <td>軟體</td>
            </tr>
          </tbody>
        </table>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        $("tr:nth-child(even)").addClass("altrow");    
        });
    </script>
  </body>
</html>

此例用 tr:nth-child(even) 選取偶數列後套用 altrow 樣式類別, 結果如下 : 




此例測試網頁 QR code 如下 :



下面範例為改用藍色系被景色, 並且在列的 hover 事件發生時更改那列底色為黃色 :



<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
  </head>
  <style>
    table {border: 1px solid #0058a3;
           border-collapse: collapse;
           background-color: #eaf5ff}
    th {border: 1px solid #0058a3; 
        padding:6px; 
        background-color: #4bacff;
        color: #ffffff;}
    td {border: 1px solid #0058a3; padding:6px;}
    .altrow {background-color: #c4e4ff;}
    .highlight {background-color: yellow;}    
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>表格測試</h1>
      </header>
      <article data-role="content">
        <table data-role="table" border="1" class="ui-responsive ui-shadow"  data-mode="columntoggle" data-column-btn-text="欄位選擇">
          <thead>
            <tr>
              <th>股票名稱</th>
              <th>股票代號</th>
              <th>收盤價 (元)</th>
              <th>成交量 (張)</th>
              <th data-priority="3">股東會日期</th>
              <th data-priority="2">董監改選</th>
              <th data-priority="1">類股</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>台積電</td>
              <td>2330</td>
              <td>123</td>
              <td>4425119</td>
              <td>2014-06-04</td>
              <td>0</td>
              <td>半導體</td>
            </tr>
            <tr>
              <td>中華電</td>
              <td>2412</td>
              <td>96.4</td>
              <td>5249</td>
              <td>2014-06-15</td>
              <td>0</td>
              <td>通信</td>
            </tr>
            <tr>
              <td>中碳</td>
              <td>1723</td>
              <td>192.5</td>
              <td>918</td>
              <td>2014-07-05</td>
              <td>0</td>
              <td>塑化</td>
            </tr>
            <tr>
              <td>創見</td>
              <td>2451</td>
              <td>108</td>
              <td>733</td>
              <td>2014-06-30</td>
              <td>0</td>
              <td>模組</td>
            </tr>
            <tr>
              <td>華擎</td>
              <td>3515</td>
              <td>118.5</td>
              <td>175</td>
              <td>2014-07-20</td>
              <td>0</td>
              <td>主機板</td>
            </tr>
            <tr>
              <td>訊連</td>
              <td>5203</td>
              <td>97</td>
              <td>235</td>
              <td>2014-05-31</td>
              <td>0</td>
              <td>軟體</td>
            </tr>
          </tbody>
        </table>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        $("tr:nth-child(even)").addClass("altrow");
        $("tr").hover(function(){  
          $(this).toggleClass("highlight");  
          });  
        });
    </script>
  </body>
</html>

結果如下 : 




此例測試網頁 QR code 如下 :




如果表格內容太長須上下捲動操作與閱讀較麻煩, 這時可以改用分頁來展示表格, 亦即固定每頁顯示之筆數, 將整份內容拆成好幾頁, 利用分頁切換按鈕選擇要看的那一頁, 我找到下面兩個分頁解決方案 :


第一個方案利用 Javascript 與 CSS 控制分頁; 第二個是將 jQuery UI 中的 Datagrid 外掛拿來給 jQuery Mobile 用, 看來是沒問題的. 第一個方案的原始碼放在 jsfiddle 上, 參考 : 


我將其原始碼稍作修改後與上面的範例 4 整合為如下的範例 5 :


 
<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
  </head>
  <style>
    table {border: 1px solid #0058a3;
           border-collapse: collapse;
           background-color: #eaf5ff}
    th {border: 1px solid #0058a3; 
        padding:6px; 
        background-color: #4bacff;
        color: #ffffff;}
    td {border: 1px solid #0058a3; padding:6px;}
    .altrow {background-color: #c4e4ff;}
    .highlight {background-color: yellow;}
    div.pager {text-align: center; margin: 1em 0;}
    div.pager span {
        display: inline-block;
        width: 1.8em;
        height: 1.8em;
        line-height: 1.8;
        text-align: center;
        cursor: pointer;
        background: #eaf5ff;
        border: 1px solid #0058a3;
        color: #000;
        margin-right: 0.5em;}
    div.pager span.active {background: yellow;}
  </style>
  <body>
    <!-- 第一頁頁面 -->
    <section data-role="page" id="page1">
      <header data-role="header">
        <h1>表格測試</h1>
      </header>
      <article data-role="content">
        <table data-role="table" border="1" class="ui-responsive ui-shadow paginated"  data-mode="columntoggle" data-column-btn-text="欄位選擇">
          <thead>
            <tr>
              <th>股票名稱</th>
              <th>股票代號</th>
              <th>收盤價 (元)</th>
              <th>成交量 (張)</th>
              <th data-priority="3">股東會日期</th>
              <th data-priority="2">董監改選</th>
              <th data-priority="1">類股</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>台積電</td>
              <td>2330</td>
              <td>123</td>
              <td>4425119</td>
              <td>2014-06-04</td>
              <td>0</td>
              <td>半導體</td>
            </tr>
            <tr>
              <td>中華電</td>
              <td>2412</td>
              <td>96.4</td>
              <td>5249</td>
              <td>2014-06-15</td>
              <td>0</td>
              <td>通信</td>
            </tr>
            <tr>
              <td>中碳</td>
              <td>1723</td>
              <td>192.5</td>
              <td>918</td>
              <td>2014-07-05</td>
              <td>0</td>
              <td>塑化</td>
            </tr>
            <tr>
              <td>創見</td>
              <td>2451</td>
              <td>108</td>
              <td>733</td>
              <td>2014-06-30</td>
              <td>0</td>
              <td>模組</td>
            </tr>
            <tr>
              <td>華擎</td>
              <td>3515</td>
              <td>118.5</td>
              <td>175</td>
              <td>2014-07-20</td>
              <td>0</td>
              <td>主機板</td>
            </tr>
            <tr>
              <td>訊連</td>
              <td>5203</td>
              <td>97</td>
              <td>235</td>
              <td>2014-05-31</td>
              <td>0</td>
              <td>軟體</td>
            </tr>
          </tbody>
        </table>
      </article>
      <footer data-role="footer">
        <h3>頁尾</h3>
      </footer>
    </section>
    <script> 
      $(function(){
        $("tr:nth-child(even)").addClass("altrow");
        $("tr").hover(function(){
          $(this).toggleClass("highlight");
          });
        $('table.paginated').each(function() {
          var currentPage=0;
          var numPerPage=5;  
          var $table=$(this);
          $table.on('repaginate', function() {
            $table.find('tbody tr').hide()
                  .slice(currentPage*numPerPage,(currentPage+1)*numPerPage).show();
            });
          $table.trigger('repaginate');
          var numRows=$table.find('tbody tr').length;
          var numPages=Math.ceil(numRows / numPerPage);
          var $pager=$('<div class="pager"></div>');
          for (var page=0; page < numPages; page++) {
            $('<span class="page-number"></span>')
              .text((page+1))
              .on('click',{newPage: page}, function(event) {
                currentPage=event.data['newPage'];
                $table.trigger('repaginate');
                $(this).addClass('active').siblings().removeClass('active');
                }).appendTo($pager).addClass('clickable');
            }
          $pager.insertAfter($table).find('span.page-number:first').addClass('active');
          });
        });
    </script>
  </body>
</html>

此例我將每頁顯示筆數 numPerPage 設為 5 筆, 結果如下 : 





此例測試網頁 QR code 如下 :




將將, 嗯, 效果不錯, 完工囉.

至於用 DataTable 呈現的方法, 由於 DataTable 已改版, 用法與之前有所不同, 故等重新做過新版 DataTable 測試後再回頭將其用在 jQuery Mobile 中, 參考 :


PS : 此文中的 PHP 程式似乎無法運作, 有空檢查一下.

沒有留言 :