Strang Situation In Using Cgridview

Very strange situation when using CGridView.

In one page I have a <div> section where I loading in ajax CGridView. When I select a row in the first CGridView it opens another CGridView in the same <div> section, and then via the link I can return back to open the first CGridView again. When several time I open the first CGridView (like selecting a row to open another CGridView and going back to the first CGridView) and then if I click the Delete icon of the CButtonColumn it shows delete confirmation as much times as I opened those CGridViews.

In the debug I can see that I do not double loading .js libraries.

What is the problem, and how can I resolve this problem?

[size=2]Could you please share your code here and explain a bit more.Since its a bit difficult for me to understand your comment here. [/size]:)

First of all Thanks for the reply.

I will try to explain the problem with code snippets.

This the first CGridView:


<?

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

	'id'=>'device-grid',

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

	'filter'=>null,

	'selectableRows'=>1,

	'columns'=>array(

		array(

	        'header'=>'#',

	        'value'=>'$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',

			'htmlOptions'=>array('style'=>'text-align:center'),

		),

		'name',

		'ip_address',

		'type',

		array(

			'class'=>'CButtonColumn',

			'buttons'=>array(

			  'delete'=>

				array(

					'url'=>'Yii::app()->createUrl("site/deleteDevice", array("id"=>$data->id))',

					'options'=>array( 

						'id'=>'deleteDevice',

					),

				),

			),

		),

	),

	'selectionChanged'=>'js:function(id){

		n = $.fn.yiiGridView.getSelection(id);

		if (n>0){

			$.ajax({

				url: "'.Yii::app()->urlManager->createUrl('site/showPorts').'",

				type: "GET",

				data: {"id": parseInt(n)},

				dataType: "html",

				success: function(data) {

						$(".device").html(data);

					}

			})

		}

	}',

)); 

?>

This is the action for this first CGridView:


	public function actionShowDevices($l_id)

	{

		$model=new Device();

		$model->location_id=$l_id;

		

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

                    'jquery.js'=>false,

                    'jquery.ba-bbq.js'=>false,

                    'jquery.yiigridview.js'=>false,

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

                ); 


		$this->renderPartial('/device/_viewbysite',array('model'=>$model,), false, true);

	}



This is the second CGridView:


<?php echo CHtml::ajaxLink($model->portLocation, array('site/showDevices', 'l_id'=>$model->device->location_id,), array('update'=>'.device'), array('id'=>'showDevices','live'=>false)).'->'.$model->deviceName?>


<?php 

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

	'id'=>'port-grid',

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

	'template'=>'{pager}{items}{pager}',

	'filter'=>null,

	'columns'=>array(

		array(

	        'header'=>'#',

	        'value'=>'$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',

			'htmlOptions'=>array('style'=>'text-align:center;width:15px'),

		),

		'subscriber',

		'subscriber_network',

		'subscriber_ip',

		array(

			'class'=>'CButtonColumn',

		),

	),

	'selectableRows'=>1,

)); ?>



And this the action for the second CGridView:


	public function actionShowports($id)

	{

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

                    'jquery.js'=>false,

                    'jquery.ba-bbq.js'=>false,

                    'jquery.yiigridview.js'=>false,

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

                ); 

		$model=new Port();

		$model->device_id=$id;

		

		$this->renderPartial('/port/showports',array(

								'model'=>$model,

							), false, true);

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

	}



Now I will try to explain the problem again step by step in scenario: I open the first CGridView. And then by clicking any row I open in the same page the second CGridView. After that I return to the first CGridView by clicking:


<?php echo CHtml::ajaxLink($model->portLocation, array('site/showDevices', 'l_id'=>$model->device->location_id,), array('update'=>'.device'), array('id'=>'showDevices','live'=>false)).'->'.$model->deviceName?>

And then if I delete any row in the first CGridView by clicking delete button of the CButtonColumn the confirmation dialog pops up. And it pops up as much times as I opened CGridViews by that ajax links. If I traverse between CGridViews 5 times the confirmation dialog will show up 10 times and then the action occurs.

Hope I could explain this time my problem. Sorry for my bad English, if there is necessary additional information I will provide it.

Thanks in advance

Are you managing both that CgridView on the same page. ?? its seems you are doing some great stuff :)

Well i think there could be problem with your ajax link. its binding twice with click event.SO, lets try to check that Ajax link click event and check whats wrong there.

I really appreciate your help. I’m not so big expert, better say newbie, so I did not understand how to “check that Ajax link click event” and understand what is wrong and which Ajax link do you mean?

Ahh no prob man :)

Lets share complete code from your view file and please attach a screenshot for your page.How do you are performing this task.Then it would be nice to answer you in more details. :)

As the Screenshot I understood the message itself, right? So if I am not misunderstood here is the screenshots:

I traverse between CGridViews 3 or 4 times

The 4591

1.jpg
.

Concerning to your question about view code. Actually I use 3 view code for this explained scenario. Shell I post all of them? Because they are too long especially the first index.php, cause I put all other ajax dialog screens there. Without those dialogs index.php looks as follows:




<div class='tree'>

<?php echo $this->renderPartial('/treeMenu/_tree'); ?>

</div>




<div class='mainarea'>

	<div class='notloading'></div>

	<div class='device'>

<?php 

	

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

        'id'=>'fake-grid',

        'dataProvider'=>new CArrayDataProvider(array()),

        'columns'=>array(

        ),

		'emptyText'=>'',

		'selectableRows'=>1,

)); 

?>


	</div>

</div>




<br>


<script>

//$(function(){

 $('.tree').on('click', 'a.tree_ajax_link', function(e, data){

  e.preventDefault();

  var url=$(this).attr('href')+'&ajax=1';

//alert(url); 

  $('#ports').empty();

  $('.device').load(url);

 });

//});

</script>



One more thing from my observation - as I understood the delete confirmation dialog for CColumnButton’s Delete button linked to the class ‘delete’. Because if in debug mode I delete that class from the button no confirmation dialog opens and rows deletes. May be this will help somehow.

So You permitted :rolleyes: :

index.php




<?php

/* @var $this SiteController */


$this->pageTitle=Yii::app()->name;

?>





<?php

		//--------------------- View Dialog Form --------------------------

$this->beginWidget('zii.widgets.jui.CJuiDialog',array(

    'id'=>'deviceInfo',

    // additional javascript options for the dialog plugin

    'options'=>array(

        'title'=>'Информация об оборудовании',

        'autoOpen'=>false,

		'modal'=>false,

		'width'=>550,

        'height'=>470,

		'resizable'=>false,

		'buttons'=>array(

            'OK'=>'js:function(){$(this).dialog("close");}',

        ),

    ),

));

?>

<div id="id_view_device"></div>

<?$this->endWidget('zii.widgets.jui.CJuiDialog');?>

<?php		//--------------------- End of View Dialog Form -------------------------- ?>


<?php

		//--------------------- Edit Dialog Form --------------------------

$this->beginWidget('zii.widgets.jui.CJuiDialog',array(

    'id'=>'deviceUpdate',

    // additional javascript options for the dialog plugin

    'options'=>array(

        'title'=>'Информация об оборудовании',

        'autoOpen'=>false,

		'modal'=>false,

		'width'=>570,

        'height'=>560,

		'resizable'=>false,

		'buttons'=>array(

            //'OK'=>'js:function(){$(this).dialog("close");}',

        ),

    ),

));

?>

<div class="id_update_device"></div>

<?$this->endWidget('zii.widgets.jui.CJuiDialog');?>

<?php		//--------------------- End of Edit Dialog Form -------------------------- ?>







<?php

		//--------------------- View Dialog Form --------------------------

$this->beginWidget('zii.widgets.jui.CJuiDialog',array(

    'id'=>'portInfo',

    // additional javascript options for the dialog plugin

    'options'=>array(

        'title'=>'Информация порта',

        'autoOpen'=>false,

		'modal'=>false,

		'width'=>550,

        'height'=>470,

		'resizable'=>false,

		'buttons'=>array(

            'OK'=>'js:function(){$(this).dialog("close");}',

        ),

    ),

));

?>

<div id="id_view_port"></div>

<?$this->endWidget('zii.widgets.jui.CJuiDialog');?>

<?php		//--------------------- End of View Dialog Form -------------------------- ?>


<?php

		//--------------------- Edit Dialog Form --------------------------

$this->beginWidget('zii.widgets.jui.CJuiDialog',array(

    'id'=>'portUpdate',

    // additional javascript options for the dialog plugin

    'options'=>array(

        'title'=>'Информация порта',

        'autoOpen'=>false,

		'modal'=>false,

		'width'=>550,

        'height'=>470,

		'resizable'=>false,

		'buttons'=>array(

            //'OK'=>'js:function(){$(this).dialog("close");}',

        ),

    ),

));

?>

<div class="id_update"></div>

<?$this->endWidget('zii.widgets.jui.CJuiDialog');?>

<?php		//--------------------- End of Edit Dialog Form -------------------------- ?>








<div class='tree'>

<?php echo $this->renderPartial('/treeMenu/_tree'); ?>

</div>




<div class='mainarea'>

	<b>Список оборудований</b>

	<div class='notloading'></div>

	<div class='device'>

<?php 

	

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

        'id'=>'fake-grid',

        'dataProvider'=>new CArrayDataProvider(array()),

        'columns'=>array(

        ),

		'emptyText'=>'',

		'selectableRows'=>1,

)); 

?>


	</div>

	<div id='ports'>

	</div>

</div>




<br>


<script>

//$(function(){

 $('.tree').on('click', 'a.tree_ajax_link', function(e, data){

  e.preventDefault();

  var url=$(this).attr('href')+'&ajax=1';

//alert(url); 

  $('#ports').empty();

  $('.device').load(url);

 });

//});

</script>




<?php

$updateJSDevice = CHtml::ajax( array(

  'url' => "js:url",

  'data' => "js:form.serialize() + action",

  'type' => 'post',

  'dataType' => 'json',

  'success' => "function( data )

  {

    if( data.status == 'failure' )

    {

      $( '#deviceUpdate div.id_update_device' ).html( data.content );

      $( '#deviceUpdate div.id_update_device form input[type=submit]' )

        .die() // Stop from re-binding event handlers

        .live( 'click', function( e ){ // Send clicked button value

          e.preventDefault();

          deviceUpdate( false, $( this ).attr( 'name' ) );

      });

    }

    else

    {

      $( '#deviceUpdate div.id_update_device' ).html( data.content );

      if( data.status == 'success' ) // Update all grid views on success

      {

        $( 'div.grid-view' ).each( function(){ // Change the selector if you use different class or element

          $.fn.yiiGridView.update( $( this ).attr( 'id' ) );

        });

      }

      setTimeout( \"$( '#deviceUpdate' ).dialog( 'close' ).children( ':eq(0)' ).empty();\", 1000 );

    }

  }"

)); 

?>


<?php

Yii::app()->clientScript->registerScript( 'deviceUpdate', "

function deviceUpdate( url, act )

{

  var action = '';

  var form = $( '#deviceUpdate div.id_update_device form' );

  if( url == false )

  {

    action = '&action=' + act;

    url = form.attr( 'action' );

  }

  {$updateJSDevice}

}" ); 

?>


<?php

$updateJSPort = CHtml::ajax( array(

  'url' => "js:url",

  'data' => "js:form.serialize() + action",

  'type' => 'post',

  'dataType' => 'json',

  'success' => "function( data )

  {

    if( data.status == 'failure' )

    {

      $( '#portUpdate div.id_update' ).html( data.content );

      $( '#portUpdate div.id_update form input[type=submit]' )

        .die() // Stop from re-binding event handlers

        .live( 'click', function( e ){ // Send clicked button value

          e.preventDefault();

          portUpdate( false, $( this ).attr( 'name' ) );

      });

    }

    else

    {

      $( '#portUpdate div.id_update' ).html( data.content );

      if( data.status == 'success' ) // Update all grid views on success

      {

        $( 'div.grid-view' ).each( function(){ // Change the selector if you use different class or element

          $.fn.yiiGridView.update( $( this ).attr( 'id' ) );

        });

      }

      setTimeout( \"$( '#portUpdate' ).dialog( 'close' ).children( ':eq(0)' ).empty();\", 1000 );

    }

  }"

)); 

?>


<?php

Yii::app()->clientScript->registerScript( 'portUpdate', "

function portUpdate( url, act )

{

  var action = '';

  var form = $( '#portUpdate div.id_update form' );

  if( url == false )

  {

    action = '&action=' + act;

    url = form.attr( 'action' );

  }

  {$updateJSPort}

}" ); 

?>



_viewbysite.php


<?php 

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

	'id'=>'device-grid',

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

	'filter'=>null,

	'selectableRows'=>1,

	'columns'=>array(

		//'id',

		array(

	        'header'=>'#',

	        'value'=>'$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',

			'htmlOptions'=>array('style'=>'text-align:center'),

		),

		'name',

		'ip_address',

		'type',

		array(

			'name'=>'id',

			'type'=>'raw',

			'value'=>'CHtml::hiddenField("id",$data->id)',

			'htmlOptions'=>array('style'=>'display:none'),

			'headerHtmlOptions'=>array('style'=>'display:none'),

		),

		array(

			'class'=>'CButtonColumn',

			'deleteConfirmation'=>'При удаление оборудования, все связанные порты так же будут удалены. Вы действительно хотиде удалить оборудование?',

			//--------------------- begin added --------------------------

			

			'buttons'=>array(

			  'view'=>

				array(

					'url'=>'Yii::app()->createUrl("site/viewDevice", array("id"=>$data->id,"asDialog"=>true))',

					'options'=>array( 

						'id'=>'viewDevice',

						'ajax'=>array(

							'type'=>'POST',

								// ajax post will use 'url' specified above 

							'url'=>"js:$(this).attr('href')", 

							'update'=>'#id_view_device',

						),

					),

				),

			  'update'=>

				array(

					'url'=>'Yii::app()->createUrl("site/updateDevice", array("id"=>$data->id))',

					'options'=>array( 

						'id'=>'updateDevice',

					),

					'click' => "function( e ){

						e.preventDefault();

						$( '#deviceUpdate' ).children( ':eq(0)' ).empty(); // Stop auto POST

						deviceUpdate( $( this ).attr( 'href' ) );

						$( '#deviceUpdate' ).dialog( 'open' ); 

					}"

				),

			  'delete'=>

				array(

					'url'=>'Yii::app()->createUrl("site/deleteDevice", array("id"=>$data->id))',

					'options'=>array( 

						'id'=>'deleteDevice',

					),

				),

			),

			

			//--------------------- end added --------------------------

		),

	),

	'emptyText'=>'На этом узле нет никаких оборудований',


	'selectionChanged'=>'js:function(id){

		n = $.fn.yiiGridView.getSelection(id);

		if (n>0){

			//alert(n);

			$.ajax({

				url: "'.Yii::app()->urlManager->createUrl('site/showPorts').'",

				type: "GET",

				data: {"id": parseInt(n)},

				dataType: "html",

				success: function(data) {

						//$(".device").empty();

						$(".device").html(data);

					}

			})

		}

	}',


	

	'hideHeader'=>false,

)); 

?>


<?php 

	echo CHtml::ajaxLink('Добавить оборудование',array('site/createDevice', 'l_id'=>$model->location_id, ), array('update'=>'.device'), array('id'=>'addDevice', 'live'=>false));

?>



showports.php




<?php

/* @var $this PortController */

/* @var $model Port */


$this->breadcrumbs=array(

	'Ports'=>array('index'),

	'Manage',

);


?>




<!--<h1>Manage Ports</h1>-->

<?php echo CHtml::ajaxLink($model->portLocation, array('site/showDevices', 'l_id'=>$model->device->location_id,), array('update'=>'.device'), array('id'=>'showDevices','live'=>false)).'->'.$model->deviceName?>





<?php 

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

	'id'=>'port-grid',

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

	'template'=>'{pager}{items}{pager}',

	'filter'=>null,

	'columns'=>array(

		array(

	        'header'=>'#',

	        'value'=>'$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',

			'htmlOptions'=>array('style'=>'text-align:center;width:15px'),

		),

		array(

			'name'=>'index_number',

	        'header'=>'#',

			'htmlOptions'=>array('style'=>'text-align:center;width:15px'),

			'visible'=>$model->isComplexIndex(),

		),

		'subscriber',

		'subscriber_network',

		'subscriber_ip',

		array(

			'class'=>'CButtonColumn',

			//--------------------- begin added --------------------------

			

			'buttons'=>array(

			  'view'=>

				array(

					'url'=>'Yii::app()->createUrl("site/viewPort", array("id"=>$data->id, "asDialog"=>true, "index"=>$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)))',

					'options'=>array(  

						'id'=>'viewPort',

						'ajax'=>array(

							'type'=>'POST',

								// ajax post will use 'url' specified above 

							'url'=>"js:$(this).attr('href')", 

							'update'=>'#id_view_port',

						),

					),

				),

			  'update' => 

				array(

					'url'=>'Yii::app()->createUrl("site/updatePort", array("id"=>$data->id, "index"=>$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)))',

					'options'=>array(  

						'id'=>'updatePort'

					),

					'click' => "function( e ){

						e.preventDefault();

						$( '#portUpdate' ).children( ':eq(0)' ).empty(); // Stop auto POST

						portUpdate( $( this ).attr( 'href' ) );

						$( '#portUpdate' ).dialog( 'open' ); }",

				),

			  'delete' => 

				array(

					'visible'=> '0',

				),

			),

			//--------------------- end added --------------------------

		),

	),

	'selectableRows'=>1,

)); ?>


<?php 

	echo CHtml::ajaxLink('Добавить порты',array('site/addports', 'd_id'=>$model->device_id, ), array('beforeSend' => 'function(){$(".notloading").addClass("loading2");}', 'complete' => 'function(){$(".notloading").removeClass("loading2");}', 'update'=>'.device'), array('id'=>'addports'));

?>




Hi Bakhtiyor

I am still trying to get the delete button working with "event delegation". It works the first time, but after that the "paging" starts using the same url that the delete button used.

I will report back.

Regards

Gerhard

Hi Bakhtiyor

This is what I ended up doing - for now: CGridView in iframe in CJuiTabs

Regards

Gerhard

i think you may change the pass the random id on button link


 array('id'=>rand(0, 99999),'live'=>false))

i am not sure it’s work or not