Reputation: 602
I'm having problem with the filter functionality in CGridview. The filter box doesn't works at all. Nothing happens when i type something, and hit enter.
Here is the view code selectproducts.php ::
<div id="shortcodes" class="page">
<div class="container">
<!-- Title Page -->
<div class="row">
<div class="span12">
<div class="title-page">
<h2 class="title">Available Products</h2>
</div>
</div>
</div>
<!-- End Title Page -->
<!-- Start Product Section -->
<div class="row">
<?php
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'products-grid',
'dataProvider' => $dataProvider,
'filter' => $dataProvider->model,
'ajaxUpdate' => TRUE,
'pager' => array(
'header' => '',
'cssFile' => false,
'maxButtonCount' => 25,
'selectedPageCssClass' => 'active',
'hiddenPageCssClass' => 'disabled',
'firstPageCssClass' => 'previous',
'lastPageCssClass' => 'next',
'firstPageLabel' => '<<',
'lastPageLabel' => '>>',
'prevPageLabel' => '<',
'nextPageLabel' => '>',
),
'columns' => array(
'id',
array(
'name' => 'name',
),
'category',
'brand',
'weight_unit',
'price_unit',
'flavors',
array(
'name' => 'providers',
'value' => function($data) {
return '<div class="provider-label label label-info"><a href="http://www.'.$data->providers. '">'. $data->providers .'</a></div>';
},
'type' => 'raw',
),
),
));
?>
</div>
<!-- End Product Section -->
</div>
Here is the relevant action in ProductsController that is rendering this view. The $dataprovider variable in the view is a CActiveDataProvider object which holds the result of a conditional query.
public function actionDropdown() {
if (isset($_GET["Dropdown"])) {
$dropdownData = $_GET["Dropdown"];
$this->category = $dropdownData["category"];
$this->price = $dropdownData["price"];
}
// separate the price text into min and max value
$priceText = explode(" - ", $this->price);
$criteria = new CDbCriteria;
$criteria->compare('category', $this->category, true);
$criteria->addBetweenCondition('price', substr($priceText[0], 1), substr($priceText[1], 1), 'AND');
$dataProvider = new CActiveDataProvider('Products', array(
'criteria' => $criteria,
'pagination' => array(
'pageSize' => 20,
),
'sort' => array(
'defaultOrder' => 'price_unit, name',
),
));
$this->render('selectproducts', array(
'dataProvider' => $dataProvider,
'criteria' => $criteria,
));
}
And here is the Products() model search() function ::
public function search()
{
// @todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('name',$this->name,true);
$criteria->compare('category',$this->category,true);
$criteria->compare('brand',$this->brand,true);
$criteria->compare('weight',$this->weight,true);
$criteria->compare('weight_unit',$this->weight_unit,true);
$criteria->compare('price',$this->price,true);
$criteria->compare('price_unit',$this->price_unit,true);
$criteria->compare('flavors',$this->flavors,true);
$criteria->compare('providers',$this->providers,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
Now, when i hit enter in the filter box, i'm getting this error, which is logged in firebug
TypeError: $.param.querystring is not a function
[Break On This Error]
options.url = $.param.querystring(options.url, options.data);
In file jquery.yiigridview.js
Does anyone knows what is causing this error. I just can't figure out what is causing this. And i also don't know what modification should i do in jquery.yiigridview.js to fix this error.
Thanks in advance. Maxx
EDIT
After suggestion from tinyByte below. I tried to move the CActiveDataProvider logic to the model, so that i can use $model->search() in the GridView 'dataProvider' property, but it didn't helped still the same error.
Here are the codes
Controller:::
public function actionDropdown() {
$dataProvider = new Products;
if (isset($_GET["Dropdown"])) {
$dropdownData = $_GET["Dropdown"];
$this->category = $dropdownData["category"];
$this->price = $dropdownData["price"];
}
$this->render('selectproducts', array(
'dataProvider' => $dataProvider,
'category' => $this->category,
'price' => $this->price,
//'num' => $this->numResults,
));
}
Here is the model ::
public function searchDropdown($category, $price) {
$this->priceText = explode(" - ", $price);
$this->criteria = new CDbCriteria;
$this->criteria->compare('category', $category, true);
$this->criteria->addBetweenCondition('price', substr($this->priceText[0], 1), substr($this->priceText[1], 1), 'AND');
return new CActiveDataProvider('Products', array(
'criteria' => $this->criteria,
'pagination' => array(
'pageSize' => 25,
),
'sort' => array(
'defaultOrder' => 'price_unit, name',
),
));
}
And here is the view ::
<div id="shortcodes" class="page">
<div class="container">
<!-- Title Page -->
<div class="row">
<div class="span12">
<div class="title-page">
<h2 class="title">Available Products</h2>
</div>
</div>
</div>
<!-- End Title Page -->
<!-- Start Product Section -->
<div class="row">
<?php
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'products-grid',
'dataProvider' => $dataProvider->searchDropdown($category, $price),
'filter' => $dataProvider,
'ajaxUpdate' => TRUE,
'pager' => array(
'header' => '',
'cssFile' => false,
'maxButtonCount' => 25,
'selectedPageCssClass' => 'active',
'hiddenPageCssClass' => 'disabled',
'firstPageCssClass' => 'previous',
'lastPageCssClass' => 'next',
'firstPageLabel' => '<<',
'lastPageLabel' => '>>',
'prevPageLabel' => '<',
'nextPageLabel' => '>',
),
'columns' => array(
array(
'name' => 'id',
'type' => 'raw',
),
array(
'name' => 'name',
),
'category',
'brand',
'weight_unit',
'price_unit',
'flavors',
array(
'name' => 'providers',
'value' => function($data) {
return '<div class="provider-label label label-info"><a href="http://www.'.$data->providers. '">'. $data->providers .'</a></div>';
},
'type' => 'raw',
),
),
));
?>
</div>
<!-- End Product Section -->
</div>
Still its not working. i.e. Nothing happens when i type something in the filter box and hit enter. The same error comes up ::
In Firebug
TypeError: $.param.querystring is not a function
[Break On This Error]
options.url = $.param.querystring(options.url, options.data);
In file jquery.yiigridview.js
And in Chrome i get a slightly more descriptive error message.
Uncaught TypeError: Object function (e,n){var r,i=[],o=function(e,t)
{t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&
x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});
else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")}
has no method 'querystring'
jquery.yiigridview.js:310
I just can't figure out what to do.
EDIT
Ok after long struggle i somehow managed to get rid of the error, with the help of a fellow forum mate at Yii forum http://www.yiiframework.com/forum/index.php/topic/47904-error-with-cgridview-filter-property-error-code-has-no-method-querystring/page_view_findpost_p_224169.
Here is what i added.
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.ba-bbq.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.jquery.ajaxqueue.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.autocomplete.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.bgiframe.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.maskedinput.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.metadata.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.treeview.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.treeview.async.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.treeview.edit.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.yii.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.yiiactiveform.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/jquery.yiitab.js"></script>
<script src="<?php echo Yii::app()->assetManager->baseUrl; ?>/28e7347b/punycode.js"></script>
The error went away but the filter is still not working. The ajax load icon shows for less than a second and then nothing happens. I also see the correct search parameter being passed in the array.
Here is the array which i'm seeing being passed
Dropdown[category] Chant Books
Dropdown[price] $340 - $476
Products[brand]
Products[category]
Products[flavors]
Products[name] Owl Chant Scroll
Products[price_unit]
Products[providers]
Products[weight_unit]
Products_page 1
ajax products-grid
yt0
Upvotes: 2
Views: 4319
Reputation: 31
TypeError: $.param.querystring is not a function
[Break On This Error]
options.url = $.param.querystring(options.url, options.data);
In file jquery.yiigridview.js
I have also faced the same problem reported above and it is very easy to resolve. It usually happens when the jQuery you have included conflicts the default js added by jquery.yiigridview.js
.
Try simply removing the min.js that you have included, it will work absolutely fine.
Upvotes: 0
Reputation: 1
Refresh yii js files.In config:
'components'=>array(
'clientScript' => array(
'packages' => array(
'jquery' => array(
'baseUrl' => 'js',
'js' => array(
'jquery-1.10.2.js',
'jquery-migrate-1.2.1.min.js',
)
),
),
),
)
Upvotes: 0
Reputation: 39
From my experience, the reason for this error is jQuery conflict: there is one you load, and another one loaded by cgridview. The solution is to remove your jquery, or if you must have it - remove the Yii's one:
$cs=Yii::app()->clientScript;
$cs->scriptMap=array(
'jquery.js'=>false,
);
Upvotes: 2
Reputation: 518
Try this code
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'products-grid',
'dataProvider' => $model->customeSearch(), // add your method of search here
'filter' => $model, // for validation
'ajaxUrl'=> Yii::app()->request->getUrl(),
...
Upvotes: 1
Reputation: 602
Well at last the problem is solved. It turned out that i needed to add the ajaxUpdate and the ajaxURL property of the Gridview widget. And make another action for the ajax filter.
'ajaxUpdate' => 'products-grid',
'ajaxUrl' => Yii::app()->createUrl('products/UpdateGrid'),
Anyways here are the code, which works now.
the action methods in the products controller ::
public function actionDropdown() {
/*
* create the session to store the dropdown variables
*
*
*/
$this->session = new CHttpSession;
$this->session->open();
$dataProvider = new Products;
$products = new Products('search');
$products->unsetAttributes();
if (isset($_GET["Dropdown"])) {
$dropdownData = $_GET["Dropdown"];
$this->category = $dropdownData["category"];
$this->price = $dropdownData["price"];
$this->session["category"] = $this->category;
$this->session["price"] = $this->price;
}
if (isset($_GET["Products"])) {
$products->attributes = $_GET["Products"];
}
$this->render('selectproducts', array(
'dataProvider' => $dataProvider,
'products' => $products,
'category' => $this->category,
'price' => $this->price,
//'num' => $this->numResults,
));
}
public function actionUpdateGrid() {
$products = new Products;
$products->unsetAttributes();
if (isset($_GET["Products"])) {
$products->attributes = $_GET["Products"];
}
$this->renderPartial('_selectproducts', array(
'products' => $products,
'category' => $this->category,
'price' => $this->price,
));
}
The Product model code::
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* @return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search() {
// @todo Please modify the following code to remove attributes that should not be searched.
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('name', $this->name, true);
$criteria->compare('category', $this->category, true);
$criteria->compare('brand', $this->brand, true);
$criteria->compare('weight', $this->weight, true);
$criteria->compare('weight_unit', $this->weight_unit, true);
$criteria->compare('price', $this->price, true);
$criteria->compare('price_unit', $this->price_unit, true);
$criteria->compare('flavors', $this->flavors, true);
$criteria->compare('providers', $this->providers, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* @param string $className active record class name.
* @return Products the static model class
*/
public static function model($className = __CLASS__) {
return parent::model($className);
}
/*
* Dropdown search
*
*
*/
public function searchDropdown($category, $price) {
$this->priceText = explode(" - ", $price);
$this->criteria = new CDbCriteria;
$this->criteria->compare('category', $category, true);
$this->criteria->addBetweenCondition('price', substr($this->priceText[0], 1), substr($this->priceText[1], 1), 'AND');
return new CActiveDataProvider('Products', array(
'criteria' => $this->criteria,
'pagination' => array(
'pageSize' => 25,
),
'sort' => array(
'defaultOrder' => 'price_unit, name',
),
));
}
public function searchGrid() {
$session = new CHttpSession;
$session->open();
$category = $session["category"];
$this->criteria = new CDbCriteria;
$this->priceText = explode(" - ", $session["price"]);
$this->criteria->compare('category', $category, true);
$this->criteria->addBetweenCondition('price', substr($this->priceText[0], 1), substr($this->priceText[1], 1), 'AND');
/*
*
* compare the names to see if the flavor or weight is present
*
*/
$this->criteria->compare('name', $this->flavors, TRUE);
$this->criteria->compare('name', $this->weight, TRUE);
$this->criteria->compare('id', $this->id);
$this->criteria->compare('name', $this->name, true);
$this->criteria->compare('category', $this->category, true);
$this->criteria->compare('brand', $this->brand, true);
$this->criteria->compare('weight', $this->weight, true);
$this->criteria->compare('weight_unit', $this->weight_unit, true);
$this->criteria->compare('price', $this->price, true);
$this->criteria->compare('price_unit', $this->price_unit, true);
$this->criteria->compare('flavors', $this->flavors, true);
$this->criteria->compare('providers', $this->providers, true);
return new CActiveDataProvider($this, array(
'criteria' => $this->criteria,
'pagination' => array(
'pageSize' => 25,
),
'sort' => array(
'defaultOrder' => 'price_unit, name',
),
));
}
And the views::
view name::- selectproducts.php
<div id="shortcodes" class="page">
<div class="container">
<!-- Title Page -->
<div class="row">
<div class="span12">
<div class="title-page">
<h2 class="title">Available Products</h2>
</div>
</div>
</div>
<!-- End Title Page -->
<!-- Start Product Section -->
<div class="row">
<?php
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'products-grid',
'dataProvider' => $dataProvider->searchDropdown($category, $price),
'filter' => $products,
'ajaxUpdate' => 'products-grid',
'ajaxUrl' => Yii::app()->createUrl('products/UpdateGrid'),
'pager' => array(
'header' => '',
'cssFile' => false,
'maxButtonCount' => 25,
'selectedPageCssClass' => 'active',
'hiddenPageCssClass' => 'disabled',
'firstPageCssClass' => 'previous',
'lastPageCssClass' => 'next',
'firstPageLabel' => '<<',
'lastPageLabel' => '>>',
'prevPageLabel' => '<',
'nextPageLabel' => '>',
),
'columns' => array(
array(
'name' => 'name',
'value' => function($data) {
return '<div class="custom-badge">' . $data->name . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'category',
'value' => function($data) {
return '<div class="grid-glow">' . $data->category . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'brand',
'value' => function($data) {
return '<div class="grid-glow">' . $data->brand . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'weight_unit',
'value' => function($data) {
return '<div class="grid-glow">' . $data->weight_unit . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'price_unit',
'value' => function($data) {
return '<div class="grid-price-glow">' . $data->price_unit . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'flavors',
'value' => function($data) {
return '<div class="grid-glow">' . $data->flavors . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'providers',
'value' => function($data) {
return '<div class="provider-label label label-info"><a href="http://www.' . $data->providers . '">' . $data->providers . '</a></div>';
},
'type' => 'raw',
),
),
));
?>
</div>
<!-- End Product Section -->
</div>
view name::- _selectproducts.php
<?php
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'products-grid',
'dataProvider' => $products->searchGrid($category, $price),
'filter' => $products,
'ajaxUpdate' => TRUE,
'pager' => array(
'header' => '',
'cssFile' => false,
'maxButtonCount' => 25,
'selectedPageCssClass' => 'active',
'hiddenPageCssClass' => 'disabled',
'firstPageCssClass' => 'previous',
'lastPageCssClass' => 'next',
'firstPageLabel' => '<<',
'lastPageLabel' => '>>',
'prevPageLabel' => '<',
'nextPageLabel' => '>',
),
'columns' => array(
array(
'name' => 'name',
'value' => function($data) {
return '<div class="custom-badge">' . $data->name . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'category',
'value' => function($data) {
return '<div class="grid-glow">' . $data->category . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'brand',
'value' => function($data) {
return '<div class="grid-glow">' . $data->brand . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'weight_unit',
'value' => function($data) {
return '<div class="grid-glow">' . $data->weight_unit . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'price_unit',
'value' => function($data) {
return '<div class="grid-price-glow">' . $data->price_unit . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'flavors',
'value' => function($data) {
return '<div class="grid-glow">' . $data->flavors . '</div>';
},
'type' => 'raw',
),
array(
'name' => 'providers',
'value' => function($data) {
return '<div class="provider-label label label-info"><a href="http://www.' . $data->providers . '">' . $data->providers . '</a></div>';
},
'type' => 'raw',
),
),
));
?>
Well as you see the ajax filter needed a new action method which will render a partial view containing just the result grid. I hope it helps someone who is stuck with the same error.
Thanks, Maxx
Upvotes: 0
Reputation: 7265
The filter attribute is for validation, you need to provide a search function for attribute "dataprovider" of your grid
$this->widget('bootstrap.widgets.TbGridView', array(
'id' => 'products-grid',
'dataProvider' => $model->customeSearch(), // add your method of search here
'filter' => $model, // for validation
...
'columns' => array(
array(
'name' => 'someCol',
'value' => '$data->someCol',
'filter' => CHtml::dropdownList( ... ), // put an input here for your filter
),
),
Upvotes: 0