Strange ajaxSubmitButton problem (Multiple Posts)

In short:

A form is displayed using an ajaxLink.

That form is then submitted with an ajaxSubmitButton.

The first submit works perfectly.

The second submit does 2 POST requests with the data. The 3rd one does 3 requests and so on.

If you refresh the page everything works normal again the first request.

More details:

The ajaxLink looks like this:


CHtml::ajaxLink('Create Category', array('create'), array('update' => '#details'), array('name' => 'bCreate'));

It calls an action that does a renderPartial on a template.

The contents of #details is then replaced by a form that is submitted using an ajaxSubmitButton:


CHtml::ajaxSubmitButton($model->isNewRecord ? 'Create' : 'Save', $model->isNewRecord ? Array('create') : Array('update', 'categoryId' => $model->categoryId), Array('update' => '#details'), Array('name' => 'bSubmit')

There is more code involved (for refreshing the resulting list etc), but the problem persists without all that. So I don’t think it’s relevant to the problem.

I get the impression that a list is kept of all the previous POST URLs on the client side or something. They are all called upon each next request. Anyone has any ideas on this? I’m getting pretty desperate…

Thanks in advance!

I was wondering: Is it possible that this is caused due to using "ajaxLink" and "ajaxSubmitButton" within content that is requested via Ajax? i.e.: Since the page does not reload, the jQuery object stays instantiated and all other .click handlers are added to the existing ones instead of replacing them?

If so, how would I proceed best to get around this?

I got the problem same like you before and here is my resolved:

First register yii and jQuery script depend on your application. After then register script that set cache for ajax is true. Add below code in your controller




	public function actions()

	{....		

                Yii::app()->getClientScript()->registerCoreScript('yii');

		Yii::app()->getClientScript()->registerCoreScript('jquery');

		Yii::app()->clientScript->registerScript('my_enable_default_caching_of_scripts',

    		'jQuery.ajaxSetup({\'cache\': true})');....



In each action that invoke by ajaxLink use scriptMap of Yii to prevent scripts that you dont want to reload




Yii::app()->clientScript->scriptMap['*.js'] = false;



Hi!

i’ve got the same situation.

@daonhack

Thank your for this solution.

Just for understanding (because I’m new on Yii):

The following code…


Yii::app()->clientScript->scriptMap['*.js'] = false;

…is an example.

On the action, which is loaded by an Ajax Request (for example "ControlerWithAjaxContent/viewForm"), I have to define every script, I found under Yii::app()->clientScript->getCoreScriptUrl() ??

(or which is loaded by getting the Ajax content -> capturing loaded files from the firebug network tab?)


Yii::app()->clientScript->scriptMap[jquery.js]=false

Yii::app()->clientScript->scriptMap[jquery.min.js]=false

Yii::app()->clientScript->scriptMap[jquery.treeview.async.js]=false

Yii::app()->clientScript->scriptMap[jquery.yiiactiveform.js]=false

[...14 more lines...]

Is this right?

On the other hand, I have to register every of this scripts at the "static" action/page (for Example "application/index")?

Something like this:


Yii::app()->getClientScript()->registerCoreScript('jquery.js');

Yii::app()->getClientScript()->registerCoreScript('jquery.min.js');

[...16 more lines...]

Is there am more consolidated way to register a set of Scripts - or to set them to false?

Thank you…

rall0r :slight_smile:

Hi,

me ones again.

I tried the following:

1.) register all the .js Files which are loaded during an Ajax Request (the Ajax request loads an Form into an div element)


Yii::app()->getClientScript()->registerCoreScript('jquery.yiiactiveform.js');

Yii::app()->getClientScript()->registerCoreScript('jquery-ui.min.js');

Yii::app()->getClientScript()->registerCoreScript('jquery-ui-i18n.min.js');

2.) at the Ajax action (which generates the Form) i set the same JS-Scripts to false:


Yii::app()->clientScript->scriptMap=array('jquery.js'=>false,

					'jquery.yiiactiveform.js'=>false,

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

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

					);

At the end the Form send the POST request multiple times. :frowning:

Are there any suggestions?

Thank you - rall0r

You are probably binding the same event on the ajax response

try to use renderPartial to render if its an ajax request

Hi Gustavo,

thank you for your replay, especially it seems to be early morning at your location! :wink:


try to use renderPartial to render if its an ajax request

“De facto” I’m using renderPartial right now.


 $this->renderPartial('_viewSet',array('model'=>$model),false,true);

So what is wrong with that renderPartial code?

Best regards,

rall0r

:) it was, i was just checking my email’s and forum msgs and saw your question

anyway, like i said you are probably binding again with some JS that you send in the ajax response

Hi,

Probably, but I don’t find an error!

On the main action (inbdex-action) I register the 1st and only Ajax script:


Yii::app()->clientScript->registerScript("loadSearchField",

                                                'jQuery.get("'.CController::createUrl('ajax/SearchSets').'",{},

                                                            function(data){jQuery("#searchField").html(data); <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/wink.gif' class='bbc_emoticon' alt=';)' />',

                                                  CClientScript::POS_END  );



This loads an minimum sarch form inside the div element "searchField". The searchFiled view is rendered with renderPartial($view,$data, false,true).

Part of the searchField view is an AjaxLink to open an extended version of the searchForm:


echo CHtml::ajaxLink("searchSet",$this->createUrl('ajax/SearchSets'),

                                      array('update' => '#searchSet',

                                             'complete' =>'function(data){ $("#searchSetDialog").dialog("open");

                                                                            return false;}' ));

The extended search form includes an ajaxSubmitButton to send the form-data to the Server,


CHtml::ajaxSubmitButton('Save_it'),

                                 array('success'=>'function(data){ $("#searchSetDialog").dialog("close");

                                                    return false;}'),

                                  array('name'=>'save'));

Until that point everything works fine.

If I open the searchSetDialog the 1st time, and submit the form: only 1 POST request is send to the server.

If I open the searchSetDialog the 2nd time and submit the form, 2 POST request where send to the server.

And so on.

In doing so, there is no different if I close the Dialog using ESC, the [X] or submit (dialog(‘close’) )

The Number of (the next) POST request raised by the number of times i open and close the the dialog.

But there is only one "registerScript".

Maybe the error is some ware else?

Best regards,

rall0r

…no idea by somebody?

I tried to force my Jui-Dialog-Form-construct into that way -> http://www.yiiframework.com/wiki/72/cjuidialog-and-ajaxsubmitbutton/

…but still no success…

…there are still multiple POST Request…

:frowning:

I looks like, the ajaxSubmitButton (or an event that belongs to the button) registered multiple times. Is there a way to confirm that assumption?

I there a way to avoid that?

thank you!

Hi everybody,

I’m also have this issue (more than one request submitted by ajaxSubmitButton or AjaxLink) and I found a way to solve this issue.

This issue appear because each time you display a view with an ajaxSubmitbutton, an event handler is created.

so, a way to solve that is to destroy the handler just after using it.

by the way

CHtml::ajaxSubmitButton($model->isNewRecord ? ‘Créer’ : ‘Sauver’,

                    array('register/ajaxUpdateSk?nav='.&#036;model-&gt;navId),


		array('update'=&gt;'#skipper',


                          'type'=&gt;'POST',


                          'beforeSend'=&gt;'function(){&#036;(&#092;'body&#092;').undelegate(&#092;'#submitSk&#092;', &#092;'click&#092;');}',											


                    ),


                     array('id'=&gt;'submitSk', 'name'=&gt;'submitSk')

);

it work fine for me

Hope this help

this solution just saved my day… thanks a lot!

i had the same issue thanx Alain u saved my life

Thanks, this worked for me too.

Thanks a bunch Alain!! :)

One more solution for this problem that I found on this link work for me good, so maybe someone will like it also. If you use you custom forms for editing some part of model data and have your on JS function that will send information trough ajax, just add at end of function this line:

$(’#your-form-id’).unbind();

So after finish your ajax call this function will automatically unbind all events that is attached to it…

1 Like

This is not work for me, but some changes set all right! Anyway MANY-MANY THANKS ALAIN!

My variation Recreating ajaxSubmitButton from JUIDialog:


<?

      $ajaxSubmitButtonID = "ajax-submit-button-for-create-box";

      echo CHtml::ajaxSubmitButton(

              Yii::t('app', 'Submit'),

              Yii::app()->createUrl('somecontroller/create', array('view'=>$view)),

              array(

                'type'=>'POST',

                'dataType'=>'json',

                // 'beforeSend'=>'js:function(){$.undelegate("#'.$ajaxSubmitButtonID.'","click");}', <- WITH THIS DOESN'T WORK!

                'success'=>'function(data) {

                  if (data.success==="success") {

                    $("body").undelegate("#'.$ajaxSubmitButtonID.'","click"); # THIS THIS - ALL FINE!

                    alert("That\'s all folks!");

                    $("#someGridID").yiiGridView.update("#someGridID");

                    $("#someDialogID").dialog("close");

                  }

                }',

 	      ), array('id'=>$ajaxSubmitButtonID,)); ?>

?>

Thank you so much you are the boss you saved my lifeeeeeeeeeee :slight_smile:

I too was having this issue with multiple submits concerning forms that were inserted via ajax and that will be submitted via ajax.

Of further note. If the form, that is returned via an ajax call has a cancel button then the undelegate needs to be aded to that button’s functionality as well.

The above works in undelegating the click event when the create button is clicked but I had to do the same with the Cancel button.

Easy solution

You can achieve this result doing something like this:

CHtml::ajaxLink(‘send a message’, ‘/message’,

array('replace' =&gt; '#message-div'), 


array('id' =&gt; 'send-link-'.uniqid())

);