Adding A Class To Cgridview Buttons Causes Multiple Submissions

Hi

I have these two CGridView buttons:




'button1' => array(

	'label'=> $parent_model->myModelDescSingular . "'s " . $child_model->myModelDescPlural,

	'icon' => false,

	'imageUrl'=>Yii::app()->baseUrl.'/images/css/gridview/children.png',

	

	'url'=>'$this->grid->controller->createUrl("update", array(

		"parentID"=>$data->primaryKey,

	))',

	

	'click'=>"function(){

		

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

		

		$.fn.yiiGridView.update('child-grid', {

			type:'POST',

			url:$(this).attr('href'),

			success:function(response) {

				$('#child1Div').html(response);

				fnc_maincode_child1div_in();

				fnc_maincode_mainloading_out();

				return false;

			},

			error:function(response){

				return false;

			}

		})

		return false;

	}",

),




'button2' => array(

	'label'=> $parent_model->myModelDescSingular . "'s " . $child_model->myModelDescPlural,

	'icon' => false,

	'imageUrl'=>Yii::app()->baseUrl.'/images/css/gridview/children.png',

	

	'url'=>'$this->grid->controller->createUrl("childgrid", array(

		"parentID"=>$data->primaryKey,

	))',

	

	'click'=>"function(){

		

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

		

		$.fn.yiiGridView.update('child-grid', {

			type:'POST',

			url:$(this).attr('href'),

			success:function(response) {

				$('#child1Div').html(response);

				fnc_maincode_child1div_in();

				fnc_maincode_mainloading_out();

			},

			error:function(response){

				fnc_maincode_mainloading_out();

			}

		})

		return false;

	}",

),



The generated code was working fine, with each button having a unique identifier ([color="#0000FF"]a.button1[/color] and [color="#0000FF"]a.button2[/color]):




$(document).on('click','#parent-grid a.button1',function(){

	$.fn.yiiGridView.update('child-grid', {

		type:'POST',

		url:$(this).attr('href'),

		success:function(response) {

			$('#child1Div').html(response);

		},

		error:function(response){

			fnc_maincode_mainloading_out();

		}

	})

	return false;

});

$(document).on('click','#parent-grid a.button2',function(){

	$.fn.yiiGridView.update('child-grid', {

		type:'POST',

		url:$(this).attr('href'),

		success:function(response) {

			$('#child1Div').html(response);

		},

		error:function(response){

			fnc_maincode_mainloading_out();

		}

	})

	return false;

});



I added ‘class_foo’ to each button (used by jquery event delegation for further window-dressing):




'button1' => array(

	'label'=> $parent_model->myModelDescSingular . "'s " . $child_model->myModelDescPlural,

	'icon' => false,

	'imageUrl'=>Yii::app()->baseUrl.'/images/css/gridview/children.png',

	

	'url'=>'$this->grid->controller->createUrl("update", array(

		"parentID"=>$data->primaryKey,

	))',

	

	'options' => array(

		'class'=> 'class_foo',

	),

	

	'click'=>"function(){

		

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

		

		$.fn.yiiGridView.update('child-grid', {

			type:'POST',

			url:$(this).attr('href'),

			success:function(response) {

				$('#child1Div').html(response);

				fnc_maincode_child1div_in();

				fnc_maincode_mainloading_out();

				return false;

			},

			error:function(response){

				return false;

			}

		})

		return false;

	}",

),




'button2' => array(

	'label'=> $parent_model->myModelDescSingular . "'s " . $child_model->myModelDescPlural,

	'icon' => false,

	'imageUrl'=>Yii::app()->baseUrl.'/images/css/gridview/children.png',

	

	'url'=>'$this->grid->controller->createUrl("childgrid", array(

		"parentID"=>$data->primaryKey,

	))',

	

	'options' => array(

		'class'=> 'class_foo',

	),

	

	'click'=>"function(){

		

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

		

		$.fn.yiiGridView.update('child-grid', {

			type:'POST',

			url:$(this).attr('href'),

			success:function(response) {

				$('#child1Div').html(response);

				fnc_maincode_child1div_in();

				fnc_maincode_mainloading_out();

			},

			error:function(response){

				fnc_maincode_mainloading_out();

			}

		})

		return false;

	}",

),



However, now the generated code uses the same identifier ([color="#0000FF"]a.class_foo[/color]) for both buttons:




$(document).on('click','#parent-grid a.class_foo',function(){

	$.fn.yiiGridView.update('child-grid', {

		type:'POST',

		url:$(this).attr('href'),

		success:function(response) {

			$('#child1Div').html(response);

		},

		error:function(response){

			fnc_maincode_mainloading_out();

		}

	})

	return false;

});

$(document).on('click','#parent-grid a.class_foo',function(){

	$.fn.yiiGridView.update('child-grid', {

		type:'POST',

		url:$(this).attr('href'),

		success:function(response) {

			$('#child1Div').html(response);

		},

		error:function(response){

			fnc_maincode_mainloading_out();

		}

	})

	return false;

});



This causes both of the generated events to fire when only one of the buttons are clicked. The more buttons you have, the more submissions.

Can we add an ‘id’ to each button to keep their identifiers unique?

Thanx

Hi Gerhard,

Try to put an unique id for each button:




'options'=>array('class'=>'class_foo','id'=>'button1_id'),



Hi Menxaca

No it does not help. The generated code still uses the class as identifier.

Then maybe… you will need to put the js script outside of click property, directly like:




<script>

$(document).on('click','#[the unique id]',function(){

        $.fn.yiiGridView.update('child-grid', {

                type:'POST',

                url:$(this).attr('href'),

                success:function(response) {

                        $('#child1Div').html(response);

                },

                error:function(response){

                        fnc_maincode_mainloading_out();

                }

        })

        return false;

});

</script>



Menxaca, i think that is a good idea.

So you make the button as stupid as possible and then create your own identifiers and ‘click’ code in a separate js function. You can use ‘event delegation’ - like in your example - or you could even call your js function with the button’s own click event.

It is maybe more work (the first time), but then you have full control.

Thanx.

You can always set a unique class for each button like

[size="2"]




        'options' => array(

                'class'=> 'class_foo btn1',

        ),



[size="2"]for button1 and[/size]




        'options' => array(

                'class'=> 'class_foo btn2',

        ),

for button2[/size]

Hi Maurizio

Yes, absolutely, unique classes work fine.

But often you want to give multiple buttons or links the same class e.g. I use jquery to make all my buttons and links ‘inactive’ if one of them is clicked (while waiting for the response).

Maurizio

I went back and tested your example.

Works perfectly:

  • The code generated has unique button identifiers e.g. a.class_foo.btn1, a.class_foo.btn2.

  • And you can still target all buttons and links with jquery by just using ‘class_foo’.

Many thanx

I think you did not get what I wrote above… check the example, both buttons has the same class “class_foo” but in addition each has a unique class. For your needs you can still access those buttons with $(’.class_foo’)

Lol, we posted at the same time… but you where few seconds faster :D

Thanks a lot. I’m slowly getting there :D