Current implementation:
$class = $direction === SORT_DESC ? 'desc' : 'asc';
And there is no way to add your custom class. I want to use Font Awesome icons.
My bad, missed that $sortLinkOptions exists in yii\grid\DataColumn.
This is how link is rendered:
return $sort->link($this->attribute, array_merge($this->sortLinkOptions, ['label' => ($this->encodeLabel ? Html::encode($label) : $label)]));
But using $sortLinkOptions doesn't solve the problem:
[
'attribute' => 'completed_at',
'sortLinkOptions' => ['class' => 'fa'],
],
Because even I can set main class like fa, I'm unable to set classes like fa-sort-amount-asc and fa-sort-amount-desc.
Also writing this for each column is kind of not optimal if the same class is used.
We are talking about DataColumn.php:142.
$sort is an instance of yii\data\Sort. There is a link() method and you can override it do satisfy your requirements.
By default link() method adds class asc or desc to the link, so the task may be solved with CSS:
.link-sorter {
.asc {
@extend .fa-sort-amount-asc;
}
.desc {
@extend .fa-sort-amount-desc;
}
}
Maybe, we can un-hardcode asc and desc and make them configurable.
Do you have another ideas, how to make it really configurable without code overcomlicating?
Yes I already tried something like that, but with Font Awesome we need to append content like <i class="fa fa-..."></i> depending on sort direction. And seems like it's not possible without extending framework classes and overriding core methods.
Actually we can use after pseudo class like it's done in advanced template.
I'd do something like
class Sort extends Object
{
public $sortClassAsc = 'asc';
public $sortClassDesc = 'desc';
//....
public function link($attribute, $options = [])
{
//....
$class = $direction === SORT_DESC ? $this->sortClassDesc: $this->sortClassAsc;
//....
}
//....
}
or
class Sort extends Object
{
public $sortClasses = [
SORT_ASC => 'asc',
SORT_DESC => 'desc'
];
//....
public function link($attribute, $options = [])
{
//....
$class = $this->sortClasses[$direction];
//....
}
//....
}
I came up with this workaround. I'm using SASS.
This is duplicate of .fa class from generated Font Awesome CSS (I don't want to import whole file because it's already included in main asset).
%fa {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
GridView customization:
.grid-view {
th {
a {
&:after {
@extend %fa;
position: relative;
left: 5px;
}
}
.asc {
&:after {
content: "\f160";
}
}
.desc {
&:after {
content: "\f161";
}
}
}
}
The content for actual icons are copied from generated Font Awesome CSS as well:
.fa-sort-amount-asc:before {
content: "\f160";
}
.fa-sort-amount-desc:before {
content: "\f161";
}
I'm not satisfied with this solution, but as temporary it works well.
@arogachev when you're using SASS, you can use @extend to inherit .asc and .desc icon from FA
@SilverFire Yes, but how we can include Font Awesome in SASS without adding it to generated CSS? Because it's included in main asset bundle AppAsset.
@arogachev never mind, my fault. You can't indeed.
I'm closing this issue because you have two ways to override default conduction of link and both of them are OK.
Well, in this case, what do you think about adding it to cookbook, @samdark?
I'm OK with it if you could help with a pull request.
@samdark OK, i will send it later.
You can configure your link like this
<a href='<?= $dataProvider->sort->createUrl( "name" ) ?>'> Name <i class="fa fa-sort-alpha-asc"></i> </a>
Here's a few SASS-solutions for FontAwesome 5 icons without modifying the grid view configuration or duplicating icon code:
Icon before label:
a[data-sort] {
&:before {
@extend .fa;
margin-right: 5px;
}
&.desc {
@extend .fa-sort-down;
}
&.asc {
@extend .fa-sort-up;
}
}
Icon behind label:
a[data-sort] {
position: relative;
padding-right: 12px;
&:before {
@extend .fa;
position: absolute;
right: 0;
top: 0;
}
&.desc {
@extend .fa-sort-down;
}
&.asc {
@extend .fa-sort-up;
}
}
Always show a default icon, and highlight icon on active column:
a[data-sort] {
@extend .fa-sort;
&:before {
@extend .fa;
margin-right: 5px;
color: #bbb;
}
&.asc, &.desc {
&:before {
color: #f00;
}
}
&.desc {
@extend .fa-sort-down;
}
&.asc {
@extend .fa-sort-up;
}
}
Most helpful comment
You can configure your link like this
<a href='<?= $dataProvider->sort->createUrl( "name" ) ?>'> Name <i class="fa fa-sort-alpha-asc"></i> </a>