Independent Widget

Hi

I develop a widget that will be used as extension

This widget will be manipulates $_POST and $_GET parameters

So, whats is the best practice ?

passing _POST and _GET as widget parameters or directly into the run() function ?

The CGridView has a same functionallity when click on sortable column, I want something like that.

All suggestions are welcome! :)

Thanks!

I suspect that CGridView access the $_GET array directly. You could include public attributes within the widget to allow overriding of the request parameter names, then just retrieve those parameters directly within the widget, such as:




    $value = Yii::app()->request->getQuery($this->paramName);



Hi Keith, thanks for your response

Yes I already tried something similar


$value = Yii::app()->request->getQuery('paramName',$this->paramName);

Somewhere read that widget could be use like controller (widgets are kind of controller)

Another problem I found, widgets has no renderPartial since display a part of html

but how to manipulate it on ajax request?

I try that and works


public function actionTest() {


        if (!Yii::app()->request->isAjaxRequest) {

            $this->render('indexWithmyWidget');

        } else {

            $this->widget('mywidget');

        }

}


//and in indexWithmyWidget.php

$this->widget('mywidget');

But it is not seems very robust technique…

what is your opinion?

I’m not sure if I’m fully understanding, but you could do this:




    $this->renderText($this->widget('mywidget', array(), true));



to render the widget without making an extra view file.

What is your widget for exactly?

I need on the first (no-ajax) request to load some css and javascript file,

these files are loaded in run() method of the widget by


Yii::app()->getClientScript()->registerScriptFile

Yii::app()->getClientScript()->registerCssFile

So renderText not works correctly in this case

I make a photo gallery with a custom pagination and a search that works both of normal http and AJAX request.

Also the only required data that I want are the images url (as array)

I’d look at the implementation of CGridView and CListView to see how the Yii devs do it. They seem to handle similar constraints.

According to

and

http://www.yiiframework.com/wiki/520/how-to-avoid-rendering-entire-page-on-ajax-call-for-cgridview-and-clistview/

We have to check if the request is AJAX or not!

My widget take entire ajax response and replace the div region with new one, so if the response is the entire html all javascript on client side corrupted by duplicates javascript code (and html)


 $.post("", $(this).serialize(), function(data) {

            $("#my-block").html($(data).html());

        })

I don’t know how exactly works the CGridView ( I assume get a part of ajax response and replace the cgridview html with new one) but in my case I have to check whether is Ajax request.

If rendering is seperated according to type of the request then evertything works ok,

But I am curious how The CGridview works in this case

without this checking

As far as I know, CGridView and CListView are fairly straightforward in the server side.

They don’t check if the request is an ajax or not. They just register the necessary scripts and render the content.

When they are rendered in render, the scripts will be output, but when they are rendered in renderPartial, the scripts will not be output. Calling render or renderPartial is up to the user. By checking if the request is an ajax, you may optimize the output by using renderPartial. Although, such a lazy programmer as I can still use render for the response to an ajax request, because in the client side they are clever enough to get only the necessary part from the whole response.

The following is from ‘jquery.yiigridview.js’ … from line 234 and on:




		update: function (options) {

			...

					success: function (data) {

						var $data = $('<div>' + data + '</div>');

						$grid.removeClass(settings.loadingClass);

						$.each(settings.ajaxUpdate, function (i, el) {

							var updateId = '#' + el;

							$(updateId).replaceWith($(updateId, $data));

						});



The key point here is "$(updateId).replaceWith($(updateId, $data));" which usually replaces only the grid content with the counter part in the response.

Thanks Keith and SoftArk!

Softark, after over two years experience on Yii, Ι realized that ajax-links of CGridView fetch the entire html response

and replace the cgridview html picking the appropriate part of html (the new one of cgridview with specific id)

It was to obvious! The same controller/action is called again and outputs the same html structure!

So the CGridView does not check whether the request is AJAX type.

You can update not only the grid itself but also some other elements in the page in a single ajax call, by specifying the extra elements in ‘ajaxUpdate’ property. This is sometimes very convenient. It could have been difficult to implement without the basic schema stated above.

Obviously is very useful!

but how to specify extra elements in ‘ajaxUpdate’ property ? like that ?


'ajaxUpdate'=>array('grid-id','another-id','another-id2',...)

Thanks!

Use a string consists of ids separated with comma.




'ajaxUpdate'=>'another-id, another-id2, another-idn',



Ids should be without ‘#’ attached. And, it’s not documented, but I had to exclude the id of the grid itself.

Thanks softark

It works perfectly :)