October CMS resources and help articles

Simple and to the point. Optimized by the community.

Create dynamic ajax popup in the frontend

13
by algoriq, last modified on August 12th, 2019

Creating a modal popup is very easy with Bootstrap. As best practises, you should use on sites about 1-2 modal windows at most inside the body tag. But what to do if you need more modal popups and those should be dynamically in the best case?

In this tutorial, we show you how you to implement dynamic modal windows with Ajax in October CMS. Before you can create the modal popup using the Bootstrap Framework, the Bootstrap and jQuery library need to included those in your layout htm file.

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
{% framework extras %}
{% scripts %}
  1. Create a new component, for example, we name it: AjaxPopup:
php artisan create:component Algoriq.Backpack AjaxPopup
  1. Then we write our function to call our popup window partial:

    public function onLoadPopupForm()
    {
        return [
            'popup' => $this->renderPartial('@popup.htm')
        ];
    }
  2. Bootstrap Modal Button. The following example creates a button. This button (openBtn) triggers the ajax process to show the modal popup window, we will write it in the default.htm component template.

<a href="nojavascript...;" class="btn btn-primary" data-show-popup>Show popup</a>
  1. Bootstrap Modal Popup. As next step we will create a new modal popup window template and call it popup.htm in same directory where the default.htm is and put the following code inside this file:
<div class="modal fade" id="ajaxPopupForm" tabindex="-1" role="dialog" aria-labelledby="ajaxPopupFormLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="ajaxPopupFormLabel">Ajax Popup</h5>
                <button
                    type="button"
                    class="close"
                    data-dismiss="modal"
                    data-disable-on-ajax-start
                    data-enable-on-ajax-always
                    aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">
                ...
            </div>
            <div class="modal-footer">
                <button
                    type="button"
                    class="btn btn-secondary"
                    data-dismiss="modal"
                    data-disable-on-ajax-start
                    data-enable-on-ajax-always>
                    Close
                </button>
                <button
                    type="submit"
                    class="btn btn-primary"
                    data-disable-on-ajax-start
                    data-enable-on-ajax-always>
                    Save changes
                </button>
            </div>
        </div>
    </div>
</div>
  1. After we have created a button and our modal template, we need to create an ajax handler to utilize our dynamic modal popups and a script where we can initialise this handler. So in the next step, we create two javascript asset files the first one we name it, for example, ajaxUtils.js and put the following code inside this file:
$(function() {
    "use strict";

    var ajaxUtils = function() {
        this.registerHandlers()
    };

    ajaxUtils.prototype.registerHandlers = function() {
        var requestSenderSelector = 'form, a[data-request], input[data-request], select[data-request]';
        $(document).on('ajaxPromise', requestSenderSelector, $.proxy(this.onFormAjaxInit));
        $(document).on('ajaxFail', requestSenderSelector, $.proxy(this.onFormAjaxFail));
        $(document).on('ajaxDone', requestSenderSelector, $.proxy(this.onFormAjaxSuccess));
        $(document).on('shown.bs.modal', 'div.modal', $.proxy(this.onModalDisplayed, this));
        $(document).on('hidden.bs.modal', 'div.modal', $.proxy(this.onModalHidden, this));
    };

    ajaxUtils.prototype.onFormAjaxInit = function(e) {
        var $form = $(e.currentTarget).closest('form');

        if ($(e.target).attr('data-no-ajax-disable-effects') !== undefined) {
            return
        }

        $form.find('[data-disable-on-ajax-start]').prop('disabled', true).attr('disabled', 'disabled')
    };

    ajaxUtils.prototype.onFormAjaxFail = function(e) {
        var $form = $(e.currentTarget).closest('form');

        $form.find('[data-enable-on-ajax-fail], [data-enable-on-ajax-always]').prop('disabled', false).removeAttr('disabled')
    };

    ajaxUtils.prototype.onFormAjaxSuccess = function(e) {
        var $form = $(e.currentTarget).closest('form');

        $form.find('[data-enable-on-ajax-success], [data-enable-on-ajax-always]').prop('disabled', false).removeAttr('disabled')
    };

    ajaxUtils.prototype.onModalDisplayed = function(e) {
        var $defaultFocus = $('[data-default-focus]', e.currentTarget);

        $defaultFocus.focus()
    };

    ajaxUtils.prototype.onModalHidden = function(e) {
        $(e.currentTarget).remove()
    };

    new ajaxUtils()

});
  1. Our second asset file with the name ajaxPopup.js should contain the following code:
$(function() {
    var PopupBuilder = function() {

        function init() {
            bindEventHandlers()
        }

        function bindEventHandlers() {
            $(document).on('click', 'a[data-show-popup]', onLoadAjaxPopup);
        }

        function onLoadAjaxPopup(e) {
            showAjaxPopup(e)
        }

        function showAjaxPopup(e) {

            $.oc.stripeLoadIndicator.show();

            $(e.currentTarget).request('onLoadPopupForm', {
                data: {},
                success: function(data) {
                    $(data.popup).modal({
                        backdrop: 'static',
                        keyboard: true
                    });
                }
            }).always(function() {
                $.oc.stripeLoadIndicator.hide();
            });

            e.preventDefault();

            return false
        }

        init()
    };

    new PopupBuilder()
});

Now you can place those files in your plugin assets folder for example (“assets/js/”) and initialize those assets scripts inside your plugin the following way:

    public function onRun()
    {
        $this->addJs('/plugins/algoriq/backpack/assets/js/ajaxUtils.js');
        $this->addJs('/plugins/algoriq/backpack/assets/js/ajaxPopup.js');
    }

Thank you for your attention I hope you enjoyed this tutorial.

However, if you have any suggestions or you probably see some room for improvements, then I would kindly ask you to drop me a line and I will get in touch with you as soon as possible!

Discussion

1 comment

1
minocodi
Post on August 29th, 2019 11:15 PM

thank you for this trick, i just want to know how i can change the title and the content of the modal dynamically

by sending data-title or data-page-url on

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