I’m using CGridView inside a form. It has selectable rows that are recorded in the database when the form is submitted. It works fine but we decided we needed to use the filtering capability of CGridView to limit the number of rows. I set the widget up to use the filter but it didn’t work.
After playing around with it I found that if the CGridView widget is NOT located inside the form then the filter works as expected. If it’s embedded in a form then the filter fields at the top are there, but they don’t do anything.
If anyone knows anything about why CGridView apparently doesn’t filter when it’s nested inside a form I’d sure like to know your experience. I assume it is a bug and will hopefully be fixed in Yii 2.0.
It would seem my only recourse is to code a custom form based filter and use the user’s input data to to construct the filtering criteria to pass to CActiveDataProvider.
The weird thing is all I have to do is comment out the two lines: "echo CHtml::beginForm();" and "echo CHtml::endForm();" and then the filter works fine!
public function actionAssign($id)
{
if (isset($_POST['RemoveButton']))
{
if (isset($_POST['selectedIds']))
{
foreach ($_POST['selectedIds'] as $delid)
{
$both = explode(",", $delid);
Xref::model()->deleteAll("callgroupId=$both[1] and calleeId=$both[0]");
}
}
}
if (isset($_POST['AddButton']))
{
if (isset($_POST['selectedIds']))
{
foreach ($_POST['selectedIds'] as $addid)
{
if (isset($_POST['cgid'])) {
$xref = new Xref;
$xref->calleeId = $addid;
$xref->callgroupId = $_POST['cgid'];
$xref->save();
}
}
}
}
$modelc=new Callee('search');
$modelc->unsetAttributes(); // clear any default values
if(isset($_GET['Callee'])) $modelc->attributes=$_GET['Callee'];
$this->render('assign',array(
'modelc'=>$modelc,
'model'=>$this->loadModel($id),
));
}
What it does is allow the user to assign (or de-assign) Callees to Callgroups. They can check the boxes individually or they can select the “all” checkbox at the top of the grid which automatically checks all the rows. There is a many-to-many relationship between the Callee model and the Callgroup model which is resolved with the Xref model Everything works beautifully, except when I add the filter. I tried replacing the CHtml stuff with standard <form> </form> and <input type=“submit”…> tags. It worked as before - it applied the assignments correctly but filtering didn’t respond. But if I just remove all the form tags the filter works!
The cause of the problem is that when you hit enter key in a filter field of the CGridView, then the form get an implicit submisstion.
Just for testing purpose, use tab key instead of enter key in a filter field, then the grid view will be correctly updated without a submission of the form.
Probably you can suppress the implicit submission of the form by replacing the "submit" type inputs to "button" type ones. That means, using CHtml::button() instead of CHtml::submitButton().
Softark thank you so much! You got it exactly right. So there is not a bug in Cgridview, it’s just that by default a form gets submitted when you press enter inside a form field. I hadn’t realized that the filter field is treated like any other form field in that respect.
After looking around a little I found some javascript that disables the "enter causes submit" aspect of a form:
So now the user can press "enter" after typing in filter criteria and the filtered result will be displayed, and they must actually click on "Assign" to process the assignment.
Thanks again Softark. You are a rock star in my book!