10

When I use normal return this->render('create', ['model' => $model]) my pop-up window goes all haywire. When I change to return $this->renderAjax('create', ['model' => $model]); everything is magically in their correct places. I have looked around quite a bit to read about renderAjax() but there seem to be absolutely nothing out there. Can someone tell me what it does? I know ajax but from what I know it usually has nothing to do with css or bootstrap.

Red Bottle
  • 2,839
  • 4
  • 22
  • 59

2 Answers2

20

To know the difference between render() and renderAjax() first you need to understand how render() works.

Basically when render() is called every piece of JS and CSS code and file references registered with the view is gathered in several arrays to be rendered later on in proper places - these places are stored in the layout and their code is rendered by calling beginPage(), head(), beginBody(), endBody() and endPage().

You can point where the JS code should be rendered by setting the second parameter in related methods - like for example:

$this->registerJs("alert()", \yii\web\View::POS_HEAD);

renders

<script type="text/javascript">alert()</script>

in layout where the method $this->head() is.

Everything is working fine until you want to render only a main part of view without the layout. Without it (and its methods like beginPage()) the JS and CSS references cannot be rendered in the previous way and that is why this fancy jQuery code rotating the square does not work - JS library has not been included there.

When you are calling $this->render() from within the view or just calling $this->renderPartial() from the controller exactly this is happening - layout is not applied.

renderAjax() comes now to the rescue.

This method doesn't care about layout because it calls beginPage(), head(), beginBody(), endBody() and endPage() methods by itself. Thanks to this every JS piece of code can be attached to the rendered view and the jQuery library can rotate this square once again even when it needs to be done inside an AJAX popup.

Bizley
  • 17,392
  • 5
  • 49
  • 59
  • 1
    I think the situation is not absolutely clear. I tried renderAjax with a view containing `registerAssetBundle`, but the registered JS file is not loaded in the ajax call. As I see, only embedded JS can be used. It would cuase a lot of problems if assets are loadad on ajax call, may be that some JS files would run more than one time. – Tibor Nagy Aug 10 '18 at 13:50
  • I totally agree with the above statement. I have issues that when using renderajax it's not applying the plugins document.ready function as that js has already been included on the initial page load and doesn't re-run. I need to find a way to trigger that JS function even though it's an IIFE (Immediately Invoked Function Expression). – Fi Horan Jul 09 '21 at 13:09
1

render() public method

Renders a view.

The view to be rendered can be specified in one of the following formats:

path alias (e.g. "@app/views/site/index"); absolute path within application (e.g. "//site/index"): the view name starts with double slashes. The actual view file will be looked for under the view path of the application. absolute path within current module (e.g. "/site/index"): the view name starts with a single slash. The actual view file will be looked for under the view path of the current module. relative view (e.g. "index"): the view name does not start with @ or /. The corresponding view file will be looked for under the view path of the view $context. If $context is not given, it will be looked for under the directory containing the view currently being rendered (i.e., this happens when rendering a view within another view).

renderAjax() public method

Renders a view in response to an AJAX request.

This method is similar to render() except that it will surround the view being rendered with the calls of beginPage(), head(), beginBody(), endBody() and endPage(). By doing so, the method is able to inject into the rendering result with JS/CSS scripts and files that are registered with the view.

renderAjax()

render()

Pritamkumar
  • 682
  • 1
  • 11
  • 30
Amitesh Kumar
  • 3,051
  • 1
  • 26
  • 42
  • "By doing so, the method is able to inject into the rendering result with JS/CSS scripts and files that are registered with the view." I'm still confused why everything else works fine apart from the UI elements being extra wide and a little out of place. If the JS is not "injected" it shouldn't work at all no? Upvoted though – Red Bottle Mar 27 '17 at 13:24
  • i Think render ajax adding some js or css in your code , just compare the classes adding or removing in both ajax and normal render. I think some classes is adding during renderajax call. you check using firebug. – Amitesh Kumar Mar 27 '17 at 13:29