Order grid after ajax update causes action to complete again

Hi,

I have an actionGo which is called by an ajaxLink (this action downlaods and imports some locations which takes about 20s):




public function actionGo()

	{

 

  $model=new LocationsImport;

  $model->init();

  $msg = "Failure";

  

  // Peform import

  $model->go();

  

  if($model->completion_state == 1)

  {

      $msg = "Success";

  }

  

  Yii::app()->user->setFlash('locationsImport',"Locations import ".$msg);

  

  // Output the patial view _grid which contains the

  // grid rendering for the locations import archive

  $this->renderPartial('_grid', array('dataprovider'=>$this->getLocationsImportData()));

  

}

After the action has completed and the _grid view is updated when i order by any of the columns it repeats the actionGo as well as reordering the rows. How can I stop the repeat of actionGo?

Thanks,

J

Anyone got any idea about this one?

Still can’t seem to solve this one, any help would be appreciated.

Thanks,

Julian

Please post your view code. Is the ajaxLink embedded in the grid or external?

Matt

The original ajax button (see below) is external

The main view code




// The Ajax link which start the locations import

// and updates the grid view when finished


echo CHtml::ajaxButton('Import Locations',array('go'),array(

    'context'=>'js:this',

    'success'     => 'js:function(data)

                          {

                          $("#locations_import_archive").html(data);

                          $(this).removeAttr("disabled");

                          }',

    'beforeSend'  => 'js:function()

                          {

                          $(this).attr("disabled","disabled");

                          }',

    )

);


?>


<?php


$this->renderPartial('_grid', array('dataprovider'=>$this->getLocationsImportData()), false, true);




And the _grid view




    $this->widget('zii.widgets.grid.CGridView', array(

   'dataProvider'=>$dataprovider,

   'id' => 'locations_import_archive'

  ));



Hi,

I’ve tried your code and all seems ok. 2 issues though.

[list=1]

[*]the $(this).removeAttr(“disabled”); should be called from complete, not success, in case there’s an error - the button will be locked.

[*]your $("#locations_import_archive").html(data); is replacing the grid, right? Shouldn’t it recplace a content div?

[/list]

My code used:

View




<?php

// The Ajax link which start the locations import

// and updates the grid view when finished


echo CHtml::ajaxButton('Import Locations', array('go'), array(

    'context' => 'js:this',

    'success' => 'js:function(data)

    {

        $("#qwerty").html(data);

    }',

    'beforeSend' => 'js:function()

    {

        $(this).attr("disabled","disabled");

    }',

    'complete' => 'js:function()

    {

        $(this).removeAttr("disabled");

    }',

    )

);


?>


<div id="qwerty"></div>

<?php

$this->renderPartial('_grid', array('dataprovider' => $model->search()));

?>



_grid partial view:




<?php

$this->widget('zii.widgets.grid.CGridView', array(

   'dataProvider'=>$dataprovider,

   'id' => 'locations_import_archive'

  ));

  ?>

controller:




public function actionGo()

    {

        sleep(5);

        

        echo 'xxxxxxxxxxxx';

        exit;

    }



If you mouseOver the grid’s sorting columns what url does it point to? My only idea is that the JS is being replaced after update. A couple of things to try. Specify a div to update after the Ajax returns, remove “false, true” from the render partial - I don’t think you need it since it’s being called within a full view.

Let me know how it goes.

Matt

Hi Matt,

Unfortunately these changes havent affected it.

When I mouse over the column headers I get url like:

http://localhost/Website/site/public/index.php/locationsImport/go?_=1316257174103&LocationsImport_sort=start_time

and looking in firebug the ajax url is:

http://localhost/Website/site/public/index.php/locationsImport/go?_=1316257174103

so it seems it is just appending the sort value to the end of the ajax url and using that.

J

Why are you renderingPartial in the controller and the view? You should just call it in the view, no? I think by calling renderPartial again through Ajax the URL is being changed. Try removing it.




public function actionGo()

        {

 

  $model=new LocationsImport;

  $model->init();

  $msg = "Failure";

  

  // Peform import

  $model->go();

  

  if($model->completion_state == 1)

  {

      $msg = "Success";

  }

  

  Yii::app()->user->setFlash('locationsImport',"Locations import ".$msg);

  

  // Output the patial view _grid which contains the

  // grid rendering for the locations import archive

  $this->renderPartial('_grid', array('dataprovider'=>$this->getLocationsImportData()));

  

}






// The Ajax link which start the locations import

// and updates the grid view when finished


echo CHtml::ajaxButton('Import Locations',array('go'),array(

    'context'=>'js:this',

    'success'     => 'js:function(data)

                          {

                          $("#locations_import_archive").html(data);

                          $(this).removeAttr("disabled");

                          }',

    'beforeSend'  => 'js:function()

                          {

                          $(this).attr("disabled","disabled");

                          }',

    )

);


?>


<?php


$this->renderPartial('_grid', array('dataprovider'=>$this->getLocationsImportData()), false, true);



Hi,

The render partial in the view displays the grid on page load and the render partial in the ajax action is needed as the return html which updates the page.

So taking it out of the action means nothing is returned.

J

You can update the grid by calling the JS function $.fn.yiiGridView.update(‘grid-id’); in the ajaxButton’s complete/success parameter. Your ajaxButton should just return the message/flashdata - no need to call renderPartial again. I think that is where the problem lies.

Here’s some code of mine that updates the grid beforeSend - you need success/compplete.




echo CHtml::ajaxLink('Notify All Users', Yii::app()->createUrl('/admin/project/notifyAllUsers', array('projectId' => $projectId)), array(

    'type' => 'POST',

    'beforeSend' => 'function(jqXHR, settings){

            $.fn.yiiGridView.update("notify-grid");

        }',

    'success' => 'function(data, textStatus, jqXHR){

            // Hide all the notification panels.

            $("div.flash-success").hide();

            $("div.flash-notice").hide();

            $("div.flash-error").hide();

            

            var json = jQuery.parseJSON(data);   

            switch(json.status)

            {

                case "success": 

                    $("div.flash-success").html(json.message);

                    $("div.flash-success").show();

                    break;

                case "notice": 

                    $("div.flash-notice").html(json.message);

                    $("div.flash-notice").show();

                    break;

                case "error": 

                    $("div.flash-error").html(json.message);

                    $("div.flash-error").show();

                    break;

            }

            

        }',

    'error' => 'function(jqXHR, textStatus, errorThrown){

            // Hide all the notification panels.

            $("div.flash-success").hide();

            $("div.flash-notice").hide();

            $("div.flash-error").hide();

            

            $("div.flash-error").html("Sorry, something went wrong. The " + 

                "error returned from the server was: " + errorThrown);

            $("div.flash-error").show();

        }',

    ), array(

        'confirm' => "Are you sure you want to send a notification email to all users?",

        'id' => 'notifyAllUsersLink',

));



Hi Matt,

Yes! that worked and is much neater code.

Thanks for all the help.

J