前言

最近实在是工作有点忙,都抽不出来时间好好的玩耍,感觉压力好大啊!一转眼,又已经10天没有更新博客了,其实早就想写了,那么今天就抽出时间来写一下吧!。

今天要介绍的是在项目中遇到过的一个问题,怎么在yii2里面的gridview加入date-range过滤搜索框。

通过查看yii2的官方文档可以发现yii2的gridview的过滤方式很有限,但他官方有个yii2-grid组件的介绍,看了下,这个组件非常不错,是一个开挂名族程序猿写的。

试用后发现了一个问题:yii2-grid的date-range在apply一个新日期范围后不会触发yii2的数据搜索。

原因是由于的val()赋值操作是无法对元素触发change()事件的,所以得手动触发一下。

测试代码:

<input id="test"/>
<a onclick="$('#test').val('xxx')">xxxxx</a>
<script>
$('#test').trigger('change', function(){
    alert('x');
});
</script>

问题描述

们来看看stackoverflow上关于此问题的描述:

http://stackoverflow.com/questions/7055729/onchange-event-not-fire-when-the-change-come-from-antoher-function/7055771#7055771

change
The change event occurs when a control loses the input focus and its value has been modified since gaining focus. This event is valid for INPUT, SELECT, and TEXTAREA. element.
When you modify the text input's value through code, the change event will not be fired because there is no focus change. You can trigger the event yourself though with createEvent and dispatchEvent

解决办法

方案1

的解决办法1:手动触发input的change事件

// 在view/index.php中加入js对applyBtn的click触发change事件
<script>
    $(document).delegate(".applyBtn", "click", function(){
        $('#statremainsearch-time').change();
    });
</script>
// 不要忘了在后端还需要对前端传过来的数据进行处理,例如:
$time = explode('-', $this->time);
$time = array_map('strtotime', $time);
if(isset($time[1]))
    $query->andFilterWhere(['between', 'time', $time[0], $time[1]]);

这种方法的弊端是,每个view的grid文件都需要写js,而写入通用js文件明显不是很科学合理,那么更好的解决办法如下:

方案2

搜vendor中的yii2-grid组件,关键词:applyBtn(其实是搜yii2-grid中的date-range-picker这个bootstrap插件的js文件)

看到103行有如下代码:

.on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))

啊,这个就是们要找的东西,那么顺藤摸瓜看下他的clickApply是怎么写的:

this.updateInputText();

继续摸,找到updateInputText方法,看到了吗?在他的两个val()方法后面加个change()吧!修改后的代码如下所示:

updateInputText: function() {
    if (this.element.is('input') && !this.singleDatePicker) {
        this.element.val(this.startDate.format(this.format) + this.separator + this.endDate.format(this.format)).change();
    } else if (this.element.is('input')) {
        this.element.val(this.endDate.format(this.format)).change();
    }
},

后端代码同方法1,完美解决!

如果您觉得您在我这里学到了新姿势,博主支持转载,姿势本身就是用来相互学习的。同时,本站文章如未注明均为 hisune 原创 请尊重劳动成果 转载请注明 转自: 关于yii2-grid组件的date-range过滤无效的问题及解决办法 - hisune.com