Yii2: kartik GridView - фильтр не работает, если отображается поле из отношения 1: n - PullRequest
0 голосов
/ 26 июня 2018

У меня есть вид сетки для модели, отображающий атрибут gender и поле lang_code из отношения 1: n language.

Когда я выбираю «женщина», она отображает 310 женщин (из 600 записей). Если я затем очищу фильтр, будут показаны 0 записей (вместо всех 600).

Когда я удаляю lang_code из вида, фильтр сбрасывается правильно после очистки.

Вот как я запрашиваю отношение 1: n в моем modelSearch.php:

        public $languages;

        public function rules()
        {
            return [

                    [[ ...,'languages',...], 'safe'],
                   ];
         }

        public function search($params)
        {
           $query = Sprecher::find();
           $query = $query->distinct()->joinWith(['languages', ...]);

           $dataProvider->sort->attributes['languages'] = [

                'asc' => ['language.lang_code' => SORT_ASC],
                'desc' => ['language.lang_code' => SORT_DESC],
            ];
         ...
         $query->andFilterWhere(['in', 'language.lang_code', $this->languages])
         ...
    }

Что я делаю не так?

EDIT:

полный поиск модели:

<?php

namespace app\models;

use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Sprecher;

/**
 * SprecherSearch represents the model behind the search form of `app\models\Sprecher`.
 */
class SprecherSearch extends Sprecher
{

    public $languages;
    public $dialekte;
    public $einsatzbereiche;
    public $nationalitaeten;

    /**
     * @inheritdoc
     */
    public function rules()
    {




        return [
            [['id', 'hat_erfahrung_synchron', 'ist_schauspieler', 'ist_ahv_pflichtig', 'braucht_neue_samples'], 'integer'],
            [[ 'einsatzbereiche','dialekte','languages','nationalitaeten','vorname', 'nachname', 'gender', 'stimmalter', 'stimmlage', 'stimmcharakter', 'mitglied_verein', 'bemerkungen', 'web', 'studio', 'skype', 'geburtsdatum', 'ahv_nummer'], 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        // bypass scenarios() implementation in the parent class
        return Model::scenarios();
    }

    /**
     * Creates data provider instance with search query applied
     *
     * @param array $params
     *
     * @return ActiveDataProvider
     */
    public function search($params)
    {
        $query = Sprecher::find();

        // add conditions that should always apply here

        $query = $query->distinct()->joinWith(['languages', 'dialekte', 'einsatzbereiche', 'nationalitaeten']);

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $dataProvider->sort->attributes['languages'] = [
            // The tables are the ones our relation are configured to
            // in my case they are prefixed with "tbl_"
            'asc' => ['language.lang_code' => SORT_ASC],
            'desc' => ['language.lang_code' => SORT_DESC],
        ];

        $dataProvider->sort->attributes['dialekte'] = [
            // The tables are the ones our relation are configured to
            // in my case they are prefixed with "tbl_"
            'asc' => ['dialekt.lang_code' => SORT_ASC],
            'desc' => ['dialekt.lang_code' => SORT_DESC],
        ];

        $dataProvider->sort->attributes['einsatzbereiche'] = [
            // The tables are the ones our relation are configured to
            // in my case they are prefixed with "tbl_"
            'asc' => ['einsatzbereich.bereich' => SORT_ASC],
            'desc' => ['einsatzbereich.bereich' => SORT_DESC],
        ];

        $dataProvider->sort->attributes['nationalitaeten'] = [
            // The tables are the ones our relation are configured to
            // in my case they are prefixed with "tbl_"
            'asc' => ['nationalitaet.code' => SORT_ASC],
            'desc' => ['nationalitaet.code' => SORT_DESC],
        ];



        $this->load($params);

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        // grid filtering conditions
        $query->andFilterWhere([
            'id' => $this->id,
            'hat_erfahrung_synchron' => $this->hat_erfahrung_synchron,
            'ist_schauspieler' => $this->ist_schauspieler,
            'geburtsdatum' => $this->geburtsdatum,
            'ist_ahv_pflichtig' => $this->ist_ahv_pflichtig,
            'braucht_neue_samples' => $this->braucht_neue_samples

        ]);




        $query->andFilterWhere(['in', 'gender', $this->gender]);
        $query->andFilterWhere(['in', 'stimmalter', $this->stimmalter]);
        $query->andFilterWhere(['in', 'stimmlage', $this->stimmlage]);
        $query->andFilterWhere(['in', 'stimmcharakter', $this->stimmcharakter]);

        $query->andFilterWhere(['like', 'vorname', $this->vorname])
            ->andFilterWhere(['like', 'nachname', $this->nachname])


            ->andFilterWhere(['like', 'mitglied_verein', $this->mitglied_verein])
            ->andFilterWhere(['like', 'bemerkungen', $this->bemerkungen])
            ->andFilterWhere(['like', 'web', $this->web])
            ->andFilterWhere(['like', 'studio', $this->studio])
            ->andFilterWhere(['like', 'skype', $this->skype])
            ->andFilterWhere(['like', 'ahv_nummer', $this->ahv_nummer])
            ->andFilterWhere(['in', 'language.lang_code', $this->languages])
            ->andFilterWhere(['in', 'dialekt.lang_code', $this->dialekte])
            ->andFilterWhere(['in', 'nationalitaet.code', $this->nationalitaeten])
            ->andFilterWhere(['in', 'einsatzbereich.bereich', $this->einsatzbereiche]);




        return $dataProvider;
    }
}

полная модель:

<?php

namespace app\models;

use Yii;

/**
 * This is the model class for table "sprecher".
 *
 * @property int $id
 * @property string $vorname
 * @property string $nachname
 * @property string $gender
 * @property string $nationalitaet
 * @property string $stimmalter
 * @property string $stimmlage
 * @property string $stimmcharakter
 * @property int $hat_erfahrung_synchron
 * @property int $ist_schauspieler
 * @property string $mitglied_verein
 * @property string $bemerkungen
 * @property string $web
 * @property string $studio
 * @property string $skype
 * @property string $geburtsdatum
 * @property string $ahv_nummer
 * @property int $ist_ahv_pflichtig
 * @property string $sprecher_id
 * @property string $korrespondenz_lang_code
 * @property string $tel
 * @property string $tel2
 * @property string $tel3
 * @property string $email
 * @property string $strasse
 * @property string $plz_org
 * @property string $firma
 * @property string $bank
 * @property int $ist_vps_mitglied
 * @property int $braucht_neue_samples
 *
 * @property Sample[] $samples
 * @property Dialekt[] $dialekte
 * @property language[] $languages
 * @property Einsatzbereich[] $einsatzbereiche
 * @property Nationalitaet[] $nationalitaeten
 */
class Sprecher extends \yii\db\ActiveRecord
{

    public $gender_search;

    /**
     * @var UploadedFile[]
     */
    public $imageFiles;

    public $selected = false;

    private function getSelected() {
        return $this->selected;
    }

    private static $auswahl_liste_id;

    public static function getAuswahl_liste_id()
    {
        return SPRECHER::$auswahl_liste_id;
    }

    public static function setAuswahl_liste_id($id)
    {
        Sprecher::$auswahl_liste_id = $id;
    }


    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'sprecher';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['vorname', 'nachname', 'hat_erfahrung_synchron', 'ist_schauspieler', 'braucht_neue_samples'], 'required'],
            [['hat_erfahrung_synchron', 'ist_schauspieler', 'ist_vps_mitglied', 'ist_ahv_pflichtig', 'braucht_neue_samples'], 'integer'],
            [['geburtsdatum'], 'safe'],
            [['vorname', 'nachname', 'studio', 'skype'], 'string', 'max' => 64],
            [['gender'], 'string', 'max' => 12],
            [['stimmalter'], 'string', 'max' => 7],
            [['stimmlage', 'stimmcharakter', 'mitglied_verein', 'ahv_nummer'], 'string', 'max' => 32],
            [['bemerkungen', 'web'], 'string', 'max' => 255],
            [['sprecher_id'], 'string', 'max' => 4],
            [['korrespondenz_lang_code', 'tel', 'email', 'strasse', 'plz_org', 'firma', 'bank', 'tel2', 'tel3'], 'string', 'max' => 128],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'System ID',
            'vorname' => 'Vorname',
            'nachname' => 'Nachname',
            'gender' => 'Gender',
            'stimmalter' => 'Stimmalter',
            'stimmlage' => 'Stimmlage',
            'stimmcharakter' => 'Stimmcharakter',
            'hat_erfahrung_synchron' => 'hat Synchron-Erfahrung',
            'ist_schauspieler' => 'Ist Schauspieler',
            'mitglied_verein' => 'Mitglied Verein',
            'bemerkungen' => 'Bemerkungen',
            'web' => 'Web',
            'studio' => 'Studio',
            'skype' => 'Skype',
            'geburtsdatum' => 'Geburtsdatum',
            'ahv_nummer' => 'Ahv Nummer',
            'ist_ahv_pflichtig' => 'Ist Ahv Pflichtig',
            'sprecher_id' => 'Sprecher ID',
            'korrespondenz_lang_code' => 'Korrespondenz lang_code',
            'tel' => 'Mobile 1',
            'tel2' => 'Mobile 2',
            'tel3' => 'Fixnet',
            'email' => 'Email',
            'strasse' => 'Strasse',
            'plz_org' => 'Plz Ort',
            'firma' => 'Firma',
            'bank' => 'Bank',
            'ist_vps_mitglied' => 'Ist Vps Mitglied',
            'braucht_neue_samples' => 'Braucht neue Samples'
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getSamples()
    {
        return $this->hasMany(Sample::className(), ['sprecher_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAusgewaehlteSprechers()
    {
        return $this->hasMany(AusgewaehlteSprecher::className(), ['sprecher_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAuswahls()
    {
        return $this->hasMany(Auswahl::className(), ['id' => 'auswahl_id'])->viaTable('ausgewaehlte_sprecher', ['sprecher_id' => 'id']);
    }



    public function upload()
    {
        if ($this->validate()) {
            foreach ($this->imageFiles as $file) {

                $file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);

                $sample = new Sample();
                $sample->sprecher_id = $this->id;
                $sample->url = 'uploads/' . $file->baseName . '.' . $file->extension;
                $sample->save();

            }
            return true;
        } else {
            return false;
        }
    }


    private $_ganzer_name = null;

    public function getGanzer_name() {
        return $this->vorname . " " . $this->nachname;
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getlanguages()
    {
        return $this->hasMany(language::className(), ['sprecher_id' => 'id']);
    }

    public function getlang_coden()
    {
        return $this->hasMany( language::className(), [ 'id' => 'categoryID' ] )
            ->via('PeopleCategoriesAssn');
    }

    public function getAllTel() {
        return
            ( empty($this->tel) == false ?'<span title="mobile 1" class="pre">'.$this->tel.'</span>' . "<br/>" : '').
            ( empty($this->tel2) == false ?'<span title="mobile 2" class="pre">'.$this->tel2.'</span>' . "<br/>" : '').
            ( empty($this->tel3) == false ?'<span title="fixnet" class="pre">'.$this->tel3.'</span>' . "<br/>" : '');


    }


    public function getlanguages_txt() {
        $languages = $this->languages;
        $languages_array = array();
        foreach ($languages as $language) {
            $languages_array[] = $language->lang_code;
        }
        return implode(",", $languages_array);
    }


    /**
     * @return \yii\db\ActiveQuery
     */
    public function getDialekte()
    {
        return $this->hasMany(Dialekt::className(), ['sprecher_id' => 'id']);
    }

    public function getDialekte_txt() {
        $languages = $this->dialekte;
        $languages_array = array();
        foreach ($languages as $language) {
            $languages_array[] = $language->lang_code;
        }
        return implode(",", $languages_array);
    }


    /**
     * @return \yii\db\ActiveQuery
     */
    public function getEinsatzbereiche()
    {
        return $this->hasMany(Einsatzbereich::className(), ['sprecher_id' => 'id']);
    }



    public function getEinsatzbereiche_txt()
    {
        $languages = $this->einsatzbereiche;
        $languages_array = array();
        foreach ($languages as $language) {
            $languages_array[] = $language->bereich;
        }
        return implode("-", $languages_array);
    }

    public function getNationalitaeten()
    {
        return $this->hasMany(Nationalitaet::className(), ['sprecher_id' => 'id']);
    }


    public function getNationalitaeten_txt()
    {

        $languages = $this->nationalitaeten;
        $languages_array = array();
        foreach ($languages as $language) {
            $languages_array[] = $language->code;
        }
        return implode("-", $languages_array);
    }





    /**
     * @inheritdoc
     * @return SprecherQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new SprecherQuery(get_called_class());
    }
}

Просмотр с помощью GridView:

<?php

use yii\helpers\Html;
use yii\widgets\Pjax;
use kartik\grid\GridView;
use kartik\widgets\Select2;
use yii\helpers\Url;
use yii\helpers\ArrayHelper;
use kartik\widgets\ActiveForm;
use app\models\Sprecher;

/* @var $this yii\web\View */
/* @var $searchModel app\models\SprecherSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = 'Sprecher';
$this->params['breadcrumbs'][] = $this->title;

$this->registerJsFile(
    '@web/js/main.js',
    ['depends' => [\yii\web\JqueryAsset::className()]]
);
?>

<p>
   <!-- <?= Html::a('Create Sprecher', ['create'], ['class' => 'btn btn-success']) ?>-->
</p>

<?php $listen = \app\models\Auswahl::find()->all(); ?>
<div class="auswahl-form">

    <!--  <?php $form = ActiveForm::begin(); ?>


 <?= Html::DropDownList("auswahl", 'titel', ArrayHelper::map($listen, 'id', 'titel'),array('prompt'=>'Liste auswählen:', 'options'=>array((isset($auswahl->id) ? $auswahl->id: 0) => array("selected"=>"selected")))) ?>
    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>-->

</div>

<?php



?>

<div class="sprecher-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <?php

    $data = [
        'Mann' => 'Mann',
        'Frau' => 'Frau',
        'Junge' => 'Junge',
        'Mädchen' => 'Mädchen',
    ];

    $lang_coden = [];
    $query = new yii\db\Query();
    $sprach_codes = $query->select(['lang_code'])
        ->from('languages')
        ->distinct()
        ->all();


    foreach ($sprach_codes as $sprach_code) {
        $lang_coden[$sprach_code["lang_code"]] = $sprach_code["lang_code"];
    }



    $dialekt_codes = $query->select(['lang_code'])
        ->from('dialekt')
        ->distinct()
        ->all();

    $dialekte = [];

    foreach ($dialekt_codes as $dialekt_code) {
        $dialekte[$dialekt_code["lang_code"]] = $dialekt_code["lang_code"];
    }


    $einsatzbereich_codes = $query->select(['bereich'])
        ->from('einsatzbereich')
        ->distinct()
        ->all();

    $einsatzbereiche = [];

    foreach ($einsatzbereich_codes as $einsatzbereich_code) {
        $einsatzbereiche[$einsatzbereich_code["bereich"]] = $einsatzbereich_code["bereich"];
    }


    $nation_codes = $query->select(['code'])
        ->from('nationalitaet')
        ->distinct()
        ->all();

    $nationen = [];

    foreach ($nation_codes as $nation_code) {
        $nationen[$nation_code["code"]] = $nation_code["code"];
    }







    // Generate a bootstrap responsive striped table with row highlighted on hover
    echo GridView::widget([
    'dataProvider'=> $dataProvider,
    'filterModel' => $searchModel,

        'pjax'=>true,

        'toolbar'=> [

            ['content'=>

                Html::a('<i class="glyphicon glyphicon-plus"></i>', ['create'], ['data-pjax'=>0,'title'=>'Sprecher erfassen', 'class'=>'btn btn-default', 'title'=>'Reset Grid']).
                Html::a('<i class="glyphicon glyphicon-repeat"></i>', ['index'], ['data-pjax'=>0, 'class'=>'btn btn-default', 'title'=>'Reset Grid'])

            ],
            '{export}',
            '{toggleData}',

        ],
        'panel'=>[
            'type'=>GridView::TYPE_PRIMARY,
            'heading' => $this->title,

        ],
        'toggleDataOptions' =>
            [
                'all' => [
                    'icon' => 'resize-full',
                    'label' => 'Alle',
                    'class' => 'btn btn-default',
                    'title' => 'Zeige alle Datensätze'
                ],
                'page' => [
                    'icon' => 'resize-small',
                    'label' => 'Seiten',
                    'class' => 'btn btn-default',
                    'title' => 'Zeige erste Datenseite'
                ],
            ],
   'columns' => [
       [
           'class' => '\kartik\grid\CheckboxColumn'
       ],

       'vorname',
       'nachname',
       [
           'attribute' => 'gender',
           'filter' => $data,
           'filterType' => '\kartik\widgets\Select2',
           'filterWidgetOptions' => [
               'data' => $data,
               'hideSearch'=>true,
               'pluginOptions' => [
                   'allowClear' => true
               ],
               'options' => ['placeholder' => 'Wähle ...', 'multiple' => true, 'hideSearch'=>true,'allowClear' => true,],
           ]


       ],
       [
           'attribute' => 'nationalitaeten',
           'label' => 'Nat.',
           'filter' => $lang_coden,
           'filterType' => '\kartik\widgets\Select2',
           'filterWidgetOptions' => [
               'data' => $nationen,
               'hideSearch'=>true,
               'pluginOptions' => [
                   'allowClear' => true
               ],
               'options' => ['placeholder' => 'Wähle ...', 'multiple' => true, 'hideSearch'=>true,'allowClear' => true,],
           ],
           'value' => 'nationalitaeten_txt'

       ],

       [
           'attribute' => 'dialekte',
           'filter' => $dialekte,
           'filterType' => '\kartik\widgets\Select2',
           'filterWidgetOptions' => [
               'data' => $dialekte,
               'hideSearch'=>true,
               'pluginOptions' => [
                   'allowClear' => true
               ],
               'options' => ['placeholder' => 'Wähle ...', 'multiple' => true, 'hideSearch'=>true,'allowClear' => true,],
           ],
           'value' => 'dialekte_txt'
       ]
       ,
       [
           'attribute' => 'einsatzbereiche',
           'label' => 'Bereich',
           'filter' => $einsatzbereiche,
           'filterType' => '\kartik\widgets\Select2',
           'filterWidgetOptions' => [
               'data' => $einsatzbereiche,
               'hideSearch'=>true,
               'pluginOptions' => [
                   'allowClear' => true
               ],
               'options' => ['placeholder' => 'Wähle ...', 'multiple' => true, 'hideSearch'=>true,'allowClear' => true,],
           ],
           'value' => 'einsatzbereiche_txt'
       ]
       ,
       [
           'attribute' => 'stimmalter',

           'filter' => array("0-20"=>"0-20","20-40"=>"20-40","40-60"=>"40-60","60-80"=>"60-80"),
           'filterType' => '\kartik\widgets\Select2',
           'filterWidgetOptions' => [
               'data' => array("0-20"=>"0-20","20-40"=>"20-40","40-60"=>"40-60","60-80"=>"60-80"),
               'hideSearch'=>true,
               'pluginOptions' => [
                   'allowClear' => true
               ],
               'options' => ['placeholder' => 'Wähle ...', 'multiple' => true, 'hideSearch'=>true,'allowClear' => true,],
           ]


       ],
       [
           'attribute' => 'stimmlage',
           'filter' => array("hoch"=>"hoch","mittel"=>"mittel","tief"=>"tief"),
           'filterType' => '\kartik\widgets\Select2',
           'filterWidgetOptions' => [
               'data' => array("hoch"=>"hoch","mittel"=>"mittel","tief"=>"tief"),
               'hideSearch'=>true,
               'pluginOptions' => [
                   'allowClear' => true
               ],
               'options' => ['placeholder' => 'Wähle ...', 'multiple' => true, 'hideSearch'=>true,'allowClear' => true,],
           ]


       ],
       [
           'attribute' => 'stimmcharakter',
           'label' => 'Charakter',
           'filter' => array("frisch"=>"frisch","hell"=>"hell","neutral"=>"neutral","rauchig"=>"rauchig","seriös"=>"seriös","sonor"=>"sonor"),
           'filterType' => '\kartik\widgets\Select2',
           'filterWidgetOptions' => [
               'data' => array("frisch"=>"frisch","hell"=>"hell","neutral"=>"neutral","rauchig"=>"rauchig","seriös"=>"seriös","sonor"=>"sonor"),
               'hideSearch'=>true,
               'pluginOptions' => [
                   'allowClear' => true
               ],
               'options' => ['placeholder' => 'Wähle ...', 'multiple' => true, 'hideSearch'=>true,'allowClear' => true,],
           ]


       ],
       [
           'class' => '\kartik\grid\BooleanColumn',
           'attribute' => 'ist_schauspieler',
           'label' => 'Actor',
           'trueLabel' => 'Yes',
           'falseLabel' => 'No'
       ],

       [
           'class' => '\kartik\grid\BooleanColumn',
           'attribute' => 'hat_erfahrung_synchron',
           'label' => 'Sync',
           'trueLabel' => 'Yes',
           'falseLabel' => 'No',


       ],

       'bemerkungen',


       [
           'attribute' => 'Samples',
           'format' => 'raw',
           'value' => function ($model) {
               $samples = $model->samples;
               return Yii::$app->controller->renderPartial('_samples', [ 'samples' => $samples]);
           },
       ],
       [
           'attribute' => 'allTel',
           'label' => 'Tel',
           'format' => 'html',
           'value' => 'allTel'
       ],
       [
           'class' => '\kartik\grid\BooleanColumn',
           'attribute' => 'braucht_neue_samples',
           'label' => 'ToDo',
           'trueLabel' => 'Yes',
           'falseLabel' => 'No',


       ],


       [
           'class' => 'yii\grid\ActionColumn',
           'buttons' => []
       ]

   ],
    'responsive'=>true,
    'hover'=>true,
        'resizableColumns'=>true,
        'resizeStorageKey'=>Yii::$app->user->id . '-' . date("m"),
    ]);
?>
</div>
<script type="text/javascript">

   /* $( document ).ready(function() {
        var files = [document.getElementById("dragout")],
            fileDetails = [];

        // Some forward thinking, utilise the custom data attribute to extend attributes available.
        if(typeof files[0].dataset === "undefined") {
            // Grab it the old way
            fileDetails[0] = files[0].getAttribute("data-downloadurl");

        } else {
            fileDetails[0] = files[0].dataset.downloadurl;

        }

        files[0].addEventListener("dragstart",function(evt){
            evt.dataTransfer.setData("DownloadURL",fileDetails[0]);
        },false);

    });
*/

</script>
...