Cgridview Not Fully Functional Within Ajax'd Div

I’m working with a site that works as follows:

There are a few dropdowns that basically fill in blanks for a mysql query. When the ‘search’ button is pressed, the database is queried, it returns an array, I turn it into a CArrayDataProvider and then ajax a CGridView into a div below the dropdowns. Here’s some code to give you a picture:




//Products.php

<?php

$form=$this->beginWidget(

    'CActiveForm',

    Array(

        'id'=>"products-form",

        'enableAjaxValidation'=>false

    )

);


echo CHtml::dropDownList(

    'make',

    $productModel->make,

    $productModel->makes

);


echo CHtml::dropDownList(

    'model',

    $productModel->model,

    $productModel->models

);


echo CHtml::dropDownList(

    'year',

    $productModel->year,

    $productModel->years

);

?>

<div class='search_button' onclick="ajaxResults();">

<?php $this->endWidget(); ?>


<div id="results-ajax"></div>






//Results.php


$dataProvider = new CArrayDataProvider(

    $resultArray,

    array(

	'keyField'=>false,

	'id'=>'parts',

	'pagination'=>false

    )

);


$columns = Array(...);


$this->widget(

    'zii.widgets.grid.CGridView',

    array(

	'id' => 'results_grid',

        'dataProvider'=>$dataProvider,

        'selectableRows'=>1,

        'selectionChanged'=> "doSomething();",

        'columns' => $columns,

	'summaryText' => ''

    )

);




The problem I’m encountering is that, while the CGridView displays, it doesn’t have any of the javascript-style selectable rows, which I need to be able to use to get further information.

Can someone help me figure this out?

Thanks,

Max

Can you post the controller code that processes the ajaxResults() request, please?

This is because in the Controller you are using the renderpartial i think so…

so u have to enable the two Properties like

$this->renderpartial(‘viewname’,array(‘model’=>$model),false,true);

I am Sure know the Styles will certainly work

Thanks for the replies guys. I had done that in the controller, and part of the CGridView works, i.e. I can hover over a row and it flickers, but I’m still not able to select a row.




$this->renderPartial(

    'results',

     array(

         'model' => $model,

     ),

     false,

     true

);



Hi

Here are my thoughts. When your view first loads, the div where the gridview should be is blank - no gridview. The gridview is usually loaded when the page is first rendered with $this->render(‘viewname’, array(‘model’=>$model)). That way, the scripts it requires to function get loaded at that point.

After it is on the page,


echo $this->renderPartial('viewname', array('model'=>$model), true, false); 

can be used for ajax responses. The renderPartial code you posted has the last parameter set to true. The last parameter is the processOutput parameter and when set to true, it processes scripts. Therefore, each time your view makes an ajax request, any scripts/scriptfiles required by that view will be rendered and you end up with the dreaded duplicate scripts problem. Could that be why it’s flickering?

Here’s an untested suggestion:

[list=1]

[*]Have a hidden div in your view with the default value of 0;

[*]When making an ajax request, grab that value and send it along with your form to your controller action.

[*]Your controller action should check the value of that parameter, if it is 0, then it could use renderPartial(‘viewname’, …,true,true)//process scripts

[*]if the value is 1 then use renderPartial(‘viewname’,…,true, false)//don’t process scripts

[*]After a successful ajax request, change the value of that div from 0 to 1.

[/list]

You could also have a go at adapting this workaround to solve your problem. Also read the comments on that wiki.

I think it has something to do with the fact that the event handler is not attaching to the CGridView because it doesn’t exist when the page is loaded. If I add an identical CGridView to content that is loaded without ajax and hide it, the ajax one appears to work. The only problem is that then I have two CGridViews with the same id, and the selectionChanged() function doesn’t work.

I hope this helps, I’m getting very frustrated.

Max

Oops, didn’t see your post. Let me try that out.

Ok, I’ve done some picking around. When I set processOutput to true, it tries to load the following scripts:




<link rel="stylesheet" type="text/css" href="styles.css">

<script type="text/javascript" src="/assets/424b4522/jquery.js"></script>

<script type="text/javascript" src="/assets/424b4522/jquery.ba-bbq.js"></script>



The problem is, styles.css loads but jquery.ba-bbq.js doesn’t. I tried loading it manually, but again, I don’t think the DOM event handler gets attached if there’s nothing to attach to initially.

To Raven: I the GridView doesn’t appear before I ajax it, and so the scripts should only load once the first time it ajaxes. Your solution will prove useful once I get it to work for the first time, but I don’t see it being true right now. Just to make sure, I set processOutput to false and loaded only styles.css and jquery.ba-bbq.js with no results. The ‘flickering’ was probably the wrong language to use; I meant that on hover, rows would change color, meaning the css was loaded on ajax.

Looking at the CGridView source code, it needs the ‘bbq’,‘yiigridview’ and ‘jquery’ scriptfiles. If enableHistory is set to true, then it also needs the ‘history’ scriptfile.

render() loads the whole page - scripts, cssfiles and layout. What renderPartial loads depends on the options set. renderpartial is designed to render partial views without the layout e.g. like the ‘_form’ or ‘_search’ views.