Ajax action in Yii

Hi,

I have a trouble working with ajax function with yii, I have a cgridview and end column is an button update,

when I click button update, I want to call an ajax function to invoke controller action. But i’d try all week, but still not idea

This is my code in cbuttonColumn with the update button:




array(

                'class' => 'CButtonColumn',

                'header' => 'Actions',

                'template' => '{update}',

                'updateButtonUrl' => '"#"',

                'updateButtonOptions' => array(

                      'class' => 'update',                    

                ),

            ),



I also have a javascript file included in page with jquery - ajax :




$('.update').click(function(){

        var id = $(this).parent().parent().children(':nth-child(2)').text();

        $.ajax({

            url: '/QuanLyTour/congty/quickUpdate/',

            type: "POST",

            dataType: 'xml',

            success: function(xml){

                if($(xml).find("jobs")){

//                    alert($(xml).find("result").text());

                    alert("suuccess");

                    alert($(xml).find("job").text());


                }                            

            },

            error: function(){

                alert("error");

            }

        });

        return false;

    });



This is my controller action which named actionQuickUpdate():




public function actionQuickUpdate()

    {   

        $value .= "<?xml version=\"1.0\"?>";

        $value .= "<root><jobs><job>Done</job></jobs>";

        $value .= "</root>";

        echo  $value;

    }



When I click “update” button, it also alert error, that mean, the request fail, but when i tried without “dataType: xml”, the success option in ajax is called. So, i don’t understand what wrong with my code.

Hope you can solve this problem!

I haven’t used XML… but check the jQuery documentation for ajax - http://api.jquery.com/jQuery.ajax/

There it says

Can you suggest any idea for my case? I’d tried for a long type, even I changed my action return type to html type, but it almost not work. If change “dataType” to “html” or “sript”, in my controller action return:




return "<div class='result' id='result'>ok</div>"



or:




return "<script>var data = 1;</script>"



and my Ajax success option:




success: function(){

            alert($('div.result').text());

         }



still alert null

Help help help!

Hi,

:D may be I found the way to fix this problem

Still in the above case

When the update button is setup to use for ajax function, in the javascript area, you can try:




$('.update').click(function(){

//get the current row at column 2, same row with the update button (cause the second column content id

        var id = $(this).parent().parent().children(':nth-child(2)').text();

        $.ajax({

            url: '/QuanLyTour/congty/quickupdate',

            type: "POST",

            dataType: '[b]html[/b]',

            success: function(result){

                var val = $(result).text();

                alert(val);

            },

            error: function(){

                alert("error");

            }

        });

        return false;

    });



In controller action code, in my case is: actionQuickUpdate() (hust demo the simple way to get back data form server):




public function actionQuickUpdate()

{

   [b]echo  [/b]"<div class='result' id='result'>ok, you success</div>";

}



Note: In controller action, particular actionQuickUpdate function must use “echo” value, if you use “return” keyword, you won’t get the alert data form server.

In JQuery-Ajax documentation descript the "dataType" option:

I think it not enough clearly, with me, i think this is the server return data, so, i just return in my controller, but correctly we shout print out the data that we want to return to client.

I just sharing my exp, so, hope every member can exchange together :D

Thanks

Hi there,

Here my two cents:

Consider reviewing the code of CButtonColumn which is responsible of your button actions. You will see that this class has a buttons() property array. In there you can seet a button this way:




'buttonID' => array( // button id: 'view', 'delete', 'update' (forget about delete on ajax, it does it automatically check its code flow)

'label'=>'...',     // text label of the button

 'url'=>'...',       // a PHP expression for generating the URL of the button

 'imageUrl'=>'...',  // image URL of the button. If not set or false, a text link is used

 'options'=>array(...), // HTML options for the button tag

 'click'=>'...',     // a JS function to be invoked when the button is clicked

 'visible'=>'...',   // a PHP expression for determining whether the button is visible



Lets concentrate on the click option for the update and set it up on your code




array(

                'class' => 'CButtonColumn',

                'header' => 'Actions',

                'template' => '{update}',

                'updateButtonUrl' => '"#"',

                'updateButtonOptions' => array(

                      'class' => 'update',                    

                ),

               'buttons'=>array('update'=>array('click'=>'doAjaxCall();')),

            ),



See what we have done? I have set the click event for the button and told him to call the doAjaxCall();

Aftewards make sure you have created a doAjaxCall() function on your code:





function doAjaxCall(){

        var id = $(this).parent().parent().children(':nth-child(2)').text();

        $.ajax({

            url: '/QuanLyTour/congty/quickUpdate/',

            type: "POST",

            dataType: 'xml',

            success: function(xml){

                if($(xml).find("jobs")){

//                    alert($(xml).find("result").text());

                    alert("suuccess");

                    alert($(xml).find("job").text());


                }                            

            },

            error: function(){

                alert("error");

            }

        });

        return false;

    }



tell me if it works my friend…[s] also, it could be good that the button javascript knows the ID value of the element right? That could be accomplished by getting the HREF attribute of the element clicked:

on doAjaxCall():

url = $(this).attr(‘href’);[/s] ( you have set it up by a hash and also you already know how to get its id)

Totally untested…

Cheers

By the way, have you checked the internal code:




protected function registerClientScript()

	{

		$js=array();

		foreach($this->buttons as $id=>$button)

		{

			if(isset($button['click']))

			{

				$function=CJavaScript::encode($button['click']);

				$class=preg_replace('/\s+/','.',$button['options']['class']);

				$js[]="jQuery('#{$this->grid->id} a.{$class}').live('click',$function);";

			}

		}


		if($js!==array())

			Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$this->id, implode("\n",$js));

	}



The above means that jQuery(’#{$this->grid->id} a.update’).live(‘click’,$function);"; will be executed…

Thanks for reply :D

I’d tried “click” option in CButtonColumn like your wrote before, but it isn’t work! Finally, I think, becasue client request server return back is “xml” type, so the actionQuickUpdate function in controller can not return back the data type to client although the server return xml data:




public function actionQuickUpdate()

    {   

//      $value = "header('Content-type: application/xhtml-xml')";

//      $value = "header('Content-type: text/xml')";

        $value .= "<?xml version=\"1.0\"?>";

        $value .= "<root><jobs><job>Done</job></jobs>";

        $value .= "</root>";

        echo  $value;

    }



Anyway, this code not work, because when I test this action in IE, the quickupdate return a xml data tree, but with Firefox, just display text only, and when i view page info, this page in format text/html. That’s reason I choose the “dataType: ‘html’” for return in server.

Anyway, thanks for reading and sharing exp in Yii.

Again, thanks and lucky

I have not tested this but you can try to set the datatype to xml like:


header("Content-Type: text/xml" );

What doesnt work? server response or ajax call?

Check the XHR of Firebug or Chrome console and let us know :) Interesting issue.

Cheers

Ok, finally, it work! :lol:

In my action, i wrote:




public function actionQuickUpdate()

{

        header('Content-Type: text/xml');

        $value .= "<?xml version=\"1.0\"?>";

        $value .= "<root><jobs><job>Done</job></jobs>";

        $value .= "</root>";

        echo  $value;

}



And in ajax query:




$.ajax({

            url: '/QuanLyTour/congty/quickupdate',

            type: "POST",

            data: {ma_ct: id, page: 1},

            dataType: '[b]xml[/b]',

            contentType: 'application/x-www-form-urlencoded',

            success: function(result){

                    if($(result).find("jobs"))

                        alert($(result).find("job").text())

                    else

                        alert("No note can be found");

            },

            error: function(){

                alert("error");

            }

        });



After that, when i click “update” button, it alert to me “Done” ;D Thanks for helped and suggested.

But, I’m still want to make this function become logic, that mean, the actionQuickUpdate in controller uses to update record in gridview. So when if the quickUpdate execute update record, it will return to client an xml document, but the gridview record still hold the old data, when i refresh, the new record updated. is there has anyway to solve this :D

Thanks

Hi everybady,

Me again ::)

I facing a problem with display number of records in cgridview. In cgridview, there are provided the "$row" variable, so, I use this to display the number of the records in grid. For example, I display the first column with following code in cgridview:




            array(

                'type' => 'raw',

                'value' => '$row+1',

                'visible' => TRUE,

                'htmlOptions' => array(

                    'style' => 'width: 25px; text-align:center'

                )

            ),



It work! It display in the first column from 1 to 12 (12 is the page size that was setted in controller). But when I click to the second page, the number of records start from 1 to 12. In my case, i want they continue increase count the records. How can I do it? Any idea :)

NOTE: for a different problem it’s better to open a new topic so that more users can find that question and answer

As for the row problem… check this post - http://www.yiiframework.com/forum/index.php?/topic/7912-show-number-list-and-set-value-in-cgridview/page__view__findpost__p__46403

Sory :mellow: I’ll take note, Thanks