Yii2 Ajax Howto

How can I get only the data from my controller and not the whole page? (when clicking on the quote of the day)

And replace it in <div id="quote-of-the-day">

I’ve created this QuoteController


<?php


namespace app\controllers;

use yii\web\JsExpression;


class QuoteController extends \yii\web\Controller {


    private $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&rsquo;s Law.', 'Hofstadter&rsquo;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'],

    ];


    public function actionIndex() {

        $js = <<< JS

           $('#quote-of-the-day').click(function(){

             $.ajax({

                url: '?r=getquote',

                success: function(data) {

                    $("#quote-of-the-day").html(data)

                }

        })

    });

JS;

        

$this->getView()->registerJs( $js); 


        return $this->render('index', ['quote' => $this->getRandomQuote()]);

    }


    private function getRandomQuote() {

        return $this->quotes[array_rand($this->quotes)];

    }


    public function actionGetquote() {

         $quote=$this->getRandomQuote();

         return "&ldquo; ".$quote[0]."&rdquo;, ".$quote[1];

    }


}



in views/quote

_quote.php


&ldquo;<?php echo $quote[0]?>&rdquo;, <?php echo $quote[1]?>

index.php


<h2>Quote of the day</h2>

<div id="quote-of-the-day">

<?php 

use yii\helpers\Html;

echo yii\base\View::render('_quote', ['quote' => $quote]);?>

</div>

Why is it so hard to find Yii2 ajax examples?

whats wrong with normal JQuery ajax functions?

I hear you. Probably because Yii2 Production is still not released and the core team is primarily focused on core PHP framework code fixing/finalizing at this stage.

Just a few tips to help you get started. Most of the view related code you have shown in your controller COULD ideally be moved to the view or individual JS files. You can use asset bundles to control such client assets/code.

As for an ajax action example, to return and update a div/modal window … you could refer this wiki.

Thanks Kartik, hope lots of examples/links will follow…

I feel Yii2 is the thing for me, just need some examples to get it up and running.

For creating real user-friendly/intuitive apps!

There’s nothing wrong,

just show me the samples/tutorials combined with Yii2. :rolleyes:

I would like to see some examples too

e.g. send an ajax request, and in your controller use try/catch en decent responses, output success or error messages with growl js

intereted topic… I always find ajax implementation in yii2 after yiidev remove all internal ajax from widget…

I’m not sure if it’s what you are looking for, but I made action that return JSON and this is version that show work for you, but also shows how to handle some attributes send from jQuery:


	// to show random quote open: index.php?r=my-controller/quote

	// to show quote with ID 2: index.php?r=my-controller/quote&query=2

    public function actionQuote()

    {

    	// some parameter from JS

    	// ex. 127.0.0.1/?r=my-controller/quote&query=3

    	// $queryTerm = 3;

    	$queryTerm = Yii::$app->request->get('query');

    	Yii::$app->response->format = 'json';

    	$quotes = ['one', 'two', 'three'];

		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.'];

			}

		}

    }

You don’t need any View.

And this is JS code for index action in your controller:


    $js = <<< JS

	// get without 'query' = random quote

           $('#quote-of-the-day').click(function(){

             $.ajax({

                url: '?r=my-controller/quote',

				dataType: "json",

                success: function(data) {

                    if(data.error) {

						alert(data.error);

					} else if(data.quote) {

						$("#quote-of-the-day").html(data.quote);

					} else {

						$("#quote-of-the-day").html("Response in invalid format!");

						alert("Response in invalid format!");

					}

                }

        })

    });

	// get with ID 2

           $('#quote-of-the-day').click(function(){

             $.ajax({

                url: '?r=my-controller/quote&query=2',

				dataType: "json",

                success: function(data) {

                    if(data.error) {

						alert(data.error);

					} else if(data.quote) {

						$("#quote-number-2").html(data.quote);

					} else {

						$("#quote-number-2").html("Response in invalid format!");

						alert("Response in invalid format!");

					}

                }

        })

    });

	// get with ID 5 - does not exist

           $('#quote-error').click(function(){

             $.ajax({

                url: '?r=my-controller/quote&query=5',

				dataType: "json",

                success: function(data) {

                    if(data.error) {

						alert(data.error);

					} else if(data.quote) {

						$("#quote-error").html(data.quote);

					} else {

						$("#quote-error").html("Response in invalid format!");

						alert("Response in invalid format!");

					}

                }

        })

    });

JS;

And this is index.php View with 3 buttons (first show random, second show id 2, third show not existing quote):


<h2>Quote of the day</h2>

<div id="quote-of-the-day">

Click to get random quote

</div>

<div id="quote-number-2">

Click to get quote ID 2

</div>

<div id="quote-error">

Click to get quote that does not exist

</div>

I’ve Just tested your code and it works!!,

Thank you for your quick response and sorry for my late reaction…