Yii2:固定第一列的Gridview [英] Yii2 : Gridview with fixed first column
问题描述
有人可以帮助我实现Gridview(Yii2),其中第一列(NAME)始终可见,其他列可以水平滚动到侧面.
我的客户要求一个类似于Excel的界面,他们可以在其中查看和过滤各种客户信息(标有是"或否"的各种产品).
首先,我以以下示例作为参考:
bootsnip的REF 1
.scrolling table {table-layout:继承;*左边距:-100px;/* ie7 */}.scrolling td,th {垂直对齐:顶部;内边距:10px;最小宽度:100像素;}.scrolling th {位置:绝对;*职位:相对;/* ie7 */左:0;宽度:120像素;}.outer {职位:相对}.inner {溢出-x:自动;溢出-y:可见;左边距: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><!------在您的HEAD标记中包含以上内容---------->< 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">编辑</li></ul></div></div>< div class ="row">< div class ="col-md-8 col-sm-8 col-xs-9">< div class ="scrolling outside">< div class ="inner">< table class ="table table-striped table-hover table-condensed">< tr>< th>日期:</th>< td>内容一</td>< td>更长的内容2</td>< td>第三内容包含更多的</td>< td>短四</td>< td>标准5</td>< td>谁的计数</td></tr>< tr>< th><输入type ="text" class ="form-control" value ="03-03-2008"></th>< td><输入type ="text" class ="form-control" value ="22"></td>< td><输入type ="text" class ="form-control" value ="22"></td>< td><输入type ="text" class ="form-control" value ="22"></td>< td><输入type ="text" class ="form-control" value ="22"></td>< td><输入type ="text" class ="form-control" value ="22"></td>< td><输入type ="text" class ="form-control" value ="22"></td></tr>< tr>< th><输入type ="text" class ="form-control" value ="07-05-2009"></th>< td><输入type ="text" class ="form-control" value ="23"></td>< td><输入type ="text" class ="form-control" value ="23"></td>< td><输入type ="text" class ="form-control" value ="23"></td>< td><输入type ="text" class ="form-control" value ="23"></td>< td><输入type ="text" class ="form-control" value ="23"></td>< td><输入type ="text" class ="form-control" value ="23"></td></tr>< tr>< th><输入type ="text" class ="form-control" value ="17-06-2010"></th>< td><输入type ="text" class ="form-control" value ="24"></td>< td><输入type ="text" class ="form-control" value ="24"></td>< td><输入type ="text" class ="form-control" value ="24"></td>< td><输入type ="text" class ="form-control" value ="24"></td>< td><输入type ="text" class ="form-control" value ="24"></td>< td><输入type ="text" class ="form-control" value ="24"></td></tr>< tr>< th><输入type ="text" class ="form-control" value ="05-07-2011"></th>< td><输入type ="text" class ="form-control" value ="25"></td>< td><输入type ="text" class ="form-control" value ="25"></td>< td><输入type ="text" class ="form-control" value ="25"></td>< td><输入type ="text" class ="form-control" value ="25"></td>< td><输入type ="text" class ="form-control" value ="25"></td>< td><输入type ="text" class ="form-control" value ="25"></td></tr>< tr>< th><输入type ="text" class ="form-control" value ="09-08-2012"></th>< td><输入type ="text" class ="form-control" value ="26"></td>< td><输入type ="text" class ="form-control" value ="26"></td>< td><输入type ="text" class ="form-control" value ="26"></td>< td><输入type ="text" class ="form-control" value ="26"></td>< td><输入type ="text" class ="form-control" value ="26"></td>< td><输入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">在内容溢出到右侧时,收缩浏览器窗口以显示滚动条.< p>左列(th)保持固定.< p>每当右边的内容过多时,滚动条就会出现.</div></div></div></div></div>
codepen的REF 2
//需要jquery库jQuery(document).ready(function(){jQuery(.main-table").clone(true).appendTo('#table-scroll').addClass('clone');});
.table-scroll {职位:相对最大宽度:600像素;保证金:自动;溢出:隐藏;边框:1px实线#000;}.table-wrap {宽度:100%;溢出:自动;}.table-scroll table {宽度:100%;保证金:自动;边界崩溃:单独;边框间距:0;}.table-scroll th,.table-scroll td {内边距:5px 10px;边框:1px实线#000;背景:#fff;空白:nowrap;垂直对齐:顶部;}.table-scroll thead,.table-scroll tfoot {背景:#f9f9f9;}.clone {位置:绝对;最高:0;左:0;指针事件:无;}.clone th,.clone td {可见度:隐藏}.clone td,.clone th {边框颜色:透明}.clone tbody th {能见度:可见;红色;}.clone .fixed-side {边框:1px实线#000;背景:#eee;能见度:可见;}.clone thead,.clone tfoot {背景:透明;}
< 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">标题2</th>< th scope ="col">标头3</th>< th scope ="col">标头4</th>< th scope ="col">标头5</th>< th scope ="col">标头6</th>< th scope ="col">标头7</th>< th scope ="col">标头8</th></tr></thead>< tbody>< tr>< th class ="fixed-side">左列</th>< td>单元格内容
测试</td>< td>< a href =#">单元格内容较长</a></td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td></tr>< tr>< th class ="fixed-side">左列</th>< td>单元格内容</td>< td>单元格内容更长</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td></tr>< tr>< th class ="fixed-side">左列</th>< td>单元格内容</td>< td>单元格内容更长</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td></tr>< tr>< th class ="fixed-side">左列</th>< td>单元格内容</td>< td>单元格内容更长</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td></tr>< tr>< th class ="fixed-side">左列</th>< td>单元格内容</td>< td>单元格内容更长</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td></tr>< tr>< th class ="fixed-side">左列</th>< td>单元格内容</td>< td>单元格内容更长</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td>< td>单元格内容</td></tr></tbody>< tfoot>< tr>< th class ="fixed-side">& nbsp;</th>< td>页脚2</td>< td>第3脚/td< td>页脚4</td>< td>第5脚/td>< td>页脚6</td>< td>页脚7</td>< td>第8张脚/td></tr></tfoot></table></div></div>< p>请参见< a href ="https://codepen.io/paulobrien/pen/LBrMxa" target ="blank">位置粘贴版本</a>没有JS</p>
我的网格视图:
我认为要实现它很难,要做的就是仔细观察
- CSS类和属性
- 要遵循的html结构
- 根据需要更新/添加您需要添加的类 为主题或引导程序覆盖的属性
- 添加
!important
.
我将在网格视图中实现问题中的第一个示例,所要做的就是在视图顶部复制以下CSS,我添加了一些选择器,这些选择器是使用网格视图所必需的,它们针对的是列标题和过滤器输入.
注意:我已经使用默认的Yii2设置测试了以下示例,该默认设置与上述第一个示例中使用的引导程序和jquery版本一起提供.
$ this-> registerJs($ js,\ yii \ web \ View :: POS_READY);$ css =<<< CSS.scrolling table {table-layout:继承!important;* margin-left:-100px!important;/* ie7 */}.scrolling td,th {垂直对齐:顶部!重要;padding:10px!重要;min-width:100px!important;}.scrolling theth:第一个孩子,.scrollingad tr.filters td:first-child,.scrolling tbody td:first-child {位置:绝对重要!*位置:相对!重要;/* ie7 */左:0!重要;宽度:120像素!重要}.outer {位置:相对!重要;}.inner {溢出-x:自动!重要;溢出-y:可见!重要;margin-left:120px!important;}CSS;$ this-> registerCss($ css);
然后,您需要将 GridView
包裹在< div class ="scrolling outside">
内,并且gridview应该定义了这些属性
- 将类添加到由gridview创建的默认包装div中
'options'=>['class'=>'内部']`.
- 覆盖表格类以删除会干扰表格布局的
table-bordered
类,'tableOptions'=>['class'=>'表表条纹表悬停表浓缩']
因此您的GridView代码如下所示
< div class ="scrolling external"><?php echo GridView :: widget(['dataProvider'=>$ dataProvider,'filterModel'=>$ searchModel,'options'=>['class'=>'内'],'tableOptions'=>['class'=>'表表条纹表悬浮表浓缩'],'columns'=>['名称',....//其余的列....['class'=>'yii \ grid \ ActionColumn',]]]);?></div>
记住要在网格视图中指定为第一列的任何列,都将停靠在左侧,在您的情况下,该列应为 name
.
如果您正确完成了所有操作,则 GridView
如下所示,您会注意到第一列 Name
停靠在左侧,并且滚动条中的滚动部分./p>
Can someone help me to implement a Gridview (Yii2) where the first column (NAME) was always visible and the others I could scroll horizontally to the side.
My customers asked for an Excel-like interface where they could view and filter various customer information (various products marked YES or NO).
At first, I have this example as a reference:
REF 1 from bootsnip
.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>
REF 2 from codepen
// 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"> </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"> </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>
My gridview: Best way to implement grid with many columns
UPDATE
I dont think its that hard to implement it all you need to do is to carefully watch
- CSS class & properties
- The html structure to follow
- Update/add the classes you need to add depending on your requirements
- Add
!important
for the properties that are overridden by the theme or the bootstrap.
i will implement the first example in your question into the gridview all you have to do is top copy the following css on top of your view, i have added a few selectors which are necessary to work with grid view and they target the column Heading and the filter input too.
Note: i have tested the following example with the default Yii2 setup that comes with the bootstrap and jquery versions that are used in the 1st example above.
$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);
Then you need to wrap your GridView
inside the <div class="scrolling outer">
and your gridview should have these properties defined
- Add the class to the default wrapper div created by gridview
'options' => ['class' => 'inner']`.
- Override the table classes to remove the
table-bordered
class which disturbs the layout of the table,'tableOptions' => ['class' => 'table table-striped table-hover table-condensed']`
So your GridView code will look like below
<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>
Remember whichever column you will specify as the first in your grid view, will be docked to the left, in your case it should be name
.
If you did everything correctly your GridView
will look like below, you can notice the first column Name
docked at the left and the scrolled section from the scroll bar.
这篇关于Yii2:固定第一列的Gridview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!