A
A
alex5e2014-02-11 20:08:39
Yii
alex5e, 2014-02-11 20:08:39

How to implement ListView filtering by dependent lists?

I'm trying to filter a ListView using dependent lists (Country->Region->City). The problem is that when you remove the filter from the list of countries, the list with regions and cities is reset as expected, and if you select a different value in the list of countries without manually removing the value from the list of regions and cities, then the filtering stops working correctly.
If I check if( strlen( $country ) > 0 ) on the contrary, then when choosing a new value from the list of countries, the list with regions and cities will be reset, but then it will not be possible to filter by regions, because $state and $town will be cleared. How can I make sure that when the value of the first list changes, the rest are reset, but not to the detriment of further selection?
Controller

public function actionIndex($string = '', $cat='', $type='', $country='', $state='', $town='')
{
...
$criteria = new CDbCriteria(); // Создаем фильтр для поиска объявления
        if( strlen( $string ) > 0 )
        {
            $criteria->addSearchCondition( 'title', $string, true, 'OR' ); //Поиск по заголовку
            $criteria->addSearchCondition( 'text', $string, true, 'OR' ); //Поиск по содержимому
        }
        if( strlen( $cat ) > 0 )
        {
            $category = Category::model()->GetCategory($cat);
            $criteria->addSearchCondition( 'category_id', $cat, true, 'AND' ); // Фильтрация по категориям
        }
        if( strlen( $type ) > 0 )
        {
            $criteria->addSearchCondition( 'find_loss', $type, true, 'AND' ); // Фильтрация по типу объявления
        }
        if( strlen( $country ) > 0 )
        {
            $criteria->addSearchCondition( 'country_id', $country, true, 'AND' ); // Фильтрация по стране
        }
        else
        {
            $state='';
            $town='';
        }
        if( strlen( $state ) > 0 ) // Фильтрация по региону
        {
            $criteria->addSearchCondition( 'state_id', $state, true, 'AND' );
        }
        else
        {
            $town='';
        }
        if( strlen( $town ) > 0 ) // Фильтрация по городу
        {
            $criteria->addSearchCondition( 'town_id', $town, true, 'AND' );
        }
        $dataProvider=new CActiveDataProvider('Posts', array( 'criteria' => $criteria,

        'sort'=>array(
                    'attributes'=>array(
                        'date_post'=>array(
                            'asc'=>'date_post ASC',
                            'desc'=>'date_post DESC',
                            'default'=>'DESC',
                        )
                    ),
                    'defaultOrder'=>array(
                        'date_post'=>CSort::SORT_DESC,
                    )
                ),
         ));
        $this->render('index', array(
        'dataProvider'=>$dataProvider,
            ));
...
  public function actionUpStateIndex() // Для выборки города
    {
        if ($_POST['country'] == "") //Проверяем, не выбрано ли 'empty'
        {
            echo 'close'; // Выводим соотв. слово 'close'
            Yii::app()->end(); 
        }

        $districts = State::model()->findAll('country_id=:country_id', array(':country_id' => (int) $_POST['country'])); // тащим регион по стране
        $return = CHtml::listData($districts, 'id', 'name'); // формируем массив
        echo "<option value=''>В любом регионе</option>";
        foreach ($return as $districtId => $districtName) 
        {
            echo CHtml::tag('option', array('value' => $districtId), CHtml::encode($districtName), true);
        }
    }

    public function actionUpCityIndex() // Для выборки города
    {
        if ($_POST['state'] == "") //Проверяем, не выбрано ли 'empty'
        {
            echo 'close'; // Выводим соотв. слово 'close'
            Yii::app()->end(); 
        }

        $districts = City::model()->findAll('state_id=:state_id', array(':state_id' => (int) $_POST['state'])); // тащим город по региону
        $return = CHtml::listData($districts, 'id', 'name'); // формируем массив
        echo "<option value=''>В любом городе</option>";
        foreach ($return as $districtId => $districtName) 
        {
            echo CHtml::tag('option', array('value' => $districtId), CHtml::encode($districtName), true);
        }
    }
    }

view
...

    Yii::app()->clientScript->registerScript('search',
        "var ajaxUpdateTimeout;
        var ajaxRequest;

                $('#country').change(function(){
            ajaxRequest = $(this).serialize();
            clearTimeout(ajaxUpdateTimeout);
         //   $('#state :selected').val('');
           // $('#town :selected').val('');
            ajaxUpdateTimeout = setTimeout(function () {
                $.fn.yiiListView.update(
    // this is the id of the CListView
                    'ajaxListView',
                    {data: ajaxRequest}
                )
            },


    // this is the delay
            300);
        });


                $('#state').change(function(){
            ajaxRequest = $(this).serialize();
            clearTimeout(ajaxUpdateTimeout);
            ajaxUpdateTimeout = setTimeout(function () {
                $.fn.yiiListView.update(
    // this is the id of the CListView
                    'ajaxListView',
                    {data: ajaxRequest}
                )
            },


    // this is the delay
            300);
        });

                $('#town').change(function(){
            ajaxRequest = $(this).serialize();
            clearTimeout(ajaxUpdateTimeout);
            ajaxUpdateTimeout = setTimeout(function () {
                $.fn.yiiListView.update(
    // this is the id of the CListView
                    'ajaxListView',
                    {data: ajaxRequest}
                )
            },


    // this is the delay
            300);
        });"


    );
    echo CHtml::beginForm(CHtml::normalizeUrl(array('posts/index')), 'get', array('id'=>'filter-form'));
    echo CHtml::textField('string', (isset($_GET['string'])) ? $_GET['string'] : '', array('id'=>'string', 'style'=>'margin:0px;'));
    echo CHtml::dropDownList('cat',(isset($_GET['cat'])) ? $_GET['cat'] : '', Category::model()->categories(), array('empty'=>'Во всех категориях', 'style'=>'margin:0px;margin-left:5px;'));
    echo CHtml::dropDownList('type', (isset($_GET['type'])) ? $_GET['type'] : '', array('1'=>"Пропажа", '2'=>"Находка"), array('empty'=>'Любой тип', 'style'=>'margin:0px;margin-left:5px;'));echo CHtml::tag('br');

    echo CHtml::dropDownList('country', (isset($_GET['country'])) ? $_GET['country'] : '', Country::model()->countries(), array('empty'=>'В любой стране', 'style'=>'margin:0px;margin-top:5px;',
                'ajax'=>array(
                'type'=>'POST',
                'url'=>CController::createUrl('Posts/UpStateIndex'),
                    //'update'=>'#Posts_state_id',
                    'success'=>'function(data){
        if(data == "close") 
        {

            $("#state").attr("disabled", "disabled");
            $("#town").attr("disabled", "disabled");
        }
        else
        {
            $("#state").removeAttr("disabled");
            $("#state").html(data); 
        }
            if($("#state :selected").val()!="")
            $("#state :selected").remove();
            if($("#town :selected").val()!="")
            $("#town :selected").remove();
    }')));
    echo CHtml::dropDownList('state', (isset($_GET['state'])) ? $_GET['state'] : '', State::model()->states(), array('empty'=>'В любом регионе', 'disabled'=>"disabled", 'style'=>'margin:0px;margin-top:5px;margin-left:5px;',
                'ajax'=>array(
                'type'=>'POST',
                'url'=>CController::createUrl('Posts/UpCityIndex'),
                    //'update'=>'#Posts_state_id',
                    'success'=>'function(data){
        if(data == "close") 
        {
            if($("#town :selected").val()!="")
            $("#town :selected").remove();
            $("#town").attr("disabled", "disabled");
        }
        else
        {
            $("#town").removeAttr("disabled");
            $("#town").html(data);
        }
    }')));
    echo CHtml::dropDownList('town', (isset($_GET['town'])) ? $_GET['town'] : '', City::model()->cityes(), array('empty'=>'В любом городе', 'disabled'=>"disabled", 'style'=>'margin:0px;margin-top:5px;margin-left:5px;'));
    $this->widget('bootstrap.widgets.TbButton',array(
            'buttonType' => 'submit',
            'type'=>'success',
            'icon' => 'icon-search icon-white',
            'htmlOptions' => array ( 'name' => 'submit-type', 'value' => 'index', 'style'=>'margin:0px; margin-left:5px;font-weight:bold;' ),
            'label' => Yii::t( 'addad', 'искать' ),));
    echo CHtml::endForm(); ?>
            </div>
        </div>
    </div>
    <?php $this->
    endClip(); ?>
    <?php 
    $this->
    widget('zii.widgets.CListView', array(
        'id'=>'ajaxListView',
        'dataProvider'=>$dataProvider,
        'itemView'=>'_allad',  
        'template'=>"{items}{pager}",
        'sortableAttributes'=>array(
                               'post_id',
                               'date_post',
                           ),
        'pager' => array(
        'class'=>'CLinkPager',
            'header'=>false,
            'cssFile'=>false,
            'htmlOptions'=>array('class'=>'pager'),
    ),              
     ))

Answer the question

In order to leave comments, you need to log in

2 answer(s)
C
Centrino, 2015-04-13
@JustFool

Well, in your code you have $form->field($model, 'name') and it returns name, but where is your output to the form id?
I don't know what IDE you have, but I recommend debugging first! What is passed to the output, in what format, what are you passing to your widget.

A
Alexander N++, 2015-04-13
@sanchezzzhak

You can even understand without a debugger what is being transmitted through the developer console in the F12 browser.
XDebug is a plugin for chrome very convenient to use
Here is the link https://chrome.google.com/webstore/detail/xdebug-h...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question