Skapa dialogruta med ren JavaScript

I denna handledning kommer vi skapa en dialogruta med ren JavaScript. En dialogruta visas ovanpå en sida, den kan användas för att visa information och/eller för att ta emot inmatning från en användare.

Denna plugin beror på annytab.effects (Rena JavaScript-effekter) som vi har skrivit om i ett tidigare blogginlägg.

Vi ska skapa en dialogruta som kan användas för att visa information, för att erhålla inmatning från en användare eller för att visa en bekräftelsedialogruta. Syftet är att skapa en flexibel dialogruta som kan användas i många olika situationer.

Det här tillägget har testats och fungerar med Google Chrome (75.0.3770.100), Mozilla Firefox (67.0.4), Microsoft Edge (42.17134.1.0) och Internet Explorer (11.829.17134.0), detta utan någon polyfill. Om du vill stödja äldre webbläsare kan du hämta polyfills från polyfill.io.

Dialogruta

Design (CSS)

Stylingen för denna plugin innehåller CSS för strukturen och för en standardiserad bekräftelsedialog. Innehållet i dialogrutan kan ha anpassat utseende.

/* Annytab modalbox*/
.annytab-modalbox-container {
    display: none;
    z-index: 100;
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    text-align: center;
    background-color: rgba(0, 0, 0, 0.7);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);
    -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";
}
.annytab-modalbox-margin {
    display: block;
    margin: 40px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.annytab-modalbox-wrapper {
    display: inline-block;
    position: relative;
    background-color: #ffffff;
    border-radius: 8px;
    max-width: 100%;
    top: calc(50vh - 50px); /* adjust for margin */
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}
.annytab-modalbox-padding {
    display: block;
    padding: 20px;
    text-align: left;
}
.annytab-modalbox-close {
    position: absolute;
    width: 24px;
    height: 24px;
    top: 8px;
    right: 8px;
    cursor: pointer;
    opacity: 0.6;
    filter: alpha(opacity=60);
}

.annytab-modalbox-close:hover {
    opacity: 1;
    filter: alpha(opacity=100);
}

.annytab-modalbox-close:before, .annytab-modalbox-close:after {
    position: absolute;
    right: 12px;
    content: ' ';
    height: 24px;
    width: 2px;
    background-color: #ffffff;
}
.annytab-modalbox-close:before {
    transform: rotate(45deg);
}
.annytab-modalbox-close:after {
    transform: rotate(-45deg);
}

.annytab-modalbox-content {
    display: block;
    position: relative;
    max-width: 600px;
    max-height: calc(100vh - 120px); /* margin + padding */
    background-color: #ffffff;
    padding: 0;
    margin: 0;
    overflow: auto;
}

.annytab-modalbox-content-title {
    font-size: 24px;
    line-height: 36px;
    font-weight: bold;
    color: #000000;
    margin-bottom: 5px;
}

.annytab-modalbox-content-message {
    font-size: 16px;
    line-height: 24px;
}

.annytab-modalbox-content-buttonpanel {
    display:block;
    bottom: 0;
    text-align: right;
    margin-top: 20px;
}

.annytab-modalbox-content-button-cancel {
    display: inline-block;
    min-width: 80px;
    padding: 0 20px 0 20px;
    margin: 0 0 0 10px;
    color: #ffffff;
    text-align: center;
    font-size: 16px;
    line-height: 28px;
    background-color: #d9534f;
    border: 1px solid #d43f3a;
    border-radius: 4px;
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
}

.annytab-modalbox-content-button-ok {
    display: inline-block;
    min-width: 80px;
    padding: 0 20px 0 20px;
    margin: 0 0 0 10px;
    color: #ffffff;
    text-align: center;
    font-size: 16px;
    line-height: 28px;
    background-color: #4CAF50;
    border: 1px solid #3B873D;
    border-radius: 4px;
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
}

.annytab-modalbox-content-button-cancel:hover {
    background-color: #F25C5C;
    border-color: #d9534f;
    text-decoration: none;
}

.annytab-modalbox-content-button-ok:hover {
    background-color: #59CC5D;
    border-color: #4CAF50;
    text-decoration: none;
}

JavaScript

Denna plugin har en konstruktor som tar alternativ som en parameter. Klickhändelser läggs till för alla länkar med en given väljare (selector). Denna plugin har en public open-metod som kan användas för att skapa en dialogruta och en offentlig close-metod som kan användas för att stänga en dialogruta.

var annytab = annytab || {};
annytab.modalbox = (function () {

    'use_strict';

    // Constructor
    function modalbox(opts)
    {
        // Set default values for parameters
        opts = opts || {};

        // Set options
        this.options = { selector: '.annytab-modalbox-popup', fade_duration: 1000, close_click_outside: false };
        for (var option in this.options) {
            if (opts.hasOwnProperty(option) === true) {
                this.options[option] = opts[option];
            }
        }

        // Set variables
        resetVariables(this);
        
        // Get all links that should have a modalbox
        var links = document.querySelectorAll(this.options.selector);

        // Add events
        addLinkEvents(this, links);

    } // End of the constructor

    // Reset variables to default values
    function resetVariables(mb)
    {
        mb.container = null;
        mb.wrapper = null;
        mb.close_button = null;
        mb.cancel_button = null;
        mb.ok_button = null;

    } // End of the resetVariables method

    // Add link events
    function addLinkEvents(mb, links)
    {
        // Loop links
        for (var i = 0; i < links.length; i++)
        {
            // Add a click event
            window.onload = links[i].addEventListener('click', function (event)
            {
                // Prevent default click behaviour
                event.preventDefault();

                // Open modalbox
                openWithHtml(mb, document.querySelector(this.getAttribute('href')).innerHTML);

            }, false);
        }

    } // End of the addEvents method

    // Add container events
    function addContainerEvents(mb, callback, parameters)
    {
        // Add a close event for close button
        window.onload = mb.close_button.addEventListener('click', function (event)
        {
            // Prevent default click behaviour
            event.preventDefault();

            // Close the container
            mb.close();

        }, false);

        // Add a close event for click outside wrapper
        if (mb.options.close_click_outside === true)
        {
            window.onload = mb.container.addEventListener('click', function (event) {

                // Prevent default click behaviour
                event.preventDefault();

                // Close the modalbox
                if (event.target.contains(mb.wrapper) === true)
                {
                    mb.close();
                }

            }, false);
        }

        // Add a cancel click event
        if (mb.cancel_button !== null)
        {
            window.onload = mb.cancel_button.addEventListener('click', function (event) {

                // Prevent default click behaviour
                event.preventDefault();

                // Disable buttons
                mb.cancel_button.setAttribute('disabled', true);
                mb.ok_button.setAttribute('disabled', true);

                // Close the modalbox
                mb.close();

            }, false);
        }

        // Add a ok click event
        if (mb.ok_button !== null && callback !== null)
        {
            window.onload = mb.ok_button.addEventListener('click', function (event) {

                // Prevent default click behaviour
                event.preventDefault();

                // Disable buttons
                mb.ok_button.setAttribute('disabled', true);
                mb.cancel_button.setAttribute('disabled', true);

                // Call the callback function
                callback(parameters);

            }, false);
        }

    } // End of the addContainerEvents method

    // Open a modalbox with html
    function openWithHtml(mb, html, callback, parameters)
    {
        // Add a modalbox
        mb.container = document.createElement('div');
        mb.container.setAttribute('class', 'annytab-modalbox-container');
        mb.container.insertAdjacentHTML('beforeend',
            '<div class="annytab-modalbox-margin">'
            + '<div class="annytab-modalbox-wrapper">'
            + '<div class="annytab-modalbox-padding">'
            + html
            + '</div></div></div>'
            + '<div class="annytab-modalbox-close"></div >');
        document.body.appendChild(mb.container);

        // Get references
        mb.wrapper = mb.container.querySelector('.annytab-modalbox-wrapper');
        mb.close_button = mb.container.querySelector('.annytab-modalbox-close');
        mb.cancel_button = mb.container.querySelector('.annytab-modalbox-content-button-cancel');
        mb.ok_button = mb.container.querySelector('.annytab-modalbox-content-button-ok');

        // Fade in the container
        annytab.effects.fadeIn(mb.container, mb.options.fade_duration, 'block');

        // Add container events
        addContainerEvents(mb, callback, parameters);

    } // End of the openWithHtml method

    // Open a modalbox
    modalbox.prototype.open = function (input)
    {
        // Get input
        var data = { html: null, title: 'Title', message: 'Message', ok_text: 'Ok', cancel_text: 'Cancel', callback: null, parameters: [] };
        for (var option in data) {
            if (input.hasOwnProperty(option) === true) {
                data[option] = input[option];
            }
        }

        // Check if we should create a customized modalbox or a standardized
        if (data.html !== null)
        {
            // Open a modalbox
            openWithHtml(this, data.html, data.callback, data.parameters);
        }
        else
        {
            var html = '<div class="annytab-modalbox-content">'
                + '<div class="annytab-modalbox-content-title">' + data.title + '</div>'
                + '<div class="annytab-modalbox-content-message">' + data.message + '</div>'
                + '<div class="annytab-modalbox-content-buttonpanel">'
                + '<input type="button" class="annytab-modalbox-content-button-ok" value="' + data.ok_text + '" />'
                + '<input type="button" class="annytab-modalbox-content-button-cancel" value="' + data.cancel_text + '" />'
                + '</div></div>';

            // Open a modalbox
            openWithHtml(this, html, data.callback, data.parameters);
        }

    }; // End of the open method

    // Close a modalbox
    modalbox.prototype.close = function ()
    {
        // Get a reference to the container
        var box = this.container;

        // Fade out the container
        annytab.effects.fadeOut(box, this.options.fade_duration);

        // Remove the container
        setTimeout(function ()
        {
            document.body.removeChild(box);

        }, this.options.fade_duration);
        
        // Reset variables (GC)
        resetVariables(this);

    }; // End of the close method

    // Return this object
    return modalbox;

})();

Så här använder du tillägget med länkar

Ett sätt att använda detta plugin är att lägga till länkar och dolda behållare med innehåll. Attributet href i länken pekar på den behållare vars innehåll skall inkluderas i dialogrutan.

@*Link*@
<a href="#modalbox-test" class="annytab-modalbox-popup">Open Modalbox</a>

@*Container*@
<div id="modalbox-test" style="display:none;">
    <div class="annytab-messagebox-container">
        <div class="annytab-messagebox-header">Delete files</div>
        <div class="annytab-messagebox-text">
            Are you sure that you want to delete files? They will be deleted permanently.
        </div>
        <div class="annytab-messagebox-button-panel">
            <input type="button" class="annytab-messagebox-button btn-green btn-disablable" value="Ok" onclick="disableButtons(); sayHello(['Bill', 'USA', 100]); enableButtons();" />
            <input type="button" class="annytab-messagebox-button btn-red btn-disablable" value="Cancel" onclick="disableButtons(); modalbox.close(); enableButtons(); " />
        </div>
    </div>
</div>
<script src="/js/annytab-shared/annytab.effects.js"></script>
<script src="/js/annytab-shared/annytab.modalbox.js"></script>
<script>

    // Modalbox
    var modalbox = new annytab.modalbox({ selector: '.annytab-modalbox-popup', fade_duration: 1000, close_click_outside: true });

    // Say hello to a person
    function sayHello(parameters)
    {
        // Log the message
        console.log('Hello ' + parameters[0] + ' from ' + parameters[1] + ', you got ' + parameters[2] + ' points!');

        // Close the modalbox
        modalbox.close();

    } // End of the sayHello method

    // Disable buttons
    function disableButtons()
    {
        var buttons = document.getElementsByClassName('btn-disablable');
        for (var i = 0; i < buttons.length; i++)
        {
            buttons[i].setAttribute('disabled', true);
        }

    } // End of the disableButtons method

    // Enable buttons
    function enableButtons()
    {
        var buttons = document.getElementsByClassName('btn-disablable');
        for (var i = 0; i < buttons.length; i++)
        {
            setTimeout(function (button) { button.removeAttribute('disabled'); }, 1000, buttons[i]);
        }

    } // End of the enableButtons method

</script>

Så här använder tillägget från skript

Du kan också använda denna plugin genom att infoga innehåll direkt från skript. Några exempel på detta visas nedan. Klickhändelser kommer att läggas till om du lägger till CSS-klasser som används av tillägget.

// Modalbox
var modalbox = new annytab.modalbox({ selector: '.annytab-modalbox-extension', fade_duration: 1000, close_click_outside: false });

// Open modalbox with html
modalbox.open({
    html: '<div class="annytab-messagebox-container">'
        + '<div class="annytab-messagebox-header">' + 'Do you need help?' + '</div>'
        + '<div class="annytab-messagebox-text">' + 'I can help you with any problem, just answer yes or no.' + '</div>'
        + '<div class="annytab-messagebox-button-panel">'
        + '<input type="button" class="annytab-messagebox-button btn-green btn-disablable" onclick="disableButtons(); sayHello([\'Donald\', \'Germany\', 33]); enableButtons();" value="Yes" />'
        + '<input type="button" class="annytab-messagebox-button btn-red btn-disablable" onclick="disableButtons(); modalbox.close(); enableButtons();" value="No" />'
        + '</div></div>'
});

// Open modalbox with html
modalbox.open({
    html: '<div class="annytab-modalbox-content">'
        + '<div class="annytab-modalbox-content-title">' + 'Do you need help?' + '</div>'
        + '<div class="annytab-modalbox-content-message">' + 'I can help you with any problem, just answer yes or no.' + '</div>'
        + '<div class="annytab-modalbox-content-buttonpanel">'
        + '<input type="button" class="annytab-modalbox-content-button-ok" value="Yes" />'
        + '<input type="button" class="annytab-modalbox-content-button-cancel" value="No" />'
        + '</div></div>', callback: sayHello, parameters: ['Marcus', 'France', 120]
});

// Open standard modalbox 
modalbox.open({ title: 'Title', message: 'Message', ok_text: 'Ok', cancel_text: 'Cancel', callback: sayHello, parameters: ['Peter', 'Russia', 50]});

Lämna ett svar

E-postadressen publiceras inte. Obligatoriska fält är märkta *