Yii (re)render scripts after rendering an iframe

[Rewrite of a Stack Overflow question. My first forum post so I can’t use embedded links]

The default entry point into a controller renders a layout with a sidebar that contains an autocomplete widget and a $content section. The autocomplete widget is a rip (see blog) and inside the run method the JQuery autocomplete is method chained to adjust how results are displayed.

There is an action on the controller that renders a view that has an iframe (with an href to another site). When that view is rendered the JavaScript registered by the autocomplete extension is gone. Traced the output of the render call and it is not present. However, the script is still registered.

Tried to override the afterRender method and when the view in question was rendered do something like:


Yii::app()->getClientScript()-render(&$output);

which does append the Javascript. Unfortunately, the Javascript is still missing.

Put a trace at the beginning and the end of the widget’s run method. Seeing a trace when the normal entry point is rendered as well when the view with the iframe is rendered. So the widget is getting run correctly.

Removing the iframe element eliminates the problem from the view that looks like:




<?php

/* @var $this AvhsController */


$this->breadcrumbs = array(

    __('Video') => array('/video'),

    __('View') . ' (' . $this->selectedSiteGroupName() . ' / ' . $model->name . ')',

);

?>

<iframe class="fullwidth" src="<?php echo $url; ?>"/>



Can’t move the script in question to the head since Yii places the jquery-ui at the end of the body. Any way to adjust where Yii puts core scripts?

Yes.

Ended up overriding the CWidget’s registerScriptFile method:




protected function registerScriptFile($fileName,$position=CClientScript::POS_END)

{

  parent::registerScriptFile($fileName, CClientScript::POS_HEAD);

}



This bumps the jquery-ui up to the header. Then when registering my script the POS_LOAD or POS_READY can’t be used since these are inserted at the end of the body. So I wrapped my script inside a JQuery on load event in POS_HEAD:




$js = "jQuery('#{$id}').autocomplete($options){$this->methodChain};";

$onLoad = "jQuery(window).on('load',function() {\n".$js."\n});";


$cs = Yii::app()->getClientScript();

$cs->registerScript(

  __CLASS__.'#'.$id, 

  $onLoad,

  CClientScript::POS_HEAD

);



Would still love somebody to weigh in on why an iframe effects stuff outside it’s tag?

Seem you’re on Yii 1.1. Moved topic to appropriate forum…