Yii Framework Forum: Ajax / Registerclientscript - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Ajax / Registerclientscript Rate Topic: -----

#1 User is offline   Joblo 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 578
  • Joined: 12-September 10
  • Location:Austria

Posted 26 November 2012 - 06:36 AM

I often have problems with widgets/js-code inside a ajax-environment (pager in CListView ...).

The problem is, that the (most of all) widgets use 'clientScript->registerScript' to publish the js-code.
But this will not work in a ajax-response and the script will not be executed.
And (perhaps?) globally registered jQuery functions cannot be used in the ajax response (needs more investigation...).
Also the CHtml::clientChange uses 'registerScript' and I have sometimes problems with that.

The problem is similar to renderPartial, with processOutput=false.
If I work with my own ajax-response controllerAction, this is no problem, but the problem are the widget extensions.

In most cases I can override the widgets registerClientScript method like below and it works:

class MyAjaxReadyWidget extends SomeWidget
{
    public $directOutput = null; //= autoMode: check for ajax


    public function init() 
    {
        if($this->directOutput == null)
            $this->directOutput=Yii::app()->request->isAjaxRequest; 

        parent::init();
    }

    public function registerClientScript()
    {
        if($this->directOutput)
        {
           $jsScript = ... nearly the same as in the parent ...
           echo CHtml::script($jsScript );
        }
        else
            parent::registerClientScript();
    }




Am I missing another solution for that problem?


I would like to see a workaround for this problem in the core.

1. place libraries/functions in the main view (jQuery,....) that can be used in the ajax-response.
2. a 'directOutput' feature in the core CWidget that processes the js-code immediatly in the run() method.

Maybe it should be possible to 'register' scripts in the ClientScript for 'directOutput' too, not only the current 'registerScript'.
0

#2 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 26 November 2012 - 11:52 AM

View PostJoblo, on 26 November 2012 - 06:36 AM, said:

The problem is, that the (most of all) widgets use 'clientScript->registerScript' to publish the js-code.
But this will not work in a ajax-response and the script will not be executed.
And (perhaps?) globally registered jQuery functions cannot be used in the ajax response (needs more investigation...).



Indeed. Registered scripts are rendered when the whole page renders. Since with AJAX you're modifiying just a little piece of HTML, even if your AJAX response has <script> tags on it, the browser won't execute them and they won't be rendered.


View PostJoblo, on 26 November 2012 - 06:36 AM, said:

1. place libraries/functions in the main view (jQuery,....) that can be used in the ajax-response.
2. a 'directOutput' feature in the core CWidget that processes the js-code immediatly in the run() method.

Maybe it should be possible to 'register' scripts in the ClientScript for 'directOutput' too, not only the current 'registerScript'.



The first solution is what I use, but the second would be preferred.
Ah! on-off, simplement!
0

#3 User is offline   Joblo 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 578
  • Joined: 12-September 10
  • Location:Austria

Posted 26 November 2012 - 01:49 PM

Maybe a possible solution could be to add methods to the base CWidget class like

- registerScript($script)
- registerScriptFile($scriptFile)


class CWidget extends extends CBaseController
{
    public $directOutput = false;

    public function registerScriptFile(script) 
    {
       if ($this->directOutput)
         echo CHtml::scriptFile($script); 
       else
          Yii::app()->getClientScript()->registerScriptFile(script);
    }    




and the widget can add the scripts in the init() or run() method like
  public function init() //or run()
  {
    ...
    $this->registerCoreScript('jquery');
    $this->registerScriptFile($assets.'fancybox.js');
    ... 

  }



Mabe a similar solution can be added to CClientScript ...

I'm currently working on a fancybox widget that should work inside a CListView - not only on the first page.
And it works now with 'directOutput'=>true :-)

Coming soon as addon to my 'quickdlgs' extension.
0

#4 User is offline   Joblo 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 578
  • Joined: 12-September 10
  • Location:Austria

Posted 27 November 2012 - 06:52 AM

I don't want to stop the discussion here, because in my opinion this is a unsolved problem of the Yii core.

It's a general problem, that widgets / core-widgets cannot be used together with a CListView.

Will this be solved in Yii 2.0 ?

Copy/Paste example:

Try to use CJuiDialog inside a CListView

$items = array();
$items[] = array('id'=>1,'content'=>'Item 1');
$items[] = array('id'=>2,'content'=>'Item 2');
$items[] = array('id'=>3,'content'=>'Item 3');
$items[] = array('id'=>4,'content'=>'Item 4');
$items[] = array('id'=>5,'content'=>'Item 5');

$dataProvider = new CArrayDataProvider($items, array(
    'keyField'=>'id',
    'pagination'=>array(
        'pageSize'=>2,
    ),
));


$this->widget('zii.widgets.CListView', array(
    'dataProvider'=>$dataProvider,
    'itemView'=>'_detail',   // refers to the partial view named '_post'
));



_detail view:

<div>
<?php
$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
    'id'=>'mydialog'.$data['id'],
    // additional javascript options for the dialog plugin
    'options'=>array(
        'title'=>'Dialog box 1',
        'autoOpen'=>false,
    ),
));

echo $data['content'];

$this->endWidget();

// the link that may open the dialog
echo CHtml::link('open dialog', '#', array(
    'onclick'=>'$("#mydialog'.$data['id'].'").dialog("open"); return false;',
));
?>
</div>


This only will work on the first page ...

I have tried to solve the problem with the fancybox addon in the extension quickdlgs 2.0.

It work's but I don't like this 'hack' ... :-(
0

#5 User is offline   yJeroen 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 94
  • Joined: 06-September 11
  • Location:The Netherlands

Posted 18 December 2012 - 02:29 PM

I don't get your problem..

Why not use a renderPartial('_view', array('model'=>$model), false, true) ?
0

#6 User is offline   Joblo 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 578
  • Joined: 12-September 10
  • Location:Austria

Posted 22 December 2012 - 12:24 PM

Where to use renderPartial in the example above?
0

#7 User is offline   Imre 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 30-March 11

Posted 13 April 2013 - 03:10 AM

View PostyJeroen, on 18 December 2012 - 02:29 PM, said:

Why not use a renderPartial('_view', array('model'=>$model), false, true) ?


this will not run dialog initialisation when inserted with ajax.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users