Winter CMS resources and help articles

Simple and to the point. Optimized by the community.

Loading a page in a popup

1
by DamsFX, last modified on April 21st, 2023

The purpose of this trick is to load a page (its content only) in a dialog window.

We will need three parts :

  • an Ajax handler to manage the page loading
  • a popup partial
  • some JavaScript to handle the dialog open/close

This tricks use Alpine JS to handle the dialog closing by clicking the cancel button or outside the dialog. You can easily replace @click attributes by vanilla JavaScript events.

Add Ajax handler to your layout

This handler will load a page of the site whose url will be given with a data-request-data attribute, and the push a partial refresh for the popup content.

function onLoadPopUp()
{
    $pageUrl = post('url');
    $content = '<h1>Nothing to load ...</h1>';
    $title = 'My Popup';

    if ($pageUrl) {
        $handlerController = new Cms\Classes\Controller;

        $router = new \Cms\Classes\Router(\Cms\Classes\Theme::getActiveTheme());
        $page = $router->findByUrl($pageUrl);
        $page->layout = null;

        // if the page loaded is a static page from Winter.Pages plugin 
        // and make use of placeholders and/or customs fields, 
        // then you need an "empty" layout repeating your defintions for thoses.
        // $page->layout = 'empty';

        $content = $handlerController->runPage($page, false);
        $title = $page->meta_title ?: $page->title;
    }

    $this['popupTitle'] = $title;
    $this['popupContent'] = $content;

    return [
        '#dialogContent' => $this->renderPartial('popup/_content')
    ];
}

Add popup's partials

The two partials defining the popup and its content.

? themes
 ┗ ? yourtheme
   ┗ ? partials
     ┗ ? popup
       ┃ ? _content.htm
       ┗ ? default.htm

1 - partials/popup/default.htm file :

<dialog id="dialog">
    <div class="dialog--container" id="dialogContent" @click.outside="closeDialog()">
    </div>
</dialog>

2 - partials/popup/_content.htm file :

<div class="dialog--headerbar">
    <span class="dialog--title">{{ popupTitle }}</span>
    <button class="btn--cancel" @click="closeDialog()" type="reset" aria-label="Cancel">
        Cancel
    </button>
</div>
<div class="dialog--content">
    {{ popupContent | raw }}
</div>

3 - In your layout, add :

{% partial 'popup/default' %}

Add some Javascript to show/hide the dialog popup in your theme's asset

These functions are intended to manage the display of an HTML <dialog> element.

window.openDialog = () => {
    document.querySelector('#dialog').showModal()
}
window.closeDialog = () => {
    document.querySelector('#dialog[open]').close()
}

Add the Ajax handler trigger

On a link or a button, allows the triggering of the Ajax handler and the opening of the dialog. In this example the page with the url /thepageurl will be loaded, it must be accessible to the site visitors.

<a class="..."
    data-request="onLoadPopUp"
    data-request-data="url: '/thepageurl'"
    data-request-success="openDialog()"
>Link text</a>

Discussion

0 comments

We use cookies to measure the performance of this website. Do you want to accept these cookies?