GridView фильтр наличия файла

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
dymsonn
Сообщения: 60
Зарегистрирован: 2018.06.13, 15:37

GridView фильтр наличия файла

Сообщение dymsonn » 2018.11.15, 15:59

Здравствуйте. Подскажите, как реализовать фильтр наличия файла селектом от Картика. В Гриде есть колонка, в которой отображается наличие прикрепленного файла у соответствующей записи. Что касается уровня базы, то все данные хранятся в одной таблице, т.е. id объекта, наименование объекта, файл и имя файла всё в одной таблице PostgreSQL.
Вот код, отвечающий за этот столбец в индексе.

Код: Выделить всё

 [
                'attribute' => 'fnamext',
                'label' => 'Прикрепленный </br> файл',
                'filter' => Select2::widget([
                    'data' =>
                        [       
                            '' => 'Все',             //что здесь      
                            0 => 'Нет файла', // писать,
                            1 => 'Есть файл', //без понятия                          
                        ],
                    'model' => $searchModel,
                    'attribute' => 'fnamext',
                    'options' => [
                        'placeholder' => 'Выберите значение',
                    ],
                ]),
                'format' => 'raw',
                'value' => function ($model) {
                    $res = $model->fnamext != null;
                    return Html::a(
                        '<span class="glyphicon glyphicon-file"></span>',
                        $res ? ['savfile', 'id' => $model->id] : Url::to(['uplfile', 'id' => $model->id]),
                        [
                            'data-method' => $res ? 'POST' : '',
                            'class' => 'label label-' . ($res ? 'success' : 'danger'),
                            'title' => $res ? 'Скачать' : 'Прикрепить',
                        ]
                    );
                },
                'encodeLabel' => false,
            ],

Это код из моделиSearch

Код: Выделить всё

  $query->andFilterWhere(['ilike', 'fnamext', $this->fnamext]); 
И он тоже не так работает как хотелось бы. А в каком месте исправить не пойму.
Поле базы fnamext варчар и содержит наименование и расширение файла. По нему и проверяю: имя есть-файл суцествует, иначе значение null-файла нет.
Забыл сказать что сдеать хочу))) В фильтре должно быть три значения: Все, Есть файл, Нет файла.

dmg
Сообщения: 672
Зарегистрирован: 2012.10.15, 03:09

Re: GridView фильтр наличия файла

Сообщение dmg » 2018.11.15, 18:25

Вы проверяете не наличие файла, а сравниваете имя файла с $this->fnamext.

Код: Выделить всё

if ($this->fnamext == 0 ){
  $query->andWhere(['fnamext' => null]); 
}
if ($this->fnamext == 1 ){
  $query->andWhere(['<>','fnamext', null]); 
}

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: GridView фильтр наличия файла

Сообщение andku83 » 2018.11.15, 18:32

dmg писал(а):
2018.11.15, 18:25

Код: Выделить всё

if ($this->fnamext == 0 ){
  $query->andWhere(['fnamext' => null]); 
}
здесь важно ===, потому что ("" == 0 == '0')
dmg писал(а):
2018.11.15, 18:25

Код: Выделить всё

  $query->andWhere(['<>','fnamext', null]); 
на NULL нужно немного по-другому проверять.

Код: Выделить всё

if ($this->fnamext === 0) {  //возможно нужно будет 0 взять в кавычки -> '0'
      $query->andWhere(['IS', 'fnamext', NULL]); 
} elseif ($this->fnamext == 1) {
      $query->andWhere(['IS NOT', 'fnamext', NULL]); 
}

dmg
Сообщения: 672
Зарегистрирован: 2012.10.15, 03:09

Re: GridView фильтр наличия файла

Сообщение dmg » 2018.11.15, 20:04

andku83 писал(а):
2018.11.15, 18:32
dmg писал(а):
2018.11.15, 18:25

Код: Выделить всё

if ($this->fnamext == 0 ){
  $query->andWhere(['fnamext' => null]); 
}
здесь важно ===, потому что ("" == 0 == '0')
dmg писал(а):
2018.11.15, 18:25

Код: Выделить всё

  $query->andWhere(['<>','fnamext', null]); 
на NULL нужно немного по-другому проверять.

Код: Выделить всё

if ($this->fnamext === 0) {  //возможно нужно будет 0 взять в кавычки -> '0'
      $query->andWhere(['IS', 'fnamext', NULL]); 
} elseif ($this->fnamext == 1) {
      $query->andWhere(['IS NOT', 'fnamext', NULL]); 
}
Конечно. Вы правы. Подзабыл.

dymsonn
Сообщения: 60
Зарегистрирован: 2018.06.13, 15:37

Re: GridView фильтр наличия файла

Сообщение dymsonn » 2018.11.16, 10:08

Спасибо. Работает. Ноль действительно в кавычки нужно брать.

Код: Выделить всё

if ($this->fnamext === '0')
И вот так

Код: Выделить всё

''=>'Все',
не работает. Не отображает в таком случае эту строку в фильтре. Написал так

Код: Выделить всё

2=>'Все',

Alex_N
Сообщения: 68
Зарегистрирован: 2015.03.02, 21:20

Re: GridView фильтр наличия файла

Сообщение Alex_N » 2018.12.03, 16:54

dmg писал(а):
2018.11.15, 18:25

Код: Выделить всё

if ($this->fnamext === 0) {  //возможно нужно будет 0 взять в кавычки -> '0'
      $query->andWhere(['IS', 'fnamext', NULL]); 
} elseif ($this->fnamext == 1) {
      $query->andWhere(['IS NOT', 'fnamext', NULL]); 
}
Подскажите пожалуйста, а можно в условии не цифру проверять, а строку? У меня что то не получается, хотя с цифрами все нормально.

У меня так работает:

Код: Выделить всё

($this->fnamext === '0')
И так работает:

Код: Выделить всё

($this->fnamext == '0')
А вот так нет:

Код: Выделить всё

($this->fnamext === 'null')
И так нет:

Код: Выделить всё

($this->fnamext == 'null')
Спасибо.

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: GridView фильтр наличия файла

Сообщение andku83 » 2018.12.03, 17:16

Alex_N писал(а):
2018.12.03, 16:54
А вот так нет:

Код: Выделить всё

($this->fnamext === 'null')
И так нет:

Код: Выделить всё

($this->fnamext == 'null')
Спасибо.
Если ваш список будет выглядеть вот так, то будет работать:

Код: Выделить всё

                    'data' =>
                        [       
                            'null' => 'Все', // null != 'null'
                            0 => 'Нет файла',
                            1 => 'Есть файл',                    
                        ],
null != 'null' так же как и false != 'false'

Alex_N
Сообщения: 68
Зарегистрирован: 2015.03.02, 21:20

Re: GridView фильтр наличия файла

Сообщение Alex_N » 2018.12.03, 17:46

andku83 писал(а):
2018.12.03, 17:16
Alex_N писал(а):
2018.12.03, 16:54
А вот так нет:

Код: Выделить всё

($this->fnamext === 'null')
И так нет:

Код: Выделить всё

($this->fnamext == 'null')
Спасибо.
Если ваш список будет выглядеть вот так, то будет работать:

Код: Выделить всё

                    'data' =>
                        [       
                            'null' => 'Все', // null != 'null'
                            0 => 'Нет файла',
                            1 => 'Есть файл',                    
                        ],
null != 'null' так же как и false != 'false'
Вот как формирую список, однако, не выходит:

Код: Выделить всё

        $array = [
            ['userid' => 'null', 'username' => 'Не назначен'],
            ['userid' => '01', 'username' => 'Назначен'],
        ];
Там где '01', все гуд. А вот где строка 'null' или любая другая, не получается, может как то хитро строку надо еще в кавычки взять?

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: GridView фильтр наличия файла

Сообщение andku83 » 2018.12.03, 19:41

С такими уточнениями все же лучше оставаться в своей теме.

Код: Выделить всё

	if ($this->responsible_id) {
		if ($this->responsible_id === 'null') {
		        $query->andWhere(['IS', 'responsible_id', NULL]);
		} else {
			$query->andWhere(['responsible_id' => this->responsible_id]);
		}
	 }
или

Код: Выделить всё

	if ($this->responsible_id) {
		if ($this->responsible_id === 'null') {
			$this->responsible_id = null;
		}
		$query->andWhere(['responsible_id' => $this->responsible_id]);
	 }
От более точных ваших требований может измениться логика.

Alex_N
Сообщения: 68
Зарегистрирован: 2015.03.02, 21:20

Re: GridView фильтр наличия файла

Сообщение Alex_N » 2018.12.03, 21:51

andku83 писал(а):
2018.12.03, 19:41
С такими уточнениями все же лучше оставаться в своей теме.

Код: Выделить всё

	if ($this->responsible_id) {
		if ($this->responsible_id === 'null') {
		        $query->andWhere(['IS', 'responsible_id', NULL]);
		} else {
			$query->andWhere(['responsible_id' => this->responsible_id]);
		}
	 }
или

Код: Выделить всё

	if ($this->responsible_id) {
		if ($this->responsible_id === 'null') {
			$this->responsible_id = null;
		}
		$query->andWhere(['responsible_id' => $this->responsible_id]);
	 }
От более точных ваших требований может измениться логика.
Сделал, по аналогии с Вашими примерами, однако все равно, условия $this->responsible_id === 'null' и $this->responsible_id === 'notnull' не срабатывают, доходит до else и там уже выполняется. Скидываю свой код, наверняка есть какая то особенности именно в строковом атрибуте, так как, если указываю числа, все работает.

Модель User:

Код: Выделить всё

    public static function getResponsibleStatus()
    {
        $array = [
            ['userid' => 'null', 'username' => 'Не назначен'],
            ['userid' => 'notnull', 'username' => 'Назначен'],
        ];
        
        $result = ArrayHelper::map($array, 'userid', 'username');

        return $result;
    }
Модель Search:

Код: Выделить всё

        if ($this->responsible_id) {
            if ( $this->responsible_id === 'null' ) {
                $query->andWhere(['IS', 'responsible_id', NULL]);
            } elseif ( $this->responsible_id === 'notnull' ) {
                $query->andWhere(['IS NOT', 'responsible_id', NULL]);
            } else {
                $query->andFilterWhere(['responsible_id' => $this->responsible_id]);
            }
        }
Вырезка из GridView:

Код: Выделить всё

            [
                'attribute' => 'responsible_id',
                'format' => 'text',
                'content' =>  function($data){
                if ($data->responsible_id)
                    return $data->responsible->username;
                },
                'filter' => Html::activeDropDownList($searchModel, 'responsible_id',['Статус' => User::getResponsibleStatus(),['prompt' => 'Все'])
            ],

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: GridView фильтр наличия файла

Сообщение andku83 » 2018.12.04, 16:02

проверьте что у вас в responsible_id

Код: Выделить всё

        if ($this->responsible_id) {
        	var_dump($this->responsible_id);
        	...
вместо 'content' => ... можно написать:

Код: Выделить всё

	'value' => 'responsible.username',

Alex_N
Сообщения: 68
Зарегистрирован: 2015.03.02, 21:20

Re: GridView фильтр наличия файла

Сообщение Alex_N » 2018.12.05, 23:40

andku83 писал(а):
2018.12.04, 16:02
проверьте что у вас в responsible_id

Код: Выделить всё

        if ($this->responsible_id) {
        	var_dump($this->responsible_id);
        	...
вместо 'content' => ... можно написать:

Код: Выделить всё

	'value' => 'responsible.username',
var_dump($this->responsible_id) Если responsible_id приваиваю строку, то пусто вообще, ничего не показывает var_dump. А если указываю числа, то вот так:

Код: Выделить всё

string(2) "00"
Если делаю 'value' => 'responsible.username', то ошибка:

Код: Выделить всё

call_user_func() expects parameter 1 to be a valid callback, function 'responsible.username' not found or invalid function name

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: GridView фильтр наличия файла

Сообщение andku83 » 2018.12.06, 15:23

что в rules() для responsible_id?

Alex_N
Сообщения: 68
Зарегистрирован: 2015.03.02, 21:20

Re: GridView фильтр наличия файла

Сообщение Alex_N » 2018.12.17, 20:49

andku83 писал(а):
2018.12.06, 15:23
что в rules() для responsible_id?
В моделе:

Код: Выделить всё

[['responsible_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['responsible_id' => 'userid']],
В поисковой моделе:

Код: Выделить всё

[['responsible_id'], 'integer'],
В этом проблема? как лучше указать правила в обычной и поисковой моделях ?
Спасибо.

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: GridView фильтр наличия файла

Сообщение andku83 » 2018.12.18, 16:34

Alex_N писал(а):
2018.12.17, 20:49
В поисковой моделе:

Код: Выделить всё

[['responsible_id'], 'integer'],
вместо этого:

Код: Выделить всё

[['responsible_id'], 'string'],

Alex_N
Сообщения: 68
Зарегистрирован: 2015.03.02, 21:20

Re: GridView фильтр наличия файла

Сообщение Alex_N » 2019.01.01, 15:03

andku83 писал(а):
2018.12.18, 16:34
Alex_N писал(а):
2018.12.17, 20:49
В поисковой моделе:

Код: Выделить всё

[['responsible_id'], 'integer'],
вместо этого:

Код: Выделить всё

[['responsible_id'], 'string'],
Все получилось, спасибо!

Ответить