Error With Parsing $_Post Data In Controller, And Rendering Cgridview

Hi, i’m facing a problem passing the correct value to the grid widget in the view. The data is being passed from jquery using ajax.

Here is the code::





$('#find-product').click(function(e) {

        e.preventDefault();




        alert($('#find-product').data("url"));




        /*

         * Make the ajax call to send the selected option to the controller for processing

         * URL : $('#find-product').data("url") , the path of the controller's action

         * Dropdown : the obejct that is passed to the controller

         * 

         * Dropdown.category : the category selected

         * Dropdown.price : the price range selected

         * 

         * 

         */


        $.ajax({

            url: $('#find-product').data("url"),

            data: {

                Dropdown: {

                    category: $('#supp-category').find(":selected").text(),

                    price: $('#supp-price').find(":selected").text()

                }


            },

            type: "POST",

            error: function(xhr, tStatus, e) {

                if (!xhr) {

                    alert(" We have an error ");

                    alert(tStatus + "   " + e.message);

                } else {

                    alert("else: " + e.message); // the great unknown

                }

            },

            success: function(resp) {

                document.location.href = $('#find-product').data("url");

            }


        })

    });






So i want to send the object named Dropdown to the controller action. In this case its /products/dropdown.

In the actionDropdown() i’m trying to form a CDbCriteria and passing it to CActiveDataProvider so that i may use it to render the grid.

Here is the code for the actionDropdown in the ProductsController ::





public function actionDropdown() {

        

        

        $criteria = new CDbCriteria;

        $criteria->compare('category', $_POST['Dropdown']['category'], true);

        

        $dataProvider = new CActiveDataProvider('Products', array(

                'criteria' => $criteria,

                

        ));

        

        

        $this->render('selectproducts', array(

            'dataProvider' => $dataProvider,

        ));

       

        

        

    }



And here is the view, called selectproducts.





<div class="row">




            <?php

            $this->widget('bootstrap.widgets.TbGridView', array(

                'id' => 'products-grid',

                'dataProvider' => $dataProvider,

               

                'filter' => $dataProvider,

                'columns' => array(

                    'id',

                    'name',

                    'category',

                    'brand',

                    'weight_unit',

                    'price_unit',

                    'flavors',

                    'providers',

                ),

            ));

            ?>


        </div>



Now this is giving me an CException error. Here is the error stack trace::





CException


CActiveDataProvider and its behaviors do not have a method or closure named "getValidators". (/var/www/html/yii/framework/base/CComponent.php:266)


#0 /var/www/html/yii/framework/web/helpers/CHtml.php(2236): CComponent->__call('getValidators', Array)

#1 /var/www/html/yii/framework/web/helpers/CHtml.php(2236): CActiveDataProvider->getValidators('id')

#2 /var/www/html/yii/framework/web/helpers/CHtml.php(1434): CHtml::activeInputField('text', Object(CActiveDataProvider), 'id', Array)

#3 /var/www/html/EasyAesthetics/protected/extensions/yiibooster/widgets/TbDataColumn.php(109): CHtml::activeTextField(Object(CActiveDataProvider), 'id', Array)

#4 /var/www/html/EasyAesthetics/protected/extensions/yiibooster/widgets/TbDataColumn.php(74): TbDataColumn->renderFilterCellContent()

#5 /var/www/html/yii/framework/zii/widgets/grid/CGridView.php(532): TbDataColumn->renderFilterCell()

#6 /var/www/html/yii/framework/zii/widgets/grid/CGridView.php(510): CGridView->renderFilter()

#7 /var/www/html/yii/framework/zii/widgets/grid/CGridView.php(480): CGridView->renderTableHeader()

#8 /var/www/html/yii/framework/zii/widgets/CBaseListView.php(167): CGridView->renderItems()

#9 [internal function]: CBaseListView->renderSection(Array)

#10 /var/www/html/yii/framework/zii/widgets/CBaseListView.php(150): preg_replace_callback('/{(\w+)}/', Array, '{summary}?{item...')

#11 /var/www/html/yii/framework/zii/widgets/CBaseListView.php(135): CBaseListView->renderContent()

#12 /var/www/html/yii/framework/web/CBaseController.php(173): CBaseListView->run()

#13 /var/www/html/EasyAesthetics/protected/views/products/selectproducts.php(37): CBaseController->widget('bootstrap.widge...', Array)

#14 /var/www/html/yii/framework/web/CBaseController.php(126): require('/var/www/html/E...')

#15 /var/www/html/yii/framework/web/CBaseController.php(95): CBaseController->renderInternal('/var/www/html/E...', Array, true)

#16 /var/www/html/yii/framework/web/CController.php(869): CBaseController->renderFile('/var/www/html/E...', Array, true)

#17 /var/www/html/yii/framework/web/CController.php(782): CController->renderPartial('selectproducts', Array, true)

#18 /var/www/html/EasyAesthetics/protected/controllers/ProductsController.php(248): CController->render('selectproducts', Array)

#19 /var/www/html/yii/framework/web/actions/CInlineAction.php(49): ProductsController->actionDropdown()

#20 /var/www/html/yii/framework/web/CController.php(308): CInlineAction->runWithParams(Array)

#21 /var/www/html/yii/framework/web/filters/CFilterChain.php(133): CController->runAction(Object(CInlineAction))

#22 /var/www/html/yii/framework/web/filters/CFilter.php(40): CFilterChain->run()

#23 /var/www/html/yii/framework/web/CController.php(1145): CFilter->filter(Object(CFilterChain))

#24 /var/www/html/yii/framework/web/filters/CInlineFilter.php(58): CController->filterAccessControl(Object(CFilterChain))

#25 /var/www/html/yii/framework/web/filters/CFilterChain.php(130): CInlineFilter->filter(Object(CFilterChain))

#26 /var/www/html/yii/framework/web/CController.php(291): CFilterChain->run()

#27 /var/www/html/yii/framework/web/CController.php(265): CController->runActionWithFilters(Object(CInlineAction), Array)

#28 /var/www/html/yii/framework/web/CWebApplication.php(282): CController->run('dropdown')

#29 /var/www/html/yii/framework/web/CWebApplication.php(141): CWebApplication->runController('products/dropdo...')

#30 /var/www/html/yii/framework/base/CApplication.php(180): CWebApplication->processRequest()

#31 /var/www/html/EasyAesthetics/index.php(13): CApplication->run()

#32 {main}




I cannot for the life of me figure out what is causing this error. Please provide any sort of help, any tip that will head me in the right direction.

Thanks, in advance.

Maxx

Hi Maxx,

The immediate cause of the error is the ‘filter’ property of the grid:

But I’m afraid correcting only this won’t give you the desired result.

I don’t understand the ‘success’ function of your ajax call.

If you want to update the grid content via ajax using dropdown, you would be better starting from the gii-generated admin page.

  1. Modify the advanced search form … delete unnecessary fields, and change some text field to dropdown.

  2. … oh, nothing more to do. It’s almost done.

I hope this wiki will help you understand the gridview.

http://www.yiiframework.com/wiki/381/cgridview-clistview-and-cactivedataprovider

Oh, thank you a lot, changing the ‘filter’ property to $dataprovider->model solved the issue. But i’m getting a new error ::




Undefined index: Dropdown 

$criteria->compare('category', $_POST['Dropdown']['category'], true);



Can’t figure out what is causing that actually.

In the success call what i’m doing is merely redirecting the user to the page rendered by the action url of the ajax call. I know it defies the purpose but i had to do it, because i’m using a custom dropdown ( because the look of the default select dropdown won’t suit the theme ) and a custom anchor element which acts as the submit button (also because the default look won’t suit the theme).

Yes i have been reading the CGridview wiki which you wrote, to make the custom grid. An excellent reference btw. And i also kept the gridview in the admin as the basic template.

All i wanted to do is to get the option that the user will select from the custom select dropdown, and send it to the controller’s action method, using ajax ( in the Dropdown[] array in my case ). The controller will then run a SQL like statement to get the necessary result. This result will then be used to render the grids.

But i’m having trouble making this whole process work. Thanks again for you help.

Your actionDropdown seems to be called twice: once by the ajax call and the other by the redirection.

There’s no $_POST in the latter, hence the error. (The error is in the 2nd call, not in the 1st ajax call.)

In other words, your 1st ajax call is working good. There’s no need to redirect. You just have to replace the gridview content by the response.

Something like this?




    'success' : function(resp) {

        $('#grid-view-id').replaceWith($('#grid-view-id', resp));

    }



Wow that is very nifty indeed. Thanks a lot for this advice. Works perfectly.

One more thing, if its not much to ask. Can you please provide any suggestion on how do i customize only specific columns in the Gridview. Like in some column i want to show a button, in some i want to apply custom styling, and so on. Is there a easy way to do this. I’m still learning Yii, and am simply amazed by the potential and the capability of CGridview mainly exemplified by you wiki article. So i was thinking maybe there is also a public property which would allow me to do this easily :) .

Thanks again for all your help. You’re a lifesaver literally.

Maxx

Uh, CGridColumn and its derivatives are also very powerful, indeed. I don’t think I’m using them to their maximum potentials. So I’m very sorry that I can’t give you a quick answer to it.

Probably the class reference is the best source.

http://www.yiiframework.com/doc/api/1.1/CGridColumn

Great, i will look into it. Thanks again.