Newbie ajax confusion while ostensibly following Cookbook....

Hi

I’m trying to do a very simple renderPartial using an ajaxLink, and have really found it hard to find a simple explanation on the site.

I followed the code from the example, and nothing happens, and when I look at the generated code for the ajaxLink it shows up as <a href="#" id="yt0">Another Comment</a>

I put in the original view (essentially right from the Cookbook page) view.php:

&lt;div id=&quot;data&quot;&gt;

<?php $this->renderPartial(’_anothercomment’, array(‘myValue’=>$myValue)); ?>

&lt;/div&gt;	


&lt;?php echo CHtml::ajaxLink(&quot;Another Comment&quot;, CController::createUrl('album/UpdateAjax'), array('update' =&gt; '#data'));


?&gt;

and then on the controller page AlbumController.php:

public function actionUpdateAjax()

{


    &#036;data = array();


    &#036;data[&quot;myValue&quot;] = &#036;model-&gt;reviewquote_2;





    &#036;this-&gt;renderPartial('_anothercomment', &#036;data, false, true);


}

and on the partial: _anothercomment.php

<?php echo $myValue;?>

Could anyone tell what I’m doing wrong?

Thanks

michael

Looks right to me, the code generated for the ajax link is ok.

Are you seeing any javascript errors ? Firefox with Firebug are an excellent combination to verify if your ajax calls are being performed and what the response is.

nz

I can see the javascript for the ajax call in Firebug, but i see no info on response… but I have never used Firebug before - the wiki talks about a 1.5x version that is the "tracing version" but on the download site I was only able to get 1.5

no firebug errors are shown, but I get no response either. What I am trying to do is get additional data from a field in a table, I think that the code in the controller is OK with:

    &#036;data = array();


    &#036;data[&quot;myValue&quot;] = &#036;model-&gt;reviewquote_2;


    &#036;this-&gt;renderPartial('_anothercomment', &#036;data, false, true);

and I know that the field isn’t null, so I don’t think that is the issue. Just to check I added another value to the data array that was just a string, but that didn’t show up either.

frustrating! and I have been really enjoying working with yii the past week

Thanks for the clue on firebug, it looks very useful. I had gotten into the habit of using Chrome, I may be using firefox a lot more

The $model object needs to be populated on the Ajax call.

You can see the Ajax requests under "Console" in Firebug.

/Tommy

Thanks for the console tip

here is the relevant section of the link shown…

/index.php?r=album/UpdateAjax&_=1265984429221

and the message is 403 aborted

subsequent clicks have a different number appended and throw a 403 CHttpException

very interesting - I have no idea where the "&_=1265984429221" comes from!

the response is

You are not authorized to perform this action.

so i will look at the accessRules()

Do you use access rules and forgot to add "updateajax"?

The "&_=1265984429221" string is appended by jQuery to avoid caching (unique url on every call).

(IIRC)

/Tommy

I changed the accessrules() to allow ‘updateajax’ and got:

The requested page does not exist.

Now, in looking at the cookbook, my understanding is that the CController::createUrl(‘album/UpdateAjax’) portion of the ajaxLink() in my original script view.php works like this:

‘album/UpdateAjax’ translates to "look in AlbumController.php for the actionUpdateAjax function and then render a chunk of code from the file named in the renderPartial() portion of the actionUpdateAjax function:

   &#036;this-&gt;renderPartial('_anothercomment', &#036;data, false, true);

so I am assuming that the renderPartial would call _anothercomment.php from the appropriate view - in this case album/_anothercomment.php

except that in the params portion of firebug the non-existing page is

http://… /michael/index.php?r=album/UpdateAjax&_=126598637644

so I guess I’m still confused!

Your right in your understanding. I think your access rules are your problem, can you comment them out and see if it works ? Specifically this request http://localhost/index.php?r=album/UpdateAjax should not give you a 403 error. If it does work post your access rules .

NZ

I had changed the access rules previously, and the firebug response "You are not authorized to perform this action." went away. It was replaced by "The requested page does not exist."

I changed access rules again,to wide open

		array('allow',  


			'users'=&gt;array('*'),

but got the same "The requested page does not exist."

the "http://localhost/index.php?r=album/UpdateAjax" is the URL for the controller, not the view

the function actionUpdateAjax in AlbumController.php would then call the view _anothercomment.php , right?

based on the previous accessrules error, it IS calling AlbumController.php, or else it wouldn’t have generated that error, I just can’t figure out why renderPartial isn’t calling for the _anothercomment.php file

So specifically you have the following ?




public function accessRules() {return array('allow', 'users'=>array('*'),); }



Do you define the function "actions" in your controller ?

NZ

at first i got the error "You are not authorized to perform this action." when trying to invoke album/UpdateAjax then I changed accessrules to :

		array('allow',  // allow all users to perform 'index' and 'view' actions


			'actions'=&gt;array('index','view','updateajax'),


			'users'=&gt;array('*'),


		),


		array('allow', // allow authenticated user to perform 'create' and 'update' actions


			'actions'=&gt;array('create', 'update'),


			'users'=&gt;array('@'),


		),


		array('allow', // allow admin user to perform 'admin' and 'delete' actions


			'actions'=&gt;array('admin','delete'),


			'users'=&gt;array('admin'),


		),


		


		array('deny',  // deny all users


			'users'=&gt;array('*'),


		),

after adding ‘updateajax’ to the allow rule in the first section, the error went away, and was replaced by “The requested page does not exist.”

I then further changed it to

array(‘allow’,

‘users’=>array(’*’),

after commenting everything else out. No access errors, but still the file not found error

I recommend the following steps:

  1. For a quick solution try echoing the string from the controller action instead of rendering the view

  2. Enable logging and add calls to Yii::trace()

The blog tutorial has this description:

http://www.yiiframework.com/doc/blog/final.logging

(remember to add trace and info levels)

You will find the log file under protected/runtime

For further reading about logging see this section in the guide

http://www.yiiframework.com/doc/guide/topics.logging

/Tommy

You did not answer my second question "Do you define the function "actions" in your controller ?"

If so comment it out.

nz

Sorry. I do not define the function "actions" - if by that you mean actions()

also I did add updateajax to the actions in the accessRules() array

array(‘allow’, // allow all users to perform ‘index’ and ‘view’ actions

‘actions’=>array(‘index’,‘view’,‘updateajax’),

‘users’=>array(’*’),

),

the other action functions (actionUpdate actionCreate etc) created by yiic in the controller seem to work fine

I was just following the cookbook - which didn’t remind me of the need to change accessRules(), so I just essentially adapted the instructions and tried to run it.

I think this is the key to why the mixed case URL didn’t work

http://code.google.com/p/yii/source/browse/trunk/UPGRADE

It seems like you verified that lower case is a requirement (feel free to comment or update the cookbook article). A note about the need for adding new actions to accessRules() may also be appropriate.

(Qiang, the convention section of the guide may also need some attention)

/Tommy

Well, I changed the ajaxLink variable to album/updateajax , the controller function from actionUpdateAjax to actionupdateajax, and I still get "The requested page does not exist." when I look at the console in Firebug.

here is the stack trace:

Stack trace:

#0 /home/garuda/public_html/michael/protected/controllers/AlbumController.php(177): AlbumController->loadModel()

#1 /home/garuda/public_html/yii/framework/web/actions/CInlineAction.php(32): AlbumController->actionupdateajax()

#2 /home/garuda/public_html/yii/framework/web/CController.php(300): CInlineAction->run()

#3 /home/garuda/public_html/yii/framework/web/filters/CFilterChain.php(129): CController->runAction(Object(CInlineAction))

#4 /home/garuda/public_html/yii/framework/web/filters/CFilter.php(41): CFilterChain->run()

#5 /home/garuda/public_html/yii/framework/web/CController.php(983): CFilter->filter(Object(CFilterChain))

#6 /home/garuda/public_html/yii/framework/web/filters/CInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain))

#7 /home/garuda/public_html/yii/framework/web/filters/CFilterChain.php(126): CInlineFilter->filter(Object(CFilterChain))

#8 /home/garuda/public_html/yii/framework/web/CController.php(283): CFilterChain->run()

#9 /home/garuda/public_html/yii/framework/web/CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#10 /home/garuda/public_html/yii/framework/web/CWebApplication.php(320): CController->run(‘updateajax’)

#11 /home/garuda/public_html/yii/framework/web/CWebApplication.php(120): CWebApplication->runController(‘album/updateaja…’)

#12 /home/garuda/public_html/yii/framework/base/CApplication.php(135): CWebApplication->processRequest()

#13 /home/garuda/public_html/michael/index.php(11): CApplication->run()

#14 {main} REQUEST_URI=/michael/index.php?r=album/updateajax&_=1266008343445

2010/02/12 13:00:00 [trace] [system.web.CModule] Loading "errorHandler" application component

so I changed the ajaxLink and controller function back to how I had them before

same result - "The requested page does not exist." from Firebug

here’s the stack trace:

Stack trace:

#0 /home/garuda/public_html/michael/protected/controllers/AlbumController.php(177): AlbumController->loadModel()

#1 /home/garuda/public_html/yii/framework/web/actions/CInlineAction.php(32): AlbumController->actionUpdateAjax()

#2 /home/garuda/public_html/yii/framework/web/CController.php(300): CInlineAction->run()

#3 /home/garuda/public_html/yii/framework/web/filters/CFilterChain.php(129): CController->runAction(Object(CInlineAction))

#4 /home/garuda/public_html/yii/framework/web/filters/CFilter.php(41): CFilterChain->run()

#5 /home/garuda/public_html/yii/framework/web/CController.php(983): CFilter->filter(Object(CFilterChain))

#6 /home/garuda/public_html/yii/framework/web/filters/CInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain))

#7 /home/garuda/public_html/yii/framework/web/filters/CFilterChain.php(126): CInlineFilter->filter(Object(CFilterChain))

#8 /home/garuda/public_html/yii/framework/web/CController.php(283): CFilterChain->run()

#9 /home/garuda/public_html/yii/framework/web/CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#10 /home/garuda/public_html/yii/framework/web/CWebApplication.php(320): CController->run(‘UpdateAjax’)

#11 /home/garuda/public_html/yii/framework/web/CWebApplication.php(120): CWebApplication->runController(‘album/UpdateAja…’)

#12 /home/garuda/public_html/yii/framework/base/CApplication.php(135): CWebApplication->processRequest()

#13 /home/garuda/public_html/michael/index.php(11): CApplication->run()

#14 {main} REQUEST_URI=/michael/index.php?r=album/UpdateAjax&_=1266008536360

2010/02/12 13:03:13 [trace] [system.web.CModule] Loading "errorHandler" application component

so I don’t think that the case sensitivity is the issue.

Thanks for all your help everybody though - I will get this figured out somehow!

michael

The controller action method names should still be in camelCase. Only the route part of the url behaves differently. BTW, all lower case in the route was always valid.

Edit: trying to find the reference for the above. From the subsection Route in the Fundamentals - Controller section of the guide:

Note the difference between inline actions (has to start with "action") and external action classes.

/Tommy

regarding the naming, I gathered that from the way things were named in the accessRules()

well, I tried both ways and it didn’t work from either one… still “The requested page does not exist.”

Does anything jump out at you from the stack trace?? it looks to me like Jquery is still calling the URI from the call to the controller rather than the one I want, which is view/album/_anothercomment.php and which I understood would be created by the renderPartial() call in actionUpdateAjax

{main} REQUEST_URI=/michael/index.php?r=album/UpdateAjax&_=1266008536360

Once again, the example in the Cookbook leads me to believe thats the way it is supposed to work - please correct me if I am wrong!!

Sorry, I didn’t pay attention to the stack traces before. It seems clear that action UpdateAjax is entered in both cases. What’s loadModel()? That’s the last method called. Do you call $this->loadModel(), is the method defined in the controller. What’s in it?

Also, as already suggested, try with view rendering excluded, just echo a string from the controller.




echo 'aString';

Yii::app()->end();   // or you can call die;



/Tommy

OK, loadModel()could be the culprit…

here is the code for loadModel and for actionUpdateAjax. I want to get some data from the AR, and thought I needed to call loadModel() but notice that if the model is null that ‘The requested page does not exist.’ is thrown

notice that I commented out the loadModel call in actionUpdateAjax – when I just ran it, I did not get the error. But I STILL didn’t get the data I wanted for AR either. So I’m probably not accessing that data properly…

BTW here’s the info on $_model (this code generated by yiic)

/**


 * @var CActiveRecord the currently loaded data model instance.


 */


private &#036;_model;

















public function loadModel()


{


	if(&#036;this-&gt;_model===null)


	{


		if(isset(&#036;_GET['id']))


			&#036;this-&gt;_model=Album::model()-&gt;findbyPk(&#036;_GET['id']);


		if(&#036;this-&gt;_model===null)


			throw new CHttpException(404,'The requested page does not exist.');


	}


	return &#036;this-&gt;_model;


}





public function actionUpdateAjax()


{


//&#036;model=&#036;this-&gt;loadModel();  	


    &#036;data = array();


    &#036;data[&quot;myValue&quot;] = &#036;model-&gt;reviewquote_2;





    &#036;this-&gt;renderPartial('_anothercomment', &#036;data, false, true);


}

would I need to pass the id variable from the ajaxLink call in view.php along with the data about the controller file?