Ajax Submit in Yii - php

I am using a CActive Form and, earlier i was having a normal submit button. Then I changed it to an Ajax Button like as follows,
CHtml::ajaxSubmitButton('Continue',CController::createUrl('//shop/order/create&store=true'),array('type'=>'POST'));
This goes to the url when u refresh the page. But i want it to go to the page without page refresh. Any idea how do it?
Thanks in advance.

try this, with some ajax success functionallity...
echo CHtml::ajaxSubmitButton('BottonLabel',
Yii::app()->createUrl('your/url',array('calltype' => 'system')),
array('type' => 'POST',
'cache' => true or false,
'success' => 'js:function(data) {yourJSfunction(data)}'),
array('id' => 'the_id'));
or follow this link to the class-reference for yii
ajaxSubmitButton

try this..
array('contoller_name/action','ajax'=>'somevalue'));
//In your case
echo CHtml::ajaxSubmitButton('Continue',array('contoller_name/action','ajax'=>'yw0'));
Just keep in mind that you are obviously setting auto created widget ids as params (yw0). You should assign your own ids to widgets, otherwise another widget could have the same id and that can be hard to debug..

Related

Yii: a JavaScript callback on successful form submit

I want a JavaScript callback on successful save of an active form. Where can I put the JavaScript callback?
Do I need to make the form AJAX in order to do this or is is doable with regular (non-AJAX) forms?
In fact, I am going to put this form inside an iframe (inside a jQuery UI modal dialog).
When the form in the iframe is saved I need to do two things:
close the dialog;
update the list of things in a <select> of the main HTML document.
Try to put ajax handler on form submit, here is a live code from my project as example:
echo CHtml::ajaxSubmitButton('submit',
array('index'),
array(
'type'=>'POST',
'data' => array(),
'success' => 'js:function(){/*callback*/}',
));
Please, remember to give this button an unique (prefix_random) id to avoid inconvenionces
You can add button to your form:
<?=CHtml::ajaxSubmitButton('Save', Yii::app()->createUrl('some_url'),
array('success' => 'function(response){afterSubmitForm(response);}'),
array('class' => 'btn btn-primary'));
?>
Where afterSubmitForm() js function, which get server response as parameter.

Yii: How to render partial dynamically JavaScript widgets

I have a problem with dynamically reloading of areas in html file. I use an Ajax based approach. I successfully update the area of my interest (HTML div tag), but every time I do an update the same JavaScript gets downloaded and processed along with the replacement html code, which consumes time. I want that browsers reuse, on AJAX update, the last downloaded JavaScript file instead fetching its same content again and again, which results in excessive overhead. What I mean? Let's say I have a Button Widget which has widget.js JavaScript attached to it. This JavaScript will be responsible for the event triggered on button click. Every time this button is clicked, the event will 'shoot' AJAX request and particular area on HTML page gets updated along with a download of widget.js if necessary. I want that widget.js is downloaded only the first time, but currently it gets downloaded on every AJAX request. What I noticed is that every time the mentioned JavaScript file is requested with an appended query parameter _ with random value.
widget.js?_=1374504824837
How can I disable this random parameter?
my index.php
<p>
<div id='widget-container'>
<?php
$this->renderPartial('widget');
?>
</div>
</p>
my controller
public function actionWidget()
{
$this->renderPartial('widget',array(),false,true);
}
my widget.php
<?php
$url = 'widget';
$update = '#widget-container';
$this->widget('ext.bootstrap.widgets.TbButton',
array('label' => 'Widget',
'size' => 'medium',
'buttonType' => 'ajaxButton',
'url' => $url,
'ajaxOptions' => array('type' => 'POST',
'update' => $update,
'cache' => false),
'htmlOptions' => array('id' => 'widget'.uniqid())
)
);
?>
There is an extension NLCClientScript, that is to prevent duplicated linking of javascript files when updating a view by ajax, replacing Yii's original ClientScript class.
Slightly different approach is to turn processOutput of renderPartial to false, but, in this case it won't embed any js at all
$this->renderPartial('widget', array(), false, false);

Process output in Yii Framework

I have an ajax submit button as follows,
echo CHtml::ajaxSubmitButton(
'>', $this->createUrl('/shop/category/nextCategory&id=16&store=true&gift_store='.$_GET['gift_store'].'&startValue='.$start_value.'&endValue='.$endValue), array(
'type'=>'GET',
'update'=>'#test',
'beforeSend' => 'function(){
alert("beforeSend");
}',
'complete' => 'function(){
alert("complete");
}',
)
);
In my action in the controller i use reder partial as follows,
$this->renderPartial('view',array('model'=>$this->loadModel()),false,true);
as i have set processOutput to true, the ajax submit button works fine. But it keeps on executing(for the number of times that i have clicked). I want it to execute only once when the submit button is clicked.
It'll be great if anyone could help me out with this. I have been trying to fix this all day.
okay i solved the solution. What is happening is,
The ajax request are triggered based on the ID. Every time the div is reloaded through ajax a new delegate/event will be loaded pointing at the same ID of the one before him. So when you actually click on the button both delegates will do their job, because both match the clicked button.
there are two solutions to this problem. One is having a unique id each time the button is generated like as follows,
array('id' => 'next-category-'.uniqid());
The other way, and this is how i solved it,
array("id"=>"next-category", "live"=>false);
live: boolean, whether the event handler should be attached with live/delegate or direct style. If not set, liveEvents will be used.Giving this to the submit button solved it.
Better if you create normalizeUrl for ajax request.
echo CHtml::ajaxSubmitButton(
'>', CHtml::normalizeUrl(array('/shop/category/nextCategory',array('store'=>1,'gift_store'=>1,'startValue'=>1,'endValue'=>1))), array(
'type'=>'GET',
'update'=>'#test',
'beforeSend' => 'function(){
alert("beforeSend");
}',
'complete' => 'function(){
alert("complete");
}',
)
);
This code is perfect, i have checked. It seems that their may be some error somewhere in your js code .
With the help of jQuery, you can define the following code to "complete" function:
function() {
$('input[type=submit]").attr("disabled", "disabled");
}
So on successful completion of your button will be disabled for re-push, if I understand you correctly.
Don't forget to modify the css selector input[type=submit] to the CSS selector your button.
Solution 2: Wap your CHtml::ajaxButton into
if (!Yii::app()->request->isAjaxRequest) {
}
Then when you load content via ajax your button will not be displayed on the page

CKEditor + Yii loaded with AJAX : $_POST doesn't contain the updated value

in short:
i'm using Yii Framework
i have a one Ckeditor window on my page ( php/ yii framework - works fine)
when i hit a button, a new CKeditor window is being generated and shown through AJAX call
THE PROBLEM: this new CKEditor window correctly displays the text stored in the database BUT : when i hit "Save" (an ajax button generated together with the rest of the form) the values from this new CKeditor window will not save : CKeditor sends back the old values that it got from the database.
When i remove the Ckeditor and leave the plain <textarea> : everything is ok so i know that the controller is fine.
Please, anybody went through something like this?
Sounds like a typical post-AJAX JS binding issue. :) There are a few possibilities for how to fix it, depending on what is going wrong.
This post in the Yii forum should be money for you, it's where I got most of these suggestions:
http://www.yiiframework.com/forum/index.php?/topic/9341-ckeditor-widget-in-a-cactiveform/
Use a widgetized Yii extension which has already solved this problem (NHCKEditor?)
Add an onClick callback to the submit button which saves the CKEditor content to the hidden 'textarea' ('onclick'=>'CKEDITOR.instances.TEXTAREA_ID.updateElement()',
Use jQuery to get the data from the CKEditor iFrame to use... wherever. AJAX validation, etc.
Good luck!
You can let CKEDITOR update the textarea before validating, and clientside/ajax validation will work as expected:
<?php $form = $this->beginWidget('CActiveForm', array(
'enableAjaxValidation' => true, // one or both
'enableClientValidation' => true, // one or both
'clientOptions' => array(
'validateOnSubmit' => true, // optional
'beforeValidate' => new CJavaScriptExpression('function(form) {
for(var instanceName in CKEDITOR.instances) {
CKEDITOR.instances[instanceName].updateElement();
}
return true;
}'),
),
)); ?>

CakePHP form selection as parameter

I have the following code in my index.ctp view to create a form:
<?php
echo $this->Form->create(false,array('url' => array('controller' => 'admins', 'action' => 'edit_gallery')));
echo $this->Form->input('name', array('options' => $array,'empty' => 'Select a gallery'));
echo $this->Form->end(__('Submit', true));
?>
Thi codes creates a dropdown list of items, each one with an associated number as value.
In my admins_controller I have the edit_gallery action implemented exactly as it comes when you bake a project, only that I changed the typical edit to edit_gallery.
What I want is the following: the user selects one item from the list, then clicks 'Submit', and he's taken to the edit_gallery.ctp view, with a form to edit the information of that item in the database and update it. My problem is that, instead of doing this, what happens is that when the user clicks Submit, a new item is created in the database, and it doesn't even show the ctp view.
In general, my question would be: how can I get the selected option of the form in the landing page after the user clicks 'Submit'?
Edit
Ideally, what I would want is that, when the user clicks 'Submit', it would send a request like admins/edit_gallery/x where x would be the value associated to the selection made by the user, without sending any other data to the action. I don't know if that's possible.
Thank you!
The edit method that CakePHP bakes check by default if data is not null, in other words, if a form has been submitted, and then updates that record.
So, when you redirect to *edit_gallery* from a form, the data property is not null, therefore the reason for the new item creation in the database.
There are many ways to solve this. One of them is to remove that check from the *edit_gallery* method, create another method like *save_gallery*, and call that method from *edit_gallery.ctp*.
So the *edit_gallery.ctp* form would look something like:
<?php
echo $this->Form->create(false,array('url' => array('controller' => 'admins', 'action' => 'save_gallery')));
(your form info)
echo $this->Form->end(__('Submit', true));
?>

Categories