111
111

Reputation: 1918

Yii2 GridView sorting breaks multi-select filter, unable to de-select after sort

I have a yii2 gridview column with a multi-select filter, on a has many relation:

in search model:

$dataProvider->sort->attributes['programSelect'] = [
    'asc' => ['programs.name' => SORT_ASC],
    'desc' => ['programs.name' => SORT_DESC],
];

Column in view:

$columns[]=[
'format' => 'raw',
'attribute' => 'programSelect',
'value' => function ($data) {return '...'},
'headerOptions' => [
    'style' => 'width:100px',
    'data-header-attrib'=>'programs', 
],
'filter' => Html::activeDropDownList($searchModel, 'programSelect', $myPrograms, 
    [
        'class' => 'form-control multiselect-filter',
        'id' =>'programs-filter',
        'multiple' => true,
    ]),
]

The grid view works fine until after sorting the first time. The links the sorter generates contain duplicate elements as follows.

On first grid load, the url of the lsorting ink is:

http://myurl?ModelSearch[programSelect]=&ModelSearch[programSelect][]=2&ModelSearch[programSelect][]=26

(note the [] for multi-select params, which is expected for array url params)

After clicking the sort link, the url params get array indexes as follows:

http://myurl?ModelSearch[programSelect][0]=2&ModelSearch[programSelect][1]=26&sort=programSelect

This breaks the multi-select and I can no longer change the multi-select options in the filter.

Do any yii2 developers know the best way to resolve this?

Thanks

Upvotes: 0

Views: 558

Answers (1)

111
111

Reputation: 1918

Ended up hacking my way around this with a bit of javascript:

$('.grid-pjax').on('pjax:complete', function(event, xhr, options) {

        // yii UrlManager does not handle array values properly for urls
        // it adds array keys into the url when parsing- changes param[]=x to param[0]=x
        // this breaks GridView filtering after clicking a grid column sort header link
        // process the sort header links to remove such array indexes
        //////////////////////////////////////////////////////////////////////////

        var re = /%5D%5B\d+%5D/gi;
        $(myGridSelector+' th>a').each(function(i){
            var badUrl=$(this).attr('href');
            $(this).attr('href',badUrl.replace(re, '%5D%5B%5D'))
            //console.log('href is now:');
            //console.log($(this).attr('href'));
        })

    })

Upvotes: 1

Related Questions