问题
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
回答1:
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.
来源:https://stackoverflow.com/questions/57277613/yii2-gridview-with-fixed-first-column