Yii - about jquery ajax - php

I am writing a shop application, and I have a question.
As you know ajax in Yii looks like
<?php
echo CHtml::ajaxLink(
'',
array("cart/add/id/$item->id"),
array(
'update'=>'#cart',
),
array('class' => "button_basket")
);
?>
This code updates the div with id = cart. How can I update the other elements on the page? For example on the Cart page, I am removing via ajax one item and I need to update the Total price, what is the best way to do this?

For this you'll need to write some javascript, preferably a function that will read the response from the server, and make changes in the ui accordingly.
If you go through the documentation for ajaxLink();, you'll see that the third parameter is ajaxOptions which takes the options of jQuery's ajax method. Therefore you can write a callback function for the success event. And in this function you can make changes to your ui.
Sample code:
<?php
echo CHtml::ajaxLink(
'',
array("cart/add/id/$item->id"),
array(
// 'update'=>'#cart', this will be ignored when you have success callback
'success'=>'js:successFunctionName',
),
array('class' => "button_basket")
);
?>
Somewhere in the current view you can use registerScript to output the function to the view:
Yii::app->clientScript->registerScript('scriptname','
function successFunctionName(data, textStatus, jqXHR){
// write awesome javascript to change ui
}
');

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);

What is the proper way to pass options to a jquery file?

On each page of my theme, a user has the option of adding a slider. When they do this, they can choose several settings for the slider. This includes things such as how long the slides will pause before changing, how long it takes for the slide to transition when it changes, and what type of transition it uses.
Now if I were to just hard code this and not let the user choose the options for the slider, the code would look like this:
<script>
jQuery(function(){
jQuery('#camera_wrap_3').camera({
height: '40%',
thumbnails: true,
time: 3500,
fx: 'scrollBottom',
transPeriod: 1200,
autoAdvance: true,
minHeight: '50px',
mobileNavHover: false,
});
});
</script>
What is the proper way to pass the variables that are created when the user chooses their settings to the code above?
Keep in mind that I want to be able to enqueue this file the proper way with wp_enqueue
I'm assuming this is related to your question about passing variables to wp_head - if you want to store parameters from a plugin, Wordpress provides two (three if you are using multisite) methods depending on the scope of your parameters.
If it is specific to a page/post, then you should store the parameters in the postmeta table with the Custom Fields API. You would use update_post_meta($post_id, $key, $data) and fetch it with get_post_meta($post_id, $key, $single) where $single is true/false depending on if you want an array of values or just a single value - if it is something like "width" you would probably set this to true. More info here - http://codex.wordpress.org/Custom_Fields.
If it is applicable to the entire site, then you would store it in the Options API in the options table using update_option($key, $data) and retrieve it with get_option($key, $default) where $default is returned if the $key can't be found, otherwise it will return false. The last option applicable only to multisite is also part of the Options API and uses update_site_option($key, $data) and get_site_option($key, $default). More info here - http://codex.wordpress.org/Options_API.
An excellent option for managing custom fields (and options through a premium feature) is Advanced Custom Fields.
Assuming this is per post/page, and you are setting the values with ACF, you can then write a hook to wp_head to pull these fields into your Javascript. You can either put this into the functions.php file in your theme, or if you want it to stick around if you change themes, you can use a Custom Functions Plugin.
// hooked to wp_head
function my_wp_head(){
// get the current $post
global $post;
// get value or key "camera_time"
$camera_time = get_post_meta($post->ID, "camera_time", true);
// write result to javascript
echo "<script>";
echo "var cameraTime = {$camera_time};";
// ... the rest of your javascript
echo "</script>";
}
if (is_single()) // only include on single pages
add_action( 'wp_head', 'my_wp_head' );
you can use extend method for that.
function foo (params) {
//default values
var settings = $.extend({
'someKey': { k1: 'v1' },
'otherKey': 'oTherValue'
}, params);
//use it
if (settings.someKey.k1 == 'v1') ...
var bar = settings.otherKey;
}
then just call it from your code
foo({someKey: {k1: 'v2'}, otherKey: 'bla' });
i created a simple jQuery plugin usnig this approach. check it out

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

Ajax Submit in Yii

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..

Categories