How to create alert notifications and modals

This is a community-contributed tutorial. This tutorial is over a year old and may not apply to your version of Concrete CMS.
Oct 24, 2017

Concrete CMS v8 provides multiple methods for creating dialog modals, confirm modals, and notifications.

The dialog() and confirm() methods are concrete wrappers for jQuery UI. The concrete notifications use PNotify.js and can be created using the ConcreteAlert JavaScript object, the PNotify JavaScript object, and the PHP UserInterface service (helper/concrete/ui).

The ConcreteAlert object is created in alert.js and is combined with PNotify and other scripts as app.js (concrete/js/app.js). When logged in, app.js is loaded by the concrete interface, with the script added near the closing body tag. To make sure app.js has been loaded before using it, use jQuery .ready(), or a similar method, to make sure ConcreteAlert and PNotify are available. When using the UserInterface service notify() method, it will return a script tag with a PNotify object and options wrapped in a jQuery .ready() shorthand method.

Translatable strings in JavaScript should be wrapped in json_encode() and t() and t() in PHP. The json_encode() method will escape quotes and t() is used for core translation.

PNotify
https://github.com/sciactive/pnotify

The full list of PNotify options can be found here (some options are only available when using PNotify directly or the UserInterface service).
https://github.com/sciactive/pnotify/blob/v3.2/README.md#configuration-defaults--options

Dialog Modals

dialog()

dialog(title, message, onCloseFn)
concrete/js/build/core/app/alert.js

  • title - the title for the dialog modal
  • message - the dialog modal message (plain text or HTML)
  • onCloseFn - an optional inline function or named function, called when the dialog modal is closed

Example:

ConcreteAlert.dialog(
    <?php echo json_encode(t('My Dialog Modal Title')); ?>,
    <?php echo json_encode(t('My dialog modal message.')); ?>
);

Example: inline on close function

ConcreteAlert.dialog(
    <?php echo json_encode(t('My Dialog Modal Title')); ?>,
    <?php echo json_encode(t('My dialog modal message.')); ?>,
    function() {
        // do this when the modal is closed
    }
);

Example: named on close function

function myOnCloseFunction() {
    // do this when the modal is closed
}
ConcreteAlert.dialog(
    <?php echo json_encode(t('My Dialog Modal Title')); ?>,
    <?php echo json_encode(t('My dialog modal message.')); ?>,
    myOnCloseFunction
);

Confirm Modals

confirm()

confirm(message, onConfirmation, btnClass, btnText)
concrete/js/build/core/app/alert.js

  • message - the confirm modal message (plain text or HTML)
  • onConfirmation - an inline function or named function, called when the modal confirm button is clicked
  • btnClass - the confirmation button class (the default class is "btn-primary")
    • available Bootstrap 3 button classes
      • btn-default
      • btn-primary
      • btn-success
      • btn-info
      • btn-warning
      • btn-danger
  • btnText - the confirmation button text (the default button text is "Go")

Example: inline on close function

ConcreteAlert.confirm(
    <?php echo json_encode(t('My confirm message.')); ?>,
    function() {
        // do this when the modal is confirmed
    }
);

Example: named on close function

function myOnConfirmationFunction() {
    // do this when the modal is confirmed
}
ConcreteAlert.confirm(
    <?php echo json_encode(t('My confirm message.')); ?>,
    myOnConfirmationFunction
);

Example: button class

function myOnConfirmationFunction() {
    // do this when the modal is confirmed
}
ConcreteAlert.confirm(
    <?php echo json_encode(t('My confirm message.')); ?>,
    myOnConfirmationFunction,
    'btn-warning'
);

Example: button class and button text

function myOnConfirmationFunction() {
    // do this when the modal is confirmed
}
ConcreteAlert.confirm(
    <?php echo json_encode(t('My confirm message.')); ?>,
    myOnConfirmationFunction,
    'btn-danger',
    <?php echo json_encode(t('Delete')); ?>
);

Please note Confirm Modals are only available from concrete 8.3.x

How to use Confirm Modals

When using normal browser confirm message, the browser takes care of preventing any action until a choice has been made in the confirm message, either accept or cancel.

With these custom Confirm Modals, we have to take care of everything ourselves.

Typically you will have 2 different situations, either the link or button you click on has an action attached to it or it doesn't.

Let's first deal with the first situation: the element does have an action attached to it.

For instance, a link can have a URL set as it's HREF attribute, a button can submit a form. So the first thing we must do before calling our modal is to prevent the default action from happening.

Let's say my link or button has a class name of action and I want to open my modal on click. Using the preceding examples we would modify them as follow:

function myOnCloseFunction() {
    // do this when the modal is confirmed
}

$('.action').on('click', function(event) {
    event.preventDefault();

    ConcreteAlert.dialog(
        <?php echo json_encode(t('My Dialog Modal Title')); ?>,
        <?php echo json_encode(t('My dialog modal message.')); ?>,
        myOnCloseFunction
    );
});

Having done so we will show the confirm message without triggering the default link or button's action.

If the user clicks the cancel button we have nothing more to do. We already cancelled the default action, nothing is going to happen other than the Confirm Modal closing.

If, however, the user clicks the OK button and confirms the action we now need to trigger the default action we previously cancelled. It's time to use our custom myOnCloseFunction()

Let's modify the code once again:

function myOnCloseFunction(button) {
    // do this when the modal is confirmed
    button.unbind('click').click();
}

$('.action').on('click', function(event) {
var button = $(this);        
event.preventDefault();

    ConcreteAlert.dialog(
        <?php echo json_encode(t('My Dialog Modal Title')); ?>,
        <?php echo json_encode(t('My dialog modal message.')); ?>,
        myOnCloseFunction(button)
    );
});

First, on click, we grab the current button in a variable. I called it button you can call it anything. Then we modify our custom functin to accept a parameter because we will send it our button to work with. Our function now looks like this myOnCloseFunction(button)

Finally, in our function we have 2 tasks: first we use unbind() to remove the previous click action attached to the button. Because we used event.preventDefault() on the button when setting our click action, we can't count on that button to trigger any action anymore so we cancel that.

Then we trigger a click on the button by calling the very aptly named click() function on it so it will do what it was supposed to do all along.

And we're done with this one.

Now let us deal with the situation where the button or link didn't have any action attached to it. Maybe that link or button was mean to be used through Javascript all along and is used purely as a trigger.

Here the idea is the same as in the previous situation with 2 differences: we do not have a default action to prevent since there's no action at all and we do not have an action to trigger once the user confirms their choice.

The solution is to use a redirect if it's a link or manually submit the form if it's a form we're dealing with.

I'll let you look at triggering a form submit on your own, it's not complicated to figure out.

I'm going to focus on redirection and look at the possible scenarii: through JavaScript or through PHP.

If your script is in a JS file you will have no choice but to redirect through JS. One drawback of that situation is your link better be static.

More often than not, however, our link will be dynamic with parameters sent from PHP (a file ID for instance) and that would complicate things. In that case you'll have to devise a way to make your script aware of those parameters.

The way concrete deals with this is to set the whole URL as an attribute on the triggering element (generated through PHP) so the script can grab it easily. For instance:

<button data-action="http://mysite.com/myaction?fID=3">

All the JS needs to do is to grab that data-action value and redirect to it to achieve the desired result.

Redirecting in JS can be done easily:

function myOnCloseFunction(button) {
    // do this when the modal is confirmed
    window.location.href = button.attr('data-action');
}

I know treating a data attribute as a simple attribute instead of a data store is not best but it ensure maximum compatibility with all kinds of browsers so just humour me on this one.

Now if your JS code is hard-coded in a PHP file, you can simplify things. Just remove references to our button since we won't need them anymore:

function myOnCloseFunction() {
    // do this when the modal is confirmed
    window.location.href = "<?php \URL::to('/path/to/action', 'oneparameter', 'anotherparameter') ?>";
}

$('.action').on('click', function(event) {     
event.preventDefault();

    ConcreteAlert.dialog(
        <?php echo json_encode(t('My Dialog Modal Title')); ?>,
        <?php echo json_encode(t('My dialog modal message.')); ?>,
        myOnCloseFunction()
    );
});

Notifications

info()

info(defaults)
concrete/js/build/core/app/alert.js

  • defaults
    • type - info
    • icon - Font Awesome question icon minus the "fa-" prefix
  • title - the notification title (plain text or HTML) displayed as an h4 element
  • message - the notification message (plain text or HTML)

Example:

ConcreteAlert.info({
    title: <?php echo json_encode(t('My Notification Title')); ?>,
    message: <?php echo json_encode(t('My notification message.')); ?>
});

error()

error(defaults)
concrete/js/build/core/app/alert.js

  • defaults
    • type - error
    • icon - Font Awesome exclamation-circle icon minus the "fa-" prefix
  • title - the notification title (plain text or HTML) displayed as an h4 element
  • message - the notification message (plain text or HTML)

Example:

ConcreteAlert.error({
    title: <?php echo json_encode(t('My Notification Title')); ?>,
    message: <?php echo json_encode(t('My notification message.')); ?>
});

notify()

notify(defaults)
concrete/js/build/core/app/alert.js

  • defaults
    • type - success
    • icon - Font Awesome check icon minus the "fa-" prefix
    • delay - 2000 (milliseconds)
  • title - the notification title (plain text or HTML) displayed as an h4 element
  • message - the notification message (plain text or HTML)
  • callback - an optional inline function or named function, called when the notification is closed or hidden after a delay

Example:

ConcreteAlert.notify({
    title: <?php echo json_encode(t('My Notification Title')); ?>,
    message: <?php echo json_encode(t('My notification message.')); ?>
});

Example: inline function callback

ConcreteAlert.notify({
    title: <?php echo json_encode(t('My Notification Title')); ?>,
    message: <?php echo json_encode(t('My notification message.')); ?>,
    callback: function() {
        // do this when the notification is closed or hidden
    }
});

Example: named function callback

function myNotificationCallbackFunction() {
    // do this when the notification is closed or hidden
}
ConcreteAlert.notify({
    title: <?php echo json_encode(t('My Notification Title')); ?>,
    message: <?php echo json_encode(t('My notification message.')); ?>,
    callback: myNotificationCallbackFunction
});

Example: type, icon, title, message, and hide options

ConcreteAlert.notify({
   type: 'info',
   icon: 'internet-explorer',
   title: <?php echo json_encode(t('Old Browser Alert')); ?>,
   message: <?php echo json_encode(t('Ewwww you are using an old version of Internet Explorer!')); ?>,
   hide: false
});

Using PNotify Directly

PNotify()

Example:

new PNotify({
    type: 'success',
    icon: 'fa fa-thumbs-up',
    title: <?php echo json_encode(t('Page Errors')); ?>,
    text: <?php echo json_encode(t('Your page has no errors.')); ?>,
    hide: false
});

UserInterface "helper/concrete/ui" Service

notify()

notify($arguments)
concrete/src/Application/Service/UserInterface.php

  • defaults
    • type - success
    • icon - fa fa-check-mark
    • hide - false
    • addclass - ccm-notification-page-alert
    • form - false
  • title - the notification title (plain text or HTML) displayed as an h4 element
  • text - the notification message (plain text or HTML)
  • buttons - an optional array() of one or more notification buttons

Example:

echo Core::make('helper/concrete/ui')->notify(
    [
        'type' => 'error',
        'icon' => 'fa fa-user',
        'title' => t('Editor Permissions Disabled'),
        'text' => t('Please contact the site administrator.')
    ]
);

Example: display a notification with a button

echo Core::make('helper/concrete/ui')->notify(
    [
        'type' => 'info',
        'icon' => 'fa fa-question',
        'title' => t('Member Survey'),
        'text' => t('Please take a moment to fill out the yearly member survey.'),
        'buttons' => [
            sprintf('<a href="%s" class="btn btn-primary">%s</a>', \URL::to('/survey'), t('Click Here'))
        ]
    ]
);

Example: display a notification with two buttons

echo Core::make('helper/concrete/ui')->notify(
    [
        'type' => 'info',
        'icon' => 'fa fa-hourglass',
        'title' => t('Site Task Reminder'),
        'text' => t('You have site task maintenance to perform.'),
        'buttons' => [
            sprintf('<a href="%s">%s</a>', \URL::to('/go-to-tasks'), t('Go to tasks')),
            sprintf('<a href="%s">%s</a>', \URL::to('/remind-me-later'), t('Remind me later'))
        ]
    ]
);
Recent Tutorials
Setting addon/theme version compatibility in the marketplace
Jan 9, 2024

For developers worn out with setting the latest addon or theme version manually across too many core versions, here is a JavaScript bookmarklet to do it for you.

How to get the locale of a page
Jan 8, 2024
By mandako.

Now, why don't we just have a getLocale() method on Page objects beats me, but here's how you work around it

Using a Redis Server
Jun 16, 2023
By mlocati.

How to configure Concrete to use one or more Redis servers to persist the cache.

Using the Concrete Migration Tool Addon
Apr 27, 2023

How to use the Concrete CMS Migration Tool

How To Add Page Last Updated To Your Concrete CMS Pages
Mar 7, 2023

Concrete CMS has a page attribute you can add to a global area called "Page Date Modified." Here's how to add it

How To Exclude Subpages from Navigation
Dec 24, 2022

How to exclude subpages from navigation - useful for a news or blog link in your main navigation where you don't want all the subpages to appear in a drop down menu.

Improvements?

Let us know by posting here.