Yii - jQuery.fn.yiiGridView throwing undefined err

2019-09-17 09:44发布

问题:

In my view I have the following widget:

$this->widget('bootstrap.widgets.TbGridView', array(
    'dataProvider' => $model->search(),
    'filter' => $model,
    'ajaxUpdate' => true,
    'afterAjaxUpdate' => "updateChild",
     /* When a user makes a selection, my js function 'updateChild' updates the
        drill-down view with the details of the selection */
    'selectionChanged' => "updateChild",
    'columns' => array(
    'firstName', 'lastName'
    )
));

It is an extension of CGridView in Yii, but given the Bootstrap look.

The dataProvider gives a list to populate the grid (the table in question contains details about people). As part of the page, a new person can be created. On this happening (and also on deletion), it is my intent to update the GridView with the new entry. This AJAX event is triggered when the user presses 'submit':

    //prevent the form from submitting in the traditional manner
    e.preventDefault();
    var jqxhr = $.ajax( {
        type: 'POST',
        url: 'person/create',
        data: { Person: $('#person-form').serialize() },
    })
    .done(function(data) {
        // Update the drill-down view with the newly submitted details
        $('#updateData').html(data);
        // Attempt to update the gridView by ID - throwing error
        jQuery.fn.yiiGridView.update('yw0');
        //alert( 'success' );
    })
    .fail(function() {
       // alert( 'error' );
    })

It sends an AJAX POST request to the relevant controller method, and inserts the data from the form. On done, the drill-down view will be updated with the details of the newly created entry. Then - and this is the problematic line - the update() method for yiiGridView is called with the id of my GridView passed in as the parameter. It throws the error:

Uncaught TypeError: Cannot read property 'update' of undefined

What further muddies the waters is that I have tried the same line of code within 'updateChild' the js function that is called on a selection change on my GridView (see the code), and it works perfectly fine. My suspicion is that it works fine in that function because it is aware of the context in which it is being performed. However, I need this to work in the separate function I defined above.

Does anybody have any idea what's going on here? Thanks.

Edit: In response to Jagsler's comment (code is a bit of a mess, it will be cleaned up before deployment):

public function actionCreate() {
    $model = new Person;

    // When form submit button is pressed
    if (isset($_POST['Person'])) {
        $params = array(); 
        parse_str($_POST['Person'], $params); // Parsing JSON object back to PHP array
        $model->attributes = $params['Person']; // Massive assignment to model from JSON parsed array
        if ($model->validate()) {
            $command = Yii::app()->db->createCommand();
            $command->insert('person', // $model->save() didn't work, threw that memory leak error we saw before
                array( 'Title' => $model->Title // So we had to resort to the good old fashioned way
                     , 'firstName' => $model->firstName
                     , 'middleName' => $model->middleName
                     , 'lastName' => $model->lastName
                     , 'DOB' => $model->DOB
                     , 'Address1' => $model->Address1
                     , 'Address2' => $model->Address2
                     , 'Address3' => $model->Address3
                     , 'City' => $model->City
                     , 'ZIP' => $model->ZIP
                     , 'State' => $model->State
                     , 'Occupation' => $model->Occupation
                     , 'homePhone' => $model->homePhone
                     , 'cellPhone' => $model->cellPhone
                     , 'workPhone' => $model->workPhone
                     , 'homeEmail' => $model->homeEmail
                     , 'workEmail' => $model->workEmail
                     , 'memberStatus' => $model->memberStatus
                     , 'dateJoined' => $model->dateJoined
                     , 'Gender' => $model->Gender
                     , 'maritalStatus' => $model->maritalStatus
                     , 'Notes' => $model->Notes
                     , 'Active' => $model->Active,));
            /* To my knowledge, there's no decent way to get back a full 
             * Person model after inserting to DB, so I had to get the model
             * by selecting the row with the latest dateCreated stamp */
            $Details = Person::model()->findBySql("SELECT * FROM person "
                    . "ORDER BY dateCreated DESC "
                    . "LIMIT 1;");
            /* Why couldn't I just put through $model? Good question, all I 
             * know is that it didn't work */
            $contributions = array();
            $this->renderPartial('_viewAjax', array(
            'Details' => $Details,
            'contributions' => $contributions,
            'createSuccess' => true,
                ), false, true);
        } else {
            echo "failure";
        }
        die();
    }

    // Code for showing the entry form
    if (isset($_POST['create'])) {
        $model = new Person();
        $this->renderPartial('_form', array(
            'model' => $model
                ), false, true);
        die();
    }
}

回答1:

I think jquery is reloaded when you call the renderPartial in your actionCreate(). Try changing the parameters of the call to

$this->renderPartial('_form', array(...), false, false);

Or add the following code to _form to prevent jquery (and maybe other javascript files) from being reloaded.

<?php
if (Yii::app()->request->isAjaxRequest) {
    $cs = Yii::app()->clientScript;
    $cs->scriptMap['jquery.js'] = false;
    $cs->scriptMap['jquery.min.js'] = false;
}
?>

When jquery is reloaded it forgets everything it knew before. So the yiiListView doesn't exist anymore.



回答2:

Found this answer, and the solution worked for me:

Put this code into your main config file under "components":

'clientScript' => array(
        'scriptMap' => array(
            'jquery.js' => '/path/to/your/jquery/file.js',
        ),
    ),

And add this to the head of your main view file (view/layouts/main):

<?php Yii::app()->clientScript->registerCoreScript('jquery'); ?>

This solved the issue.