alertify.js

# alertify.js

### Simple browser dialogs v1.0.11

file_download Download Now

Alertify.js is a small library which provides light-weight, high performance browser dialogs. Since it uses only 1 HTTP request and a payload of less than 3kB, it's a great option for adding basic style to alert, dialog, prompt and log messages even on low bandwidth connections.

## Getting Started

#### Notes

We're working to get the latest version on all major public CDN's but until then, you'll need to either use a GitHub raw service, download it, or install via NPM or Bower.

Obviously, if you're installing via Bower or NPM, you'll need to include the files in the "dist" directory in your HTML for everything to work. But you knew that already.

It's also worth noting that the CSS is bundled by default, so there's no need to include any stylesheets to use the default theme. It's dyamically inserted before any other <link> elements (like) stylesheets so it's super easy to override with your own styles.

#### Via RawGit

    <-- standard version -->
    <script src="https://cdn.rawgit.com/alertifyjs/alertify.js/v1.0.11/dist/js/alertify.js"></script>

    <-- angular module -->
    <script src="https://cdn.rawgit.com/alertifyjs/alertify.js/v1.0.11/dist/js/ngAlertify.js"></script>

#### Via Bower

    bower install --save alertifyjs

#### Via NPM

    npm install --save alertify.js

#### Disabling CSS Injection

If you don't want to inject CSS for some reason, just insert your own styles (any style or link element with an id of alertifyCSS) before the javascript file:

    <link rel="stylesheet"
          href="/path/to/custom/styles.css"
          id="alertifyCSS">
    <script src="/path/to/alertify.js"></script>

#### AngularJS

An AngularJS module is also included. It's in the "ngAlertify.js" file, so use that instead if you're building an AngularJS app.

If you want to check out a live demo of log messages with ngAlertify, click here.

#### Initialize ngAlertify

    // Make sure to include the ngAlertify.js file.
    angular
        .module("myApp", ["ngAlertify"])
        .controller("myController", function($scope, alertify) {
            alertify.success("Welcome to alertify!");
        });

## Performance

Alertify is designed from the ground-up for great performance and a small footprint. That means it's not as feature-rich as some other options. That's on purpose. We don't plan on adding a lot more features so it stays a great option for every kind of website and user.

Currently, the entire library, with JavaScript and CSS is ~2.29 kB (gzipped), and getting smaller all the time. That's quite impressive considering it's only a single HTTP request, and no external dependencies at all being required.

The Angular module is only 2.32kB, so that's light, too!

## Usage

### Dialogs

##### Alert Dialog

Dialogs display a text and require user to acknowledge the message. You can use click callback function as a second argument.

Try It

##### Code Example

    alertify
        .alert("This is an alert dialog", function (e, ui) {
            // you can handle click event here
            e.preventDefault();
        });

##### Confirm Dialog

Confirm and prompt dialogs have 2 callback functions for the each button.

Try It

##### Code Example

    alertify
        .confirm("This is a confirm dialog", function (e, ui) {
            alertify.success("You've clicked 'OK'");
        }, function (e, ui) {
            alertify.error("You've clicked 'Cancel'");
        });

##### Prompt Dialog

Use "ui.getInputValue()" method inside a click callback to retrieve the input value.

Try It

##### Code Example

    alertify
        .prompt("This is a prompt dialog", "Default value", function (e, ui) {
            // the value entered in the prompt input
            var inputValue = ui.getInputValue();

            alertify.success("You've clicked 'OK' and typed: " + inputValue);
        }, function (e, ui) {
            alertify.error("You've clicked 'Cancel'");
        });

##### Custom Button Labels

You're not limited to the "Ok" and "Cancel" button labels. You can easily set your own labels. For that purpose you have to use object instead of callback function for each button. Use "label" property to set custom labels and the callback function should be assigned to "click" property of the object.

Try It

##### Code Example

    alertify
        .confirm("Confirm dialog with custom button labels",
        {
            label: "Accept",
            click: function (e, ui) {
                e.preventDefault();
                alertify.success("You've clicked Accept");
            }
        },{
            label: "Deny",
            click: function (e, ui) {
                e.preventDefault();
                alertify.error("You've clicked Deny");
            }
        });

##### Persistent Buttons

If you don't need not to automatically close a dialog while clicking a button, you can set "autoClose" button object property to "false". You are able to close the dialog programmatically inside the "click" callback function with "ui.closeDialog()" method.

Try It

##### Code Example

    alertify
        .confirm("Confirm dialog with persistent buttons",
        {
            autoClose: false,
            click: function (e, ui) {
                e.preventDefault();
                alertify.success("This is the persistent button");
            }
        },{
            autoClose: false,
            click: function (e, ui) {
                e.preventDefault();
                if (true) {
                    // method to close currently open dialog
                    ui.closeDialog();
                }
                alertify.error("This is the persistent button, but it was closed programmatically");
            }
        });

##### Comprehensive dialog demo

The "alert", "confirm" and "prompt" dialogs are designed to imitate browser native modal windows, so they have a strictly limited number of buttons or specific elements, like input in prompt dialog.

With the "dialog" method it is possible to customize your dialog to your liking. The second argument accepts array of button objects, as:

- type - valid values: "ok", "cancel", "custom". Button with type "ok" or "cancel" behaves as a regular appropriate button in "confirm" dialog. You are able to change the button behavior with any of the option below.
- label - button label text, applies to an element with the "data-alertify-btn" attribute in the button template.
- autoClose - boolean value, defines whether the dialog will be closed upon the button click. By default "true" for "ok" and "cancel" button types, otherwise is "false".
- template - valid html string, replaces default button template. Button tag should be marked with "data-alertify-btn" attribute.
- click - callback function to fire after the button is clicked.

The "click" callback function are passed with "event" and "ui" attributes, where the "ui" is the reference to the dialog object, which provides the following methods and properties:

- closeDialog() - method to close dialog programmatically. Useful in case the "autoClose" button property is set to "false".
- centerDialog() - method to center dialog vertically. By default dialog centered on window resize, but if the content is changed you may have to center the dialog programmatically.
- getInputValue() - method to return the value of input field inside the "prompt" dialog. Returns "undefined" for other dialogs.
- setMessage(text) - method to update the message in general dialogs ("alert", "confirm", "prompt").
- setContent(html) - method to update the whole content in the dialog. Most appropriate for "dialog" dialog.
- getButtonObject() - method to return an object with data for the current button.
- dom - object which contains references to DOM elements of the dialog.

Try It

##### Code Example

    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function createInput(value) {
        return '<input type="radio" name="quiz" id="quiz_' + value + '" value="' + value + '"><label for="quiz_' + value + '">' + value + '</label>';
    }

    function buildQuiz(ui) {
        var min = 5;
        var max = 20;
        var html = "";
        var values = [];
        var numbers = [];
        var options = [];
        var solution = 0;
        var optionsLength = 3;
        var numbersLength = getRandomInt(2, 4);
        var scatter = Math.floor((min * numbersLength) / 2);

        for (var i = 0; i < numbersLength; i++) {
            var number = getRandomInt(min, max);
            numbers.push(number);
            solution += number;
        }

        while (values.length < optionsLength) {
            var value = getRandomInt(solution - scatter, solution + scatter);
            if(value !== solution && values.indexOf(value) === -1) {
                values.push(value);
            }
        }
        // put correct answer
        values.splice(getRandomInt(0, optionsLength - 1), 0, solution);

        for (var n = 0; n < values.length; n++) {
            options.push(createInput(values[n]));
        }

        html += numbers.join(' + ') + ' = ?';
        html += '<br><br>';
        html += options.join('<br>');

        ui.dom.content.innerHTML = html;
        ui.solution = solution;
    }

    alertify
        .dialog("Click New quiz to create new quiz.", [
        {
            type: "ok",
            label: "Test",
            autoClose: false,
            click: function (e, ui) {

                var dialog = ui.dom.dialog;
                var checked = dialog.querySelector('input[name="quiz"]:checked');

                if(checked === null) {
                    alertify.error("Choose an answer from the list");
                    buildQuiz(ui);
                } else {
                    if(ui.solution === parseInt(checked.value)) {
                        alertify.success("Correct answer!");
                        ui.closeDialog();
                    } else {
                        alertify.error("Wrong answer. Bad luck");
                        buildQuiz(ui);
                    }
                }
            }
        },{
            label: "New quiz",
            autoClose: false,
            click: function (e, ui) {
                buildQuiz(ui);
                ui.centerDialog();
            },
            template: '<button data-alertify-btn style="font-weight: bold"></button>'
        },{
            type: "cancel",
            label: "Close"
        }
    ]);

##### Ajax requests

"OK" button updates a message inside the open dialog.

"CLOSE" button shows result message in a new dialog. Multiple dialogs chain.

Try It

##### Code Example

    alertify
        .confirm("Ajax requests",
        {
            autoClose: false,
            click: function (e, ui) {
                e.preventDefault();

                // AJAX request delay imitation
                setTimeout(function () {

                    // updates message in the current dialog
                    ui.setMessage("Successful AJAX after OK. Without opening a new dialog.");

                    // center dialog vertically due to dialog height might be changed
                    ui.centerDialog();

                    alertify.log("Dialog message was updated using AJAX request.");
                }, 200);
            }
        },{
            click: function (e, ui) {
                e.preventDefault();

                // AJAX request delay imitation
                setTimeout(function () {

                    // notification in the new dialog window
                    alertify.alert("Successful AJAX after Cancel);
                }, 200);
            }
        });

##### Promise Aware

If your browser supports promises, you can use them instead of callbacks. The "resolved" is an object with the "event" and "ui" properties.

Try It

##### Code Example

    if ("function" !== typeof Promise) {
        alertify.alert("Your browser doesn't support promises");
        return;
    }

    alertify
        .confirm("Promise confirm").then(function (resolved) {
            // The click event object is accessible via "event" property.
            resolved.event.preventDefault();

            // UI object is accessible via "ui" property.
            alertify.alert("You clicked the " + resolved.ui.getButtonObject().label + " button!");
        });

### Log Messages

##### Standard Log

Try It

##### Code Example

    alertify.log("Standard log message");

##### Log types

Try out predefined different log types.

Success Log

Warning Log

Error Log

##### Code Example

    alertify.success("Success log message");

    alertify.warning("Warning log message");

    alertify.error("Error log message");

##### Log With HTML

HTML works just fine in log messages. Have at it!

Try It

##### Code Example

    var msg = "<img src='https://placehold.it/256x128'>" +
              "<h3>This is HTML</h3>" +
              "<p>It's great, right?</p>";
    alertify.log(msg);

##### Log with callback

Keep in mind that the current log are not going to close automatically if you call another one, as it is implemented inside the callback function in example. To force log closing use "ui.closeLog()" inside the callback function.

Try It

##### Code Example

    alertify.log("Log message with callback", function(e, ui) {
        // you can use click event here
        e.preventDefault();

        // method to close current log message
        ui.remove();

        alertify.log("You clicked the notification");
    });

##### Hide in 10 seconds

Try It

##### Code Example

    alertify
        .logDelay(10000)
        .log("Hiding in 10 seconds");

##### Persistent Log

Persistent log messages will stay until clicked (if "ui.remove()" is used inside callback function) or until forcibly removed when the number of messages exceeds the "logMaxItems" setting. See below.

Try It

##### Code Example

    alertify
        .logDelay(0)
        .log("Will stay until clicked", function(e, ui) {
            ui.remove();
        });

##### Maximum Number of Log Messages

You can easily set the maximum number of log/success/error messages that will be displayed at a single time. The default is two.

Try It

##### Code Example

    alertify
        .logMaxItems(1)
        .log("This is the first message");

    // The timeout is just for visual effect.
    setTimeout(function() {
        alertify.log("The second message will force the first to close.");
    }, 1000);

##### Template for Log messages

You can change the template for all logs.

Try It

##### Code Example

    alertify
        .logMessageTemplate(function (input) {
            return 'log message: ' + input;
        })
        .log("This is the message");

##### Setting the Position

Try It

##### Code Example

    alertify.logDelay(1000); // This is just to make the demo go faster.
    alertify.log("Default botoom left position");
    setTimeout(function() {
        alertify.logPosition("top left");
        alertify.log("top left");
    }, 1500);
    setTimeout(function() {
        alertify.logPosition("top right");
        alertify.log("top right");
    }, 3000);
    setTimeout(function() {
        alertify.logPosition("bottom right");
        alertify.log("bottom right");
    }, 4500);
    setTimeout(function() {
        alertify.reset(); // Puts the message back to default position.
        alertify.log("Back to default");
    }, 6000);

##### Setting the parent element

You can set where parent element where Alertify is appended into the DOM.

##### Code Example

    // By default, Alertify is appended to document.body.
    // You can easily change that, though, like this:
    var elem = document.getElementById("my-element");
    alertify.parent(elem);

##### Advanced example - Progress Bar

This complex example demonstrates how to create log that contains progress bar. Concept - you perform batch operations on some objects (uploading files e.g.) and would like to:

- display a single log message with total progress;
- display a success log message for each processed object;
- message with progress bar is stuck/fixed until all objects are processed;

First we log the message with progress bar and apply logMessageTemplate method to customize its template. All following "success" messages in the stack use default settings by cleaning previous setup with reset method.

Note that we use getLogs to get all existing log messages, fetch the last one (which contains progress bar) and assign it to the "logUI" variable for further usage.

After that we stick the progressbar log message by calling stick method on this message with true argument.

Stuck (fixed) log message means that it will constantly remains in the beginning of the log messages stack and wouldn't be shifted by other messages when the maximum number of log messages is exceeded.

Once all objects are processed we "unstick" progressbar log message so now it behaves the same way as other messages and can be shifted by the following messages. Also we set timeout to remove the message with delay.

Try It

##### Code Example

    var ProcessingLog = function() {
        this.total = 0;
        this.succeed = 0;
        this.failure = 0;
        this.processed = 0;

        this.getProgress = function() {
            var progress = Math.round((this.succeed / this.total) * 100);
            return (progress < 5) ? 5 : progress;
        };

        this.getMessage = function() {
            return '%s of %s items successfully processed'.replace('%s', this.succeed).replace('%s', this.total);
        };

        this.succeeded = function() {
            this.succeed++;
            this.processed++;
        };

        this.failed = function() {
            this.failure++;
            this.processed++;
        };

        this.isProcessed = function() {
            return this.processed === this.total;
        };
    };

    var process = new ProcessingLog();
    process.total = 5;

    var logs = alertify
        .logDelay(0)
        .logMessageTemplate(function (message) {
            var progress = process.getProgress(),
                animateCss = process.isProcessed() ? 'striped' : 'striped animated';

            return '<div>' + message + '</div>' +
                '<div class="progress">' +
                '<div class="progress-counter">' + progress + '%</div>' +
                '<div class="progress-bar ' + animateCss + '" style="width: ' + progress + '%"></div>' +
                '</div>';
        })
        .log(process.getMessage())
        .getLogs();

    var logUI = logs[logs.length-1];
    logUI.stick(true);

    var interval = setInterval(function() {
        process.succeeded();
        logUI.setMessage(process.getMessage());
        alertify
            .reset()
            .logDelay(5000)
            .success("Item #" + process.processed + " processed.");

        if (process.isProcessed()) {
            logUI.stick(false);
            clearInterval(interval);
            setTimeout(function() {
                logUI.remove();
            }, 5000);
        }
    }, 500);

### Template Customization

##### Predefined themes

Alertify provides a number of templates for popular platforms. To apply predefined theme use one the following names in "theme()" method:

- bootstrap
- purecss
- material-design-light
- angular-material

Try It Reset

##### Code Example

    alertify
        .theme("bootstrap")
        .prompt("Bootstrap theme message");

    alertify
        .theme("default")
        .prompt("Default theme message");

##### Custom templates

You are able to customize templates at your own. There are few templates for dialogs and logs which are listed below and should be passed to "theme()" method as object. Most of templates supposed to have key elements marked by data-alertify-* attribute, which is mandatory and serves to identify a target tag for the dialog message, prompt input, etc.

##### Dialog templates

- dialogMessage - Dialog message template. Target element attribute - "data-alertify-msg"
- dialogInput - Dialog prompt input template. Target element attribute - "data-alertify-input"
- dialogButtonsHolder - Dialog buttons wrapper template. Target element attribute - "data-alertify-btn-holder"

Try Dialog

##### Log templates

- logMessage - Log message template. Target element attribute - "data-alertify-log-msg"

Try Log

##### Code Example

    alertify.
        theme({
            dialogMessage: '<div style="text-align: center; color: #3F51B5;">' +
                '<div data-alertify-msg style="font-weight: bold"></div>' +
                '</div>',
            dialogInput: '<div>' +
                '<label for="template-dialog-input">LABEL - click to focus:</label>' +
                '<input data-alertify-input id="template-dialog-input" type="text">' +
                '<div style="font-size: 12px">Note: write any text to the input.</div>' +
                '</div>',
            dialogButtonsHolder: '<nav data-alertify-btn-holder style="text-align: center"></nav>'
        })
        .prompt("Dialog prompt with custom template.", "Default value",
        {
            click: function (e, ui) {
                alertify.success("You've typed: " + ui.getInputValue());
            }
        });

        // set default options
        setTimeout(function() {alertify.reset()}, 500);

    alertify.
        theme({
            logMessage:'<div class="wrapper">
                <div data-alertify-log-msg style="background: rgb(78, 150, 193);"></div>
                </div>'
        })
        .log("Log message with custom template.");

        // set default options
        setTimeout(function() {alertify.reset()}, 500);

### Other Options

##### Resetting Default Values

When you change values like the button labels, delays, dinput efaultr placeholders, etc., you can easily reset the defaults.

Try It

##### Code Example

    // Notice the okay button is not the custom value, it was reset.
    alertify
      .okBtn("Go For It!")
      .reset()
      .alert("Custom values were reset!");