diff --git a/framework/yii/assets/yii.gridView.js b/framework/yii/assets/yii.gridView.js index b07ece2..a452c17 100644 --- a/framework/yii/assets/yii.gridView.js +++ b/framework/yii/assets/yii.gridView.js @@ -22,6 +22,8 @@ }; var defaults = { + filterUrl: undefined, + filterSelector: undefined }; var methods = { @@ -32,6 +34,32 @@ $e.data('yiiGridView', { settings: settings }); + + var enterPressed = false; + $(document).on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) { + if (event.type === 'keydown') { + if (event.keyCode !== 13) { + return; // only react to enter key + } else { + enterPressed = true; + } + } else { + // prevent processing for both keydown and change events + if (enterPressed) { + enterPressed = false; + return; + } + } + var data = $(settings.filterSelector).serialize(); + var url = settings.filterUrl; + if (url.indexOf('?') >= 0) { + url += '&' + data; + } else { + url += '?' + data; + } + window.location.href = url; + return false; + }); }); }, @@ -74,5 +102,38 @@ return this.data('yiiGridView'); } }; + + var enterPressed = false; + + var filterChanged = function (event) { + if (event.type === 'keydown') { + if (event.keyCode !== 13) { + return; // only react to enter key + } else { + enterPressed = true; + } + } else { + // prevent processing for both keydown and change events + if (enterPressed) { + enterPressed = false; + return; + } + } + var data = $(settings.filterSelector).serialize(); + if (settings.pageVar !== undefined) { + data += '&' + settings.pageVar + '=1'; + } + if (settings.enableHistory && settings.ajaxUpdate !== false && window.History.enabled) { + // Ajaxify this link + var url = $('#' + id).yiiGridView('getUrl'), + params = $.deparam.querystring($.param.querystring(url, data)); + + delete params[settings.ajaxVar]; + window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url.substr(0, url.indexOf('?')), params))); + } else { + $('#' + id).yiiGridView('update', {data: data}); + } + return false; + }; })(window.jQuery); diff --git a/framework/yii/grid/GridView.php b/framework/yii/grid/GridView.php index f4433bc..4bf7a39 100644 --- a/framework/yii/grid/GridView.php +++ b/framework/yii/grid/GridView.php @@ -14,6 +14,7 @@ use yii\base\InvalidConfigException; use yii\base\Widget; use yii\db\ActiveRecord; use yii\helpers\Html; +use yii\helpers\Json; use yii\widgets\BaseListView; /** @@ -137,6 +138,14 @@ class GridView extends BaseListView */ public $filterModel; /** + * @var string|array the URL for returning the filtering result. [[Html::url()]] will be called to + * normalize the URL. If not set, the current controller action will be used. + * When the user makes change to any filter input, the current filtering inputs will be appended + * as GET parameters to this URL. + */ + public $filterUrl; + public $filterSelector; + /** * @var string whether the filters should be displayed in the grid view. Valid values include: * * - [[FILTER_POS_HEADER]]: the filters will be displayed on top of each column's header cell. @@ -167,6 +176,9 @@ class GridView extends BaseListView if (!isset($this->options['id'])) { $this->options['id'] = $this->getId(); } + if (!isset($this->filterRowOptions['id'])) { + $this->filterRowOptions['id'] = $this->options['id'] . '-filters'; + } $this->initColumns(); } @@ -177,12 +189,33 @@ class GridView extends BaseListView public function run() { $id = $this->options['id']; + $options = Json::encode($this->getClientOptions()); $view = $this->getView(); GridViewAsset::register($view); - $view->registerJs("jQuery('#$id').yiiGridView();"); + $view->registerJs("jQuery('#$id').yiiGridView($options);"); parent::run(); } + + /** + * Returns the options for the grid view JS widget. + * @return array the options + */ + protected function getClientOptions() + { + $filterUrl = isset($this->filterUrl) ? $this->filterUrl : array(Yii::$app->controller->action->id); + $id = $this->filterRowOptions['id']; + $filterSelector = "#$id input, #$id select"; + if (isset($this->filterSelector)) { + $filterSelector .= ', ' . $this->filterSelector; + } + + return array( + 'filterUrl' => Html::url($filterUrl), + 'filterSelector' => $filterSelector, + ); + } + /** * Renders the data models for the grid view. */