best practices for ajax

I get ajax. I get jQuery.

What I want to know is there some cool Yii best practice.

Before frameworks you have some package to do ajax. Your front end passes data into javascript which is intercepted by the package and gets to the backend. The backend know nothing about who called it. You could have the backend totally somewhere else.

For example I use jQuery .post method to send some data to a URL to process it. This is a totally backend script, so no views or anything. Would it just be a procedural php script to do whatever I need done and send the response back? Is there any support in Yii for this. Do you store such scripts in a directory called ajax or something? Or outside of Yii. will you hit problems with the rewrite rules? This is really more a question How do you guys handle the layout & packaging of these things. Thank you. I never saw Yii examples with very much ajax in them I don’t think.

Check this in cookbook

http://www.yiiframework.com/doc/cookbook/46/

http://www.yiiframework.com/doc/cookbook/49/

Thanks, what I get from this is to have the ajax processor action as a method in the controller script and let it go through the usual routing. That’s the bit I was unsure about. I wish the search function on these forums was better.

Now I see that Yii has an ajax button sort of thing. Is that the same as if you have an independent jQuery script with a .get or .post in it?

Yes. Actually i see them as helper for the simple cases. But even then i never use any CHtml::ajax* and always rely on custom jquery code. As jquery code is usually easy to understand i don’t see much benefit if it’s wrapped in another PHP method. But that’s only my POV.

I’m on the page with you Mike. I’m just learning, but in general it seems like a lot of these so-called wrapper thingies are more trouble & overhead than they are worth and actually add ballast to the learning curve, and only work well for the dead simple cases anyway, now you not only have to learn WTF it is your doing but you have to remember the parameters to the wrapper and it ends up being kind of chunky and unreadable, whereas if you know jQuery just attach the jQuery directly. If I wanted trivial I wouldn’t bother with all this jQuery in the 1st place.

OK now question please help me with a logistical.

My ajax javascript with jQuery is below, it is being properly attached and called when you click

the submit button but Yii can’t find the URL on the server side so it’s coming back with a 404.

note in the javascript where the url is.

I would really rather not hard code the URL but I will for now

I think I’m getting messed up in the urlmanager.

These are the rules I have configured I really don’t understand urlManager at all.


'urlManager' => array(

		    'urlFormat' => 'path',

		    'rules' => array(

		        'tag/<tag>' => 'joke/list',

		        'jokes' => 'joke/list',

		        'joke/<id:\d+>' => 'joke/show',

		        'joke/update/<id:\d+>' => 'joke/update',

		    ),

		),



I do have a submitRatingAction method defined in my joke controller so it should at least get into it if Yii

could find it.

Can someone pls tell me how to make Yii find it?

Here is my Javascript, not that it really matters for this except for the URL.




//ajaxrate.js

//to attach to submit button in show view for joke

$(document).ready(

	function() {

		$('#submitRating').click(

		   function($e) {

			   $e.preventDefault();

			   console.log("INSIDE");

			   $.post(

			       '/yiijokes/joke/submitRating',        

			       $('form :input').serialize(), 

			       function(xml) {

			    	   if (parseInt($(xml).text()) >0) {

			    		   alert('Rating Successfully Updated');

			    	   } 

			       },

			       'xml'

			   );

		   }

        ); 

	}

);	



Try accessing the URL /yiijokes/joke/submitRating directly in your browser. What is the error message? You need actionSubmitRating method, not submitRatingAction.

yes (sheepish grin) after while I realize I was using Zend convention for controller actions method name

(OOPS)

so I renamed it to

actionSubmitRating and also enabled any logged in user to do it in the access

The full url for everything is actually like

http://testing1/yiijokes/index.php/joke/list (which works)

The virtual server is name testing1 so I fixed the url in the ajax routine to be

‘/yiijokes/index.php/joke/submitRating’,

and I access directly in browser already and it is still getting page not found but actually

[size="5"][color="#FF0000"]the URL is working!!!!![/color][/size]

because it’s getting into the action routine and trying to loadJoke but I don’t know how to know which joke we’re on since sending thru ajax does a whole new Yii this way. I don’t want to do put the joke id through the form because security. That’s why I don’t put the user ID in the form also, the app already knows which user in the cookie. Where is saved the id of the active record we were on before we submit this server call?

Here is the entire error stack:

exception ‘CHttpException’ with message 'The requested page does not

exist.’ in

/Users/tpdick/Sites/testing1/yiijokes/protected/controllers/JokeController.php:234

Stack trace:

#0 /Users/tpdick/Sites/testing1/yiijokes/protected/controllers/JokeController.php(257):

JokeController->loadJoke()

#1 /Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/actions/CInlineAction.php(32):

JokeController->actionSubmitRating()

#2 /Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/CController.php(300):

CInlineAction->run()

#3 /Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/filters/CFilterChain.php(129):

CController->runAction(Object(CInlineAction))

#4 /Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/filters/CFilter.php(41):

CFilterChain->run()

#5 /Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/CController.php(957):

CFilter->filter(Object(CFilterChain))

#6/Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/filters/CInlineFilter.php(59):

CController->filterAccessControl(Object(CFilterChain))

#7/Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/filters/CFilterChain.php(126):

CInlineFilter->filter(Object(CFilterChain))

#8/Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/CController.php(283):

CFilterChain->run()

#9/Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/CController.php(257):

CController->runActionWithFilters(Object(CInlineAction), Array)

#10/Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/CWebApplication.php(320):

CController->run(‘submitRating’)

#11/Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/web/CWebApplication.php(120):

CWebApplication->runController(‘joke/submitRati…’)

#12/Users/tpdick/Sites/testing1/yii-1.1a.r1436/framework/base/CApplication.php(135):

CWebApplication->processRequest()

#13 /Users/tpdick/Sites/testing1/yiijokes/index.php(11):

CApplication->run()

#14 {main} REQUEST_URI=/yiijokes/index.php/joke/submitRating


/**

 * triggered by ajax, sends asynchronous ratings update to server

 * @return unknown_type

 */	

	public function actionSubmitRating()

	{  

	   return $this->loadJoke()->addRating($_REQUEST['rating'], $_REQUEST['userId']);  //dunno if this is how u do it 

	}

and here is the addRating function from the Joke model not sure how you really suppose to do it but that is a start.

public function addRating(&#036;rating,&#036;userId) 


{


    &#036;q = &quot;INSERT Rating (rating, jokeId, userId, dateCreated, dateUpdated) values(' . &#036;rating . ', ' . &#036;this-&gt;model-&gt;id . ', ' . &#036;userId . ', NOW(), NOW )&quot;;


    //how do you submit a query to this thing


    Yii::app()-&gt;db-&gt;execute(&#036;q);  //no error checking for now


    return 1;


}

When I did my own little framework years ago, I reasoned that the little snippets of PHP code you submit ajax requests to should not really be part of the framework because each page request to a framework URL causes a whole bunch of objects to be generated that are not really needed just to process a REQUEST and update a database.

But the tutorials I’ve seen on Yii and Zend suggests that you should make your ajax target an action of your controller. That goes through the whole application generation process each time you merely want to do a little bit of ajax. Won’t that be cumbersome and cause performance hits?

Why is that way a better practice? What do you gain in easy and flexibility to make up for loss in performance?

So no one can answer this?

Yii tries to keep the loss in performance as low as possible since only required application components are loaded. You gain all advantages of a framework: central configuration, easy extensibility, db abstraction, …

This is remembering my first steps with CI.

That time I was learning MVC and when there were the need for ajax I did some php scripts (1-2 then I learn how to use controllers for this) ouside CI.

But why do you make some functions outside your Yii code.Do not you want all be at one place?

Will be so slow your ajax code?

OK. I’m sold. I want my ajax scripts to have the db abstraction.