【问题标题】:Yii2 : Gridview with fixed first columnYii2:固定第一列的Gridview
【发布时间】:2019-07-30 18:06:03
【问题描述】:

有人可以帮我实现一个 Gridview (Yii2),其中第一列 (NAME) 始终可见,而其他列我可以水平滚动到一边。

我的客户要求使用类似 Excel 的界面,他们可以在其中查看和过滤各种客户信息(标记为“是”或“否”的各种产品)。

首先,我有这个例子作为参考:

来自 bootsnip 的 REF 1

.scrolling table {
  table-layout: inherit;
  *margin-left: -100px;
  /*ie7*/
}

.scrolling td,
th {
  vertical-align: top;
  padding: 10px;
  min-width: 100px;
}

.scrolling th {
  position: absolute;
  *position: relative;
  /*ie7*/
  left: 0;
  width: 120px;
}

.outer {
  position: relative
}

.inner {
  overflow-x: auto;
  overflow-y: visible;
  margin-left: 120px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->

<div class="container">
  <div class="row">
    <div class="col-md-12">
      <ul class="breadcrumb">
        <li> <a href="#">Home</a></li>
        <li> <a href="#">Forms</a></li>
        <li class="active">Edit</li>
      </ul>
    </div>
  </div>
  <div class="row">
    <div class="col-md-8 col-sm-8 col-xs-9">
      <div class="scrolling outer">
        <div class="inner">
          <table class="table table-striped table-hover table-condensed">
            <tr>
              <th>Date:</th>
              <td>Content One</td>
              <td>Longer Content Two</td>
              <td>Third Content Contains More</td>
              <td>Short Four</td>
              <td>Standard Five</td>
              <td>Who's Counting</td>
            </tr>
            <tr>
              <th><input type="text" class="form-control" value="03-03-2008"></th>
              <td><input type="text" class="form-control" value="22"></td>
              <td><input type="text" class="form-control" value="22"></td>
              <td><input type="text" class="form-control" value="22"></td>
              <td><input type="text" class="form-control" value="22"></td>
              <td><input type="text" class="form-control" value="22"></td>
              <td><input type="text" class="form-control" value="22"></td>
            </tr>
            <tr>
              <th><input type="text" class="form-control" value="07-05-2009"></th>
              <td><input type="text" class="form-control" value="23"></td>
              <td><input type="text" class="form-control" value="23"></td>
              <td><input type="text" class="form-control" value="23"></td>
              <td><input type="text" class="form-control" value="23"></td>
              <td><input type="text" class="form-control" value="23"></td>
              <td><input type="text" class="form-control" value="23"></td>
            </tr>
            <tr>
              <th><input type="text" class="form-control" value="17-06-2010"></th>
              <td><input type="text" class="form-control" value="24"></td>
              <td><input type="text" class="form-control" value="24"></td>
              <td><input type="text" class="form-control" value="24"></td>
              <td><input type="text" class="form-control" value="24"></td>
              <td><input type="text" class="form-control" value="24"></td>
              <td><input type="text" class="form-control" value="24"></td>
            </tr>
            <tr>
              <th><input type="text" class="form-control" value="05-07-2011"></th>
              <td><input type="text" class="form-control" value="25"></td>
              <td><input type="text" class="form-control" value="25"></td>
              <td><input type="text" class="form-control" value="25"></td>
              <td><input type="text" class="form-control" value="25"></td>
              <td><input type="text" class="form-control" value="25"></td>
              <td><input type="text" class="form-control" value="25"></td>
            </tr>
            <tr>
              <th><input type="text" class="form-control" value="09-08-2012"></th>
              <td><input type="text" class="form-control" value="26"></td>
              <td><input type="text" class="form-control" value="26"></td>
              <td><input type="text" class="form-control" value="26"></td>
              <td><input type="text" class="form-control" value="26"></td>
              <td><input type="text" class="form-control" value="26"></td>
              <td><input type="text" class="form-control" value="26"></td>
            </tr>
          </table>
        </div>
      </div>
    </div>
    <div class="col-md-4 col-sm-4 col-xs-3">
      <div class="well">
        <p class="text-danger">Shrink your browser window to see the scroll bar apear as content overflows to the right</p>
        <p>Left Column (th) stays fixed</p>
        <p>Anytime there is too much content to the right the scroll bar will appear.</p>
      </div>
    </div>
  </div>
</div>
</div>

来自 codepen 的 REF 2

// requires jquery library
jQuery(document).ready(function() {
  jQuery(".main-table").clone(true).appendTo('#table-scroll').addClass('clone');
});
.table-scroll {
  position: relative;
  max-width: 600px;
  margin: auto;
  overflow: hidden;
  border: 1px solid #000;
}

.table-wrap {
  width: 100%;
  overflow: auto;
}

.table-scroll table {
  width: 100%;
  margin: auto;
  border-collapse: separate;
  border-spacing: 0;
}

.table-scroll th,
.table-scroll td {
  padding: 5px 10px;
  border: 1px solid #000;
  background: #fff;
  white-space: nowrap;
  vertical-align: top;
}

.table-scroll thead,
.table-scroll tfoot {
  background: #f9f9f9;
}

.clone {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

.clone th,
.clone td {
  visibility: hidden
}

.clone td,
.clone th {
  border-color: transparent
}

.clone tbody th {
  visibility: visible;
  color: red;
}

.clone .fixed-side {
  border: 1px solid #000;
  background: #eee;
  visibility: visible;
}

.clone thead,
.clone tfoot {
  background: transparent;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table-scroll" class="table-scroll">
  <div class="table-wrap">
    <table class="main-table">
      <thead>
        <tr>
          <th class="fixed-side" scope="col">&nbsp;</th>
          <th scope="col">Header 2</th>
          <th scope="col">Header 3</th>
          <th scope="col">Header 4</th>
          <th scope="col">Header 5</th>
          <th scope="col">Header 6</th>
          <th scope="col">Header 7</th>
          <th scope="col">Header 8</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content<br> test
          </td>
          <td><a href="#">Cell content longer</a></td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <th class="fixed-side">&nbsp;</th>
          <td>Footer 2</td>
          <td>Footer 3</td>
          <td>Footer 4</td>
          <td>Footer 5</td>
          <td>Footer 6</td>
          <td>Footer 7</td>
          <td>Footer 8</td>
        </tr>
      </tfoot>
    </table>
  </div>
</div>

<p>See <a href="https://codepen.io/paulobrien/pen/LBrMxa" target="blank">position Sticky version </a>with no JS</p>

我的网格视图:Best way to implement grid with many columns

更新

【问题讨论】:

    标签: gridview twitter-bootstrap-3 yii2


    【解决方案1】:

    我觉得实现起来并不难,只要仔细观察就可以了

    • CSS 类和属性
    • 要遵循的 html 结构
    • 根据您的要求更新/添加您需要添加的类
    • 为被主题或引导程序覆盖的属性添加!important

    我会将您问题中的第一个示例实现到 gridview 中,您所要做的就是在您的视图顶部复制以下 css,我添加了一些使用网格视图所必需的选择器,它们针对列标题和过滤器输入也是。

    注意:我已经使用上面第一个示例中使用的引导和 jquery 版本附带的默认 Yii2 设置测试了以下示例。

    $this->registerJs($js, \yii\web\View::POS_READY);
        $css = <<<CSS
        .scrolling table {
      table-layout: inherit !important;
      *margin-left: -100px !important;
      /*ie7*/
    }
    
    .scrolling td,
    th {
      vertical-align: top !important;
      padding: 10px !important;
      min-width: 100px !important;
    }
    
    .scrolling thead th:first-child,
    .scrolling thead tr.filters td:first-child,
    .scrolling tbody td:first-child {
      position: absolute !important;
      *position:relative !important;
      /*ie7*/
      left: 0 !important;
      width: 120px !important;
    }
    
    .outer {
      position: relative !important;
    }
    
    .inner {
      overflow-x: auto !important;
      overflow-y: visible !important;
      margin-left: 120px !important;
    }
    
    CSS;
        $this->registerCss($css);
    

    然后你需要将GridView 包裹在&lt;div class="scrolling outer"&gt; 中,并且你的gridview 应该定义了这些属性

    • 将类添加到gridview创建的默认包装器div
      'options' => ['class' => 'inner']`.
      
    • 重写表格类以删除干扰表格布局的table-bordered 类,
       'tableOptions' => ['class' => 'table table-striped table-hover table-condensed']`
      

    所以你的 GridView 代码如下所示

    <div class="scrolling outer">
        <?php echo GridView::widget([
                'dataProvider' => $dataProvider,
                'filterModel' => $searchModel,
                'options' => ['class' => 'inner'],
                'tableOptions' => ['class' => 'table table-striped table-hover table-condensed'],
                'columns' => [
                    'name',
                    ....
                    //Your rest of the columns
                    ....
                    [
                        'class' => 'yii\grid\ActionColumn',
                    ]
                ]
        ]); ?>
    </div>
    

    请记住,您将在网格视图中指定为第一列的任何列都将停靠在左侧,在您的情况下,它应该是 name

    如果您做的一切正确,您的GridView 将如下所示,您会注意到停靠在左侧的第一列Name 和滚动条上的滚动部分。

    【讨论】:

    • 快到了!如何增加第一列的宽度? '样式' => '宽度:150px';不工作
    • 奥马尔,看我的更新
    • @gugoan,你没注意,好吧,把.scrolling thead th:first-child, .scrolling thead tr.filters td:first-child, .scrolling tbody td:first-child里的width:120px改成.inner里的margin:120px
    • 好的,我明白了。它在这里工作。我只需要进行一些视觉格式调整。
    猜你喜欢
    • 2016-01-13
    • 2012-10-10
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多