Gridview Not Working In Cjuidialog On Reopen

Hi guys

I have a CJuiDialog containing a Gridview that opens fine and works perfectly. I can paginate, filter and all that kind of stuff. However when I click the close button in the dialog title bar and then reopen the dialog, the pagination stops working and invariably firefox crashes so I can’t see the error in the console. :frowning: I’ve tried all sorts of things such as turning on and off various scriptmaps, setting the processOutput boolean in renderPartial to true/false. The only thing that works reliably is refreshing the page on clicking the close button. This is not ideal as the user may have already filled in some other fields.

So basically I have my view which preloads a CJuiDialog. On clicking the ajaxbutton, the actionShowCourseList is called in the controller and the partial page ‘_courseList’ is rendered in the dialog. It all works fine until I close and then reopen the dialog.

Here is my code. I’ve stripped out all the boilerplate and unnecessary stuff to save space so I hope it makes sense.





<?php $form = $this->beginWidget('CActiveForm', array(

    'id' => 'course-period-form',

)); ?>

        /*

         * Form elements here which I've stripped out the form elements here to save space. They are populated from the dialog

        */

        ......


        <?php


              // Button to call dialog


              echo CHtml::ajaxButton('Select Course', $this->createUrl('/course/showCourseList',

                            array(

                                'course' => $model->isNewRecord ? null : $model->id

                            )),

                        array(

                            "success" => 'function(data){

                               $("#dialog").dialog("option", "title", "Add Course");

                               $("#dialog").html(data).dialog("open");

                               return false;

                           }',

                   ),

                  );

                    ?>

                </div>

            </div>

        </fieldset>

    </div>

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


<!-- CJuiDialog -->


<?php $this->Widget('zii.widgets.jui.CJuiDialog', array(

    'id' => 'dialog',

    'options' => array(

        'title' => 'Show data',

        'show' => 'fade',

        'autoOpen' => false,

        'modal' => true,

        'width' => '80%',

        'height' => 'auto',

        // This is how I'm getting the dialog to work again on reopening

        'close' => 'js:function(event, ui) { location.reload(); }'

    ),

));







// The partial page ('_courseList') to be rendered in the dialog


Yii::app()->clientScript->scriptMap = array(

    //scripts that we don't need inside this view

    'jquery.js' => false,

    'jquery.min.js' => false,

    'jquery.maskedinput.min.js' => false,

    'jquery-ui.min.js' => false,

);


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

    'id' => 'course-grid',

    'dataProvider' => $courses->search(),

    'type' => 'striped bordered condensed',

    'filter' => $courses,

    'columns' => array(

        array(

            'header' => 'ID',

            'name' => 'course_id',

            'htmlOptions' => array('width' => '40px'),

        ),

        array(

            'header' => 'Course Name',

            'name' => 'course_name',

        ),

        .... and so on

?>







// The action to show the dialog


public function actionShowCourseList()

    {

        $courses = new Course('search');

        $courses->unsetAttributes();

        if (isset($_GET['Course'])) {

            $courses->attributes = $_GET['Course'];

        }

        $this->renderPartial('/course/_courseList',

            array('courses' => $courses),

            false, false);


        Yii::app()->end();

    }



Any ideas would be greatly appreciated!

Actually even my shoddy idea of refreshing the page doesn’t cut it either. Part of the functionality of this dialog is that if a course is not available in the list, the user can add a new one by clicking ‘Create new course’. This opens a new form in the dialog. On creating the course, the user is brought back to the previous screen with the Gridview in the same dialog and we are back to square one again where any JS related actions in the gridview crashes the browers.

Is there some way of reinitializing CJuiDialog without refreshing the page?

Just an update…

I played around with it today and found out that it works if the id of the gridview is changed on reopening.

What I did was:

  • Open the dialog with the gridview in it

  • Close the dialog

  • Change the id of the gridview in the source code

  • Open the gridview without refreshing

  • Everything works! Pagination etc :slight_smile:

I can’t however just set the id to a unique id as obviously the gridview won’t be able to do pagination and filtering if the id is changed on each call.

So it seems that the gridview is bound somehow but I just can’t figure it out. There must be a way of cleaning up after you have close the dialog. I’ve tried messing around with .unbind() on lots of different selectors but it didn’t work.

Anyone out there with a clue of how to tidy up after closing a dialog, which can be opened again? :frowning:

In the end my fix was to apply a unique id to the gridview. To deal with pagination and filtering requests, I basically check if $_GET[‘ajax’] is set. If it is, I run it through some validation to check for naughtiness and then assign the id back to the grid again. Otherwise the grid gets a unique ID. This works great and I can now open and close the dialog and use the gridview as normal without refreshing the page.

This all feels a bit dirty to me though and I’m probably introducing memory leaks if the previous gridviews are still hanging around. In the end, when the user chooses a course, there is a redirect so it’ll all be flushed out eventually.

I am still looking for a more elegant solution if anybody in the know is out there! :slight_smile: