= Yii 2 Using AJAX =
== Using JQuery AJAX ==
Create a view. This should include the JavaScript method to call AJAX, and a form control that calls the method somehow (eg. ''onchange'' or ''click'' events).
File ''/views/issue/create.php'':
request->baseUrl. '/issue/get-company' . "',
// Parameter data to pass in
data: {
account_number: $('#issue-account_number').val(),
},
type: 'POST',
cache: false,
// Code to run if the request succeeds;
// the response is passed to the function
success: function(data) {
// process data
console.log('data: [' + data + ']');
$('#company_search_results').html(data);
},
// Code to run if the request fails;
// the raw request and status codes are passed to the function
error: function( xhr, status, errorThrown ) {
alert('Sorry, there was a problem! Error: ' + errorThrown + 'Status: ' + status + xhr);
console.log('Error: ' + errorThrown );
console.log('Status: ' + status );
console.dir( xhr );
},
// Code to run regardless of success or failure
complete: function( xhr, status ) {
//alert('The request is complete!');
}
})
.fail (function(){ alert('Error'); });
}
";
// NOTE: $position can be:
// View::POS_READY (the default)
// View::POS_HEAD
// View::POS_BEGIN
// View::POS_END
$position = \yii\web\View::POS_END;
$this->registerJs($jsBlock, $position);
?>
...
In controller, add action to handle query in ''OnChange'':
File ''/controllers/IssueController.php'':
use app\models\Issue;
use app\models\Customer;
...
class IssueController extends Controller
{
...
public function actionGetCompany()
{
// Grab AJAX parameter from POST (since that is the method we used)
if (Yii::$app->request->isPost){
$account_number = Yii::$app->request->post('account_number');
Yii::info('POST account_number: ' . $account_number, 'actionGetrec');
}
// Validate and query the data we need
if (empty($account_number)) {
$modelCust = new Customer();
$account_number = $modelCust->account_number;
$company_name = $modelCust->company_name;
$arrCustomer = $modelCust->toArray();
Yii::info('Empty account_number: ' . $account_number .
'company_name: ' . $company_name, 'actionGetrec');
} else {
$modelCust = Customer::find()->where(['account_number' => $account_number])->one();
$arrCustomer = Customer::find()->where(['account_number' => $account_number])->asArray()->one();
if(!empty($modelCust)) {
$company_name = $modelCust->company_name;
Yii::info('Found account_number: ' . $account_number .
'company_name: ' . $company_name, 'actionGetrec');
Yii::info('Customer record: ' . print_r($modelCust, true), 'actionGetrec');
} else {
Yii::info('Customer not found: ' . $account_number, 'actionGetrec');
}
}
// Prepare data to send back
$data = array();
if (!empty($arrCustomer['company_name'])) { $data[] = $arrCustomer['company_name']; }
if (!empty($arrCustomer['address'])) { $data[] = $arrCustomer['address']; }
if (!empty($arrCustomer['city'])) { $data[] = $arrCustomer['city']; }
if (!empty($arrCustomer['state_prov'])) { $data[] = $arrCustomer['state_prov']; }
if (!empty($arrCustomer['country'])) { $data[] = $arrCustomer['country']; }
if (!empty($arrCustomer['phone'])) { $data[] = $arrCustomer['phone']; }
if (!empty($arrCustomer['phone'])) { $data[] = $arrCustomer['phone']; }
if (!empty($arrCustomer['email'])) { $data[] = $arrCustomer['email']; }
// Send AJAX results
if (count($data) > 0) {
return '' . implode(', ', $data) . '
';
} else {
return 'Customer record not found
';
}
}
}
== Using JQuery $.get() or $.post() ==
You can also get data using a simplified AJAX call using JQuery ''$.get()'' or ''$.post()'' method attached to an event (such as ''OnChange'' event).
Using GET method:
= $form->field($model, 'product_name')->dropDownList(ArrayHelper::map(Products::find()->all(), 'id', 'name'), [
'prompt' => '-Choose a Product-',
'onchange' => '
//var aUrl = "index.php?r=suborders/listprice&id="+$(this).val(); // with enablePrettyUrl disabled (default)
var aUrl = "'.Yii::$app->homeUrl.'suborders/listprice/id/"+$(this).val(); // with enablePrettyUrl enabled
$.get( aUrl, function( data ) {
$( "#suborders-product_price" ).val( data );
});
',
]) ?>
Using POST method:
= $form->field($model, 'product_name')->dropDownList(ArrayHelper::map(Products::find()->all(), 'id', 'name'), [
'prompt' => '-Choose a Product-',
'onchange' => '
var anId = $(this).val(); // or $("#my_element_id").val()
var aUrl = "'.Yii::$app->homeUrl.'suborders/listprice"; // with enablePrettyUrl enabled
$.post({
url: aUrl,
data: {id: anId},
success: function( data ) {
$( "#suborders-product_price" ).val( data );
},
error: function (xhr, status, errorThrown) {
console.log("Error: " + errorThrown );
console.log("Status: " + status );
console.dir( xhr );
},
dataType: "json" // return data type
});
',
]) ?>
=== Examples ===
Request the test.php page, but ignore the return results.
$.get( "test.php" );
Request the test.php page and send some additional data along (while still ignoring the return results).
$.get( "test.php", { name: "John", time: "2pm" } );
Pass arrays of data to the server (while still ignoring the return results).
$.get( "test.php", { "choices[]": ["Jon", "Susan"] } );
Alert the results from requesting test.php (HTML or XML, depending on what was returned).
$.get( "test.php", function( data ) {
alert( "Data Loaded: " + data );
});
Alert the results from requesting test.cgi with an additional payload of data (HTML or XML, depending on what was returned).
$.get( "test.cgi", { name: "John", time: "2pm" } )
.done(function( data ) {
alert( "Data Loaded: " + data );
});
Get the test.php page contents, which has been returned in json format (''"John","time"=>"2pm" ) ); ?>''), and add it to the page.
$.get( "test.php", function( data ) {
$( "body" )
.append( "Name: " + data.name ) // John
.append( "Time: " + data.time ); // 2pm
}, "json" );
See more:
* [[https://api.jquery.com/jquery.get|JQuery.get() Documentation]]
* [[https://api.jquery.com/jquery.post|JQuery.post() Documentation]]
== Using AJAX Returning JSON ==
Add HTML elements that will be updated with AJAX, and attach the AJAX functionality to an event, such as the ''click'' event. Eg: The view ''index'' for the ''SiteController'' (file ''[app]/views/site/index.php''):
Quote of the day
Click to get random quote
Click to get quote ID 2
Click to get quote that does not exist
...
registerJs($jsBlock, $position);
?>
In the controller, add an action to handle the AJAX request. Eg: In the ''SiteController'' we would add action ''quote'' (file ''[app]/controllers/SiteController.php''):
request->get('query');
Yii::$app->response->format = 'json';
//$quotes = ['one', 'two', 'three'];
$quotes = [
['Walking on water and developing software from a specification are easy if both are frozen.', 'Edward V Berard'],
['It always takes longer than you expect, even when you take into account Hofstadter’s Law.', 'Hofstadter’s Law'],
['Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.', 'Rick Osborne'],
['I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone.', 'Bjarne Stroustrup'],
['Java is to JavaScript what Car is to Carpet.', 'Chris Heilmann']
];
if($queryTerm !== null) { // some parameter specified
if(isset($quotes[$queryTerm])) { // quote exists, show it
return ['quote' => $quotes[$queryTerm]];
} else { // quote with specified ID does not exist
return ['error' => 'Quote with this ID does not exist.'];
}
} else { // no parameter - show random
if(count($quotes) > 0) { // we got some quotes, we can random
return ['quote' => $quotes[rand(0, count($quotes)-1)]];
} else { // we got zero quotes, error
return ['error' => 'Zero quotes in database. Cannot show random quote.'];
}
}
}
...
}
?>
Source: [[http://www.yiiframework.com/forum/index.php/topic/54820-yii2-ajax-howto/]]
References:
* [[http://www.yiiplayground.com/yii2/web/index.php?r=ajax/index|Yii2 Playground: Ajax Request]]
* [[http://www.yiiframework.com/forum/index.php/topic/54820-yii2-ajax-howto/|Yii 2 Ajax HowTo]]
* [[http://stackoverflow.com/questions/28831860/ajax-controller-action-in-yii2|Ajax Controller Action in Yii2]]
* [[http://stackoverflow.com/questions/24199595/how-to-make-ajax-call-in-yii2|How to make Ajax call in Yii2]]
* [[http://tutorials.jenkov.com/jquery/ajax.html|JQuery Ajax Tutorial]]
* [[http://learn.jquery.com/ajax/|JQuery Ajax]]
== Using PJAX (instead of AJAX) ==
In the view, add a Pjax block where dynamic value is going to display. Eg: For the 'Create Issue' view in ''[app]/views/issue/create.php'':
use yii\widgets\Pjax;
...
= Html::a("Generate Random String", ['issue/create'], ['class' => 'btn btn-lg btn-primary']) ?>
= $randomString ?>
= Html::a("Generate Random Key", ['issue/create'], ['class' => 'btn btn-lg btn-primary']) ?>
= $randomKey ?>
In the controller, create the variables references in the view. Eg: For the 'Create Issue' view, we add this to the ''actionCreate()'' in ''[app]/controllers/IssueController.php'':
public function actionCreate()
{
$randomString = strtotime("now");
$randomKey = strtotime("now");
$model = new Issue();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
'randomString' => $randomString,
'randomKey' => $randomKey,
]);
}
}
Another example, pointing to different actions. Eg: File ''views\site\time-date.php''
use yii\widgets\Pjax;
use yii\helpers\Html;
...
= Html::a("Show Time", ['site/time'], ['class' => 'btn btn-lg btn-primary']) ?>
= Html::a("Show Date", ['site/date'], ['class' => 'btn btn-lg btn-success']) ?>
It's: = $response ?>
File ''controllers\SiteController.php''
public function actionTime()
{
return $this->render('time-date', ['response' => date('H:i:s')]);
}
public function actionDate()
{
return $this->render('time-date', ['response' => date('Y-M-d')]);
}
== References ==
* [[http://blog.neattutorials.com/yii2-pjax-tutorial|Yii2 Pjax Tutorial]]
* [[https://stackoverflow.com/questions/23953659/using-pjax-in-yii2-for-updating-a-div|Using Pjax in YII2 for updating a div]]