все зависит от задачи. как правило это грид - места нет, а при малом количестве места слайдер даст только неточное ограничение. а в админке как правило нужна точная выборка.VaNnOrus писал(а): Админам не нужны удобства, только хардкор?
GridView filter больше меньше <>=
Re: GridView filter больше меньше <>=
Re: GridView filter больше меньше <>=
Можно попробовать задать validateOnBlur/...OnChange/...OnType false.Insolita писал(а):попробовала, но штука в том что при изменении select фильтр сразу начинает запрос фильтрации...
Re: GridView filter больше меньше <>=
да можно, мне это в принципе то не нужно было, я чисто так особо не заморачиваясь набросала, на заметочку, вдруг когда понадобится
Re: GridView filter больше меньше <>=
надо добавлять data-pjax="0" тем вещам, на которые не надо вешать pjaxInsolita писал(а):да можно, мне это в принципе то не нужно было, я чисто так особо не заморачиваясь набросала, на заметочку, вдруг когда понадобится
Re: GridView filter больше меньше <>=
сделайте min и max, и необязательными, тогда знаки сравнения юзер не будет вводить, и вам при валидации меньше проблем
Re: GridView filter больше меньше <>=
В общем... Сделал я behavior, по мне так удобно... Если кто захочет покритиковать - пожалуйста... Кому-то может показаться неудобным...
behavior:
Как использовать:
1. В моделе добавляем сценарий search. вписываем все поля для массового присваивания (в общем все поля что выводим и по которым есть фильтр):
2. Прикручиваем бехейвер:
В comparisonAttributes вставляем аттрибуты которые должны использовать сортировку со знаками. И пишем каждому тип, numeric или datetime. В зависимости от поля.
3. В функцию search добавляем сценарий до валидации:
И с запросом работаем так:
т.е. в моем случае первой строкой забираем условия по тем полям, для которых нужны сравнения.
После этого руками указываю поля, для которых эти сравнения не нужны.
4. Поля во вьюхе выводим след. образом:
П.с. поля datetime храняться в Y-m-d H:i:s. Я их не переделывал, так и вывожу...
Все. В чем профит... Во-первых integer, double, и т.д. сравниваются <, <=, >, >=, <>, =. Так же сравнивать можно и поля с datetime типом. Так же можно писать например: 2014 (все поля за 2014 год), <2014 (все поля до 2014 года) и т.д. Так же можно писать и <2014-02 (Все меньше февраля 2014) и т.д. по дням часам минутам...
Сильно строго не судите, критика принимается...
behavior:
Код: Выделить всё
<?php
namespace app\modules\admin\common\behaviors;
use yii;
use yii\base\Behavior;
use yii\db\ActiveRecord;
use yii\helpers\Html;
class AdminSignComparison extends Behavior
{
/**
* @var $comparisonAttributes array
* Array of attributes that needed comparison
*/
public $comparisonAttributes;
/**
* @return array
*/
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_VALIDATE => 'setComparisonAttributes'
];
}
/**
* Method before validate, delete comparison characters and sets needed value.
* @return void
*/
public function setComparisonAttributes()
{
if($this->owner->scenario != 'search')
return;
foreach($this->comparisonAttributes as $attribute => $settingsArray)
{
if(empty($this->owner->$attribute) || $settingsArray['type'] === false)
continue;
if($settingsArray['type'] === 'text')
{
$this->comparisonAttributes[$attribute]['comparison'] = '=';
continue;
}
$this->setComparisonCharacters($attribute);
if($settingsArray['type'] === 'datetime')
$this->setDatetimeAttribute($attribute);
}
}
/**
* @param $attribute string
* Function delete comparison characters and sets comparison characters into $comparisonAttributes
*/
private function setComparisonCharacters($attribute)
{
switch(substr($this->owner->$attribute, 0, 1))
{
case '<':
if(substr($this->owner->$attribute, 1, 1) == '=')
{
$this->owner->$attribute = substr($this->owner->$attribute, 2);
$this->comparisonAttributes[$attribute]['comparison'] = '<=';
}
else if(substr($this->owner->$attribute, 1, 1) == '>')
{
$this->owner->$attribute = substr($this->owner->$attribute, 2);
$this->comparisonAttributes[$attribute]['comparison'] = '<>';
}
else
{
$this->owner->$attribute = substr($this->owner->$attribute, 1);
$this->comparisonAttributes[$attribute]['comparison'] = '<';
}
break;
case '>':
if(substr($this->owner->$attribute, 1, 1) == '=')
{
$this->owner->$attribute = substr($this->owner->$attribute, 2);
$this->comparisonAttributes[$attribute]['comparison'] = '>=';
}
else
{
$this->owner->$attribute = substr($this->owner->$attribute, 1);
$this->comparisonAttributes[$attribute]['comparison'] = '>';
}
break;
default:
if(substr($this->owner->$attribute, 0, 1) === '=')
$this->owner->$attribute = substr($this->owner->$attribute, 1);
$this->comparisonAttributes[$attribute]['comparison'] = '=';
break;
}
}
/**
* @param $attribute string
* Function sets right comparison for datetime and call getComparisonDatetime() to get correct datetime
*/
private function setDatetimeAttribute($attribute)
{
if($this->comparisonAttributes[$attribute]['comparison'] === '=')
$this->comparisonAttributes[$attribute]['comparison'] = 'between';
$attributeLength = strlen($this->owner->$attribute);
if($attributeLength == 4)
{
if($this->comparisonAttributes[$attribute]['comparison'] === '=')
$this->comparisonAttributes[$attribute]['secondAttribute'] = $this->owner->$attribute . '-12-31 23:59:59';
$this->owner->$attribute = $this->getComparisonDatetime($attribute, 'year', $this->owner->$attribute);
}
elseif($attributeLength == 7)
{
if($this->comparisonAttributes[$attribute]['comparison'] === '=')
$this->comparisonAttributes[$attribute]['secondAttribute'] = $this->owner->$attribute . '-' . date('t', strtotime($this->owner->$attribute)) . ' 23:59:59';
$this->owner->$attribute = $this->getComparisonDatetime($attribute, 'month', $this->owner->$attribute);
}
elseif($attributeLength == 10)
{
if($this->comparisonAttributes[$attribute]['comparison'] === '=')
$this->comparisonAttributes[$attribute]['secondAttribute'] = $this->owner->$attribute . ' 23:59:59';
$this->owner->$attribute = $this->getComparisonDatetime($attribute, 'day', $this->owner->$attribute);
}
elseif($attributeLength == 13)
{
if($this->comparisonAttributes[$attribute]['comparison'] === '=')
$this->comparisonAttributes[$attribute]['secondAttribute'] = $this->owner->$attribute . ':59:59';
$this->owner->$attribute = $this->getComparisonDatetime($attribute, 'hour', $this->owner->$attribute);
}
elseif($attributeLength == 16)
{
if($this->comparisonAttributes[$attribute]['comparison'] === '=')
$this->comparisonAttributes[$attribute]['secondAttribute'] = $this->owner->$attribute . ':59';
$this->owner->$attribute = $this->getComparisonDatetime($attribute, 'minute', $this->owner->$attribute);
}
else
$this->comparisonAttributes[$attribute]['comparison'] = '=';
}
/**
* @param $attribute string
* @param $period string
* @param $value string
* @return string
*
* Function sets right comparison for datetime and return correct datetime
*/
private function getComparisonDatetime($attribute, $period, $value)
{
$comparisonDateTime = $value;
$comparison = $this->comparisonAttributes[$attribute]['comparison'];
switch($period)
{
case 'year':
if($comparison === '<' || $comparison === '>=')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . '-01-01 00:00:00'));
elseif($comparison === '<=' || $comparison === '>')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . '-12-31 23:59:59'));
elseif($comparison === '<>' || $comparison === 'between')
{
$this->comparisonAttributes[$attribute]['secondAttribute'] = date('Y-m-d H:i:s', strtotime($value . '-12-31 23:59:59'));
$this->comparisonAttributes[$attribute]['comparison'] = $comparison === '<>' ? 'not between' : 'between';
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . '-01-01 00:00:00'));
}
break;
case 'month':
if($comparison === '<' || $comparison === '>=')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . '-01 00:00:00'));
elseif($comparison === '<=' || $comparison === '>')
{
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . '-' . date('t', strtotime($value)) . ' 23:59:59'));
}
elseif($comparison === '<>' || $comparison === 'between')
{
$this->comparisonAttributes[$attribute]['secondAttribute'] = date('Y-m-d H:i:s', strtotime($value . '-' . date('t', strtotime($value)).' 23:59:59'));
$this->comparisonAttributes[$attribute]['comparison'] = $comparison === '<>' ? 'not between' : 'between';
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . '-01 00:00:00'));
}
break;
case 'day':
if($comparison === '<' || $comparison === '>=')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ' 00:00:00'));
elseif($comparison === '<=' || $comparison === '>')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ' 23:59:59'));
elseif($comparison === '<>' || $comparison === 'between')
{
$this->comparisonAttributes[$attribute]['secondAttribute'] = date('Y-m-d H:i:s', strtotime($value . ' 23:59:59'));
$this->comparisonAttributes[$attribute]['comparison'] = $comparison === '<>' ? 'not between' : 'between';
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ' 00:00:00'));
}
break;
case 'hour':
if($comparison === '<' || $comparison === '>=')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ':00:00'));
elseif($comparison === '<=' || $comparison === '>')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ':59:59'));
elseif($comparison === '<>' || $comparison === 'between')
{
$this->comparisonAttributes[$attribute]['secondAttribute'] = date('Y-m-d H:i:s', strtotime($value . ':59:59'));
$this->comparisonAttributes[$attribute]['comparison'] = $comparison === '<>' ? 'not between' : 'between';
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ':00:00'));
}
break;
case 'minute':
if($comparison === '<' || $comparison === '>=')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ':00'));
elseif($comparison === '<=' || $comparison === '>')
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ':59'));
elseif($comparison === '<>' || $comparison === 'between')
{
$this->comparisonAttributes[$attribute]['secondAttribute'] = date('Y-m-d H:i:s', strtotime($value . ':59'));
$this->comparisonAttributes[$attribute]['comparison'] = $comparison === '<>' ? 'not between' : 'between';
$comparisonDateTime = date('Y-m-d H:i:s', strtotime($value . ':00'));
}
break;
default:
$comparisonDateTime = $value;
break;
}
return $comparisonDateTime;
}
/**
* @param yii\db\ActiveQuery $query
* @return yii\db\ActiveQuery
*
* Function return $query with all filters for search
*/
public function getFiltersForSearch(yii\db\ActiveQuery $query)
{
foreach($this->comparisonAttributes as $attribute => $settingsArray)
{
if(empty($this->owner->$attribute) || $settingsArray['type'] === false)
continue;
if($this->comparisonAttributes[$attribute]['comparison'] === 'between' || $this->comparisonAttributes[$attribute]['comparison'] === 'not between')
$query->andFilterWhere([
$this->comparisonAttributes[$attribute]['comparison'],
$this->owner->tableName() . '.' . $attribute,
$this->owner->$attribute,
$this->comparisonAttributes[$attribute]['secondAttribute']
]);
else
$query->andFilterWhere([
$this->comparisonAttributes[$attribute]['comparison'],
$this->owner->tableName() . '.' . $attribute,
$this->owner->$attribute
]);
}
return $query;
}
/**
* @param $attribute string
* @return string
*
* Function return textInput of filter
*/
public function getFilter($attribute)
{
if(isset(Yii::$app->request->get($this->owner->formName(), null)[$attribute]))
$value = Yii::$app->request->get($this->owner->formName(), null)[$attribute];
else
$value = null;
return Html::textInput($this->owner->formName() . '['.$attribute.']', $value, ['class' => 'form-control']);
}
}
1. В моделе добавляем сценарий search. вписываем все поля для массового присваивания (в общем все поля что выводим и по которым есть фильтр):
Код: Выделить всё
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['search'] = ['id', 'user_id', 'banner_place_id', 'start_datetime', 'end_datetime', 'cost', 'active', 'created_at', 'updated_at'];
return $scenarios;
}
Код: Выделить всё
public function behaviors()
{
return [
'AdminSignComparison' => [
'class' => AdminSignComparison::className(),
'comparisonAttributes' => [
'id'=>['type'=>'numeric'],
'user_id'=>['type'=>'numeric'],
'banner_place_id'=>['type'=>'text'],
'start_datetime'=>['type'=>'datetime'],
'end_datetime'=>['type'=>'datetime'],
'cost'=>['type'=>'numeric'],
'created_at'=>['type'=>'datetime'],
'updated_at'=>['type'=>'datetime'],
]
]
];
}
3. В функцию search добавляем сценарий до валидации:
Код: Выделить всё
$this->setScenario('search');
Код: Выделить всё
$query = $this->getBehavior('AdminSignComparison')->getFiltersForSearch($query);
$query->andFilterWhere([
'active_banners.active' => $this->active,
'active_banners.banner_place_id' => $this->banner_place_id
]);
Код: Выделить всё
$query = $this->getBehavior('AdminSignComparison')->getFiltersForSearch($query);
Код: Выделить всё
$query->andFilterWhere([
'active_banners.active' => $this->active,
'active_banners.banner_place_id' => $this->banner_place_id
]);
Код: Выделить всё
[
'attribute'=>'id',
'filter' => $searchModel->getBehavior('AdminSignComparison')->getFilter('id')
],
Все. В чем профит... Во-первых integer, double, и т.д. сравниваются <, <=, >, >=, <>, =. Так же сравнивать можно и поля с datetime типом. Так же можно писать например: 2014 (все поля за 2014 год), <2014 (все поля до 2014 года) и т.д. Так же можно писать и <2014-02 (Все меньше февраля 2014) и т.д. по дням часам минутам...
Сильно строго не судите, критика принимается...
Последний раз редактировалось Shappy 2014.11.26, 13:34, всего редактировалось 1 раз.
Re: GridView filter больше меньше <>=
всю работу с датами я бы вынес в отдельный метод и использовал бы DateTime с sub/add
Re: GridView filter больше меньше <>=
Вообще использовать DateTime наверно было бы разумней... А метод с датами жирным слишком был, разделил его на два...zelenin писал(а):всю работу с датами я бы вынес в отдельный метод и использовал бы DateTime с sub/add
Re: GridView filter больше меньше <>=
так это для ссылок работает , а не для селектов, и там не pjax - там подвешенный скрипт от фильтра отрабатывает,zelenin писал(а):надо добавлять data-pjax="0" тем вещам, на которые не надо вешать pjaxInsolita писал(а):да можно, мне это в принципе то не нужно было, я чисто так особо не заморачиваясь набросала, на заметочку, вдруг когда понадобится
Re: GridView filter больше меньше <>=
у грида есть клиентские опции, где можно указать filterSelector, который по умолчанию "#$id input, #$id select"Insolita писал(а):так это для ссылок работает , а не для селектов, и там не pjax - там подвешенный скрипт от фильтра отрабатывает,zelenin писал(а):надо добавлять data-pjax="0" тем вещам, на которые не надо вешать pjaxInsolita писал(а):да можно, мне это в принципе то не нужно было, я чисто так особо не заморачиваясь набросала, на заметочку, вдруг когда понадобится
Можно указать что-то типа "#$id input:not([data="not-filter"]), #$id select:not([data="not-filter"])"
Re: GridView filter больше меньше <>=
Критика уже была - юзабилити страдает.Shappy писал(а):П.с. поля datetime храняться в Y-m-d H:i:s. Я их не переделывал, так и вывожу...
Все. В чем профит... Во-первых integer, double, и т.д. сравниваются <, <=, >, >=, <>, =. Так же сравнивать можно и поля с datetime типом. Так же можно писать например: 2014 (все поля за 2014 год), <2014 (все поля до 2014 года) и т.д. Так же можно писать и <2014-02 (Все меньше февраля 2014) и т.д. по дням часам минутам...
Сильно строго не судите, критика принимается...
Если уж совсем лень прикручивать ползунки - два инпута "от" и "до" - для пользователя и то лучше будет.
Дата так же от и до, но обязательно человеческими календарями. Если это сайт не для программистов - Ваши 2014-12-21 добрая половина пользователей просто не поймет, потому что так не принято писать даты в жизни.
Re: GridView filter больше меньше <>=
Да, согласен что было бы удобней с человеческими датами... Но это надо будет переделывать работу с датой... Может потом займусь этим, сделаю все по человечески... А на счет ползунков... Ну даже не знаю... Мне кажется и так хорошо:)) Можно конечно тоже что-нибудь придумать... Доделаю как будет время... Спасибо...VaNnOrus писал(а):Критика уже была - юзабилити страдает.Shappy писал(а):П.с. поля datetime храняться в Y-m-d H:i:s. Я их не переделывал, так и вывожу...
Все. В чем профит... Во-первых integer, double, и т.д. сравниваются <, <=, >, >=, <>, =. Так же сравнивать можно и поля с datetime типом. Так же можно писать например: 2014 (все поля за 2014 год), <2014 (все поля до 2014 года) и т.д. Так же можно писать и <2014-02 (Все меньше февраля 2014) и т.д. по дням часам минутам...
Сильно строго не судите, критика принимается...
Если уж совсем лень прикручивать ползунки - два инпута "от" и "до" - для пользователя и то лучше будет.
Дата так же от и до, но обязательно человеческими календарями. Если это сайт не для программистов - Ваши 2014-12-21 добрая половина пользователей просто не поймет, потому что так не принято писать даты в жизни.
Re: GridView filter больше меньше <>=
Shappy писал(а):Код: Выделить всё
if($this->owner->scenario != 'search') return;
Сценарии нужные поисковые самому бы в behavior подставлять, причём чтоб массивом,а не один конкретно заданныйShappy писал(а): Как использовать:
1. В моделе добавляем сценарий search.
Re: GridView filter больше меньше <>=
Честно говоря не понял... Я понял так: чтобы behavior выполнялся только при определенных (нескольких) сценариях, которые укажет пользователь. Нам этот behavior нужен только при GridView, это всего один метод, больше он нигде не используется... Сделать это не проблема, а где это может понадобиться?Insolita писал(а):Shappy писал(а):Код: Выделить всё
if($this->owner->scenario != 'search') return;
Сценарии нужные поисковые самому бы в behavior подставлять, причём чтоб массивом,а не один конкретно заданныйShappy писал(а): Как использовать:
1. В моделе добавляем сценарий search.
Re: GridView filter больше меньше <>=
ну вообще-то на одну модель может быть и несколько разных GridView и вариантов поисков
Re: GridView filter больше меньше <>=
Понял, спасибо, учту...Insolita писал(а):ну вообще-то на одну модель может быть и несколько разных GridView и вариантов поисков