views:

115

answers:

1

I have created a modal window using the Prototype JavaScript framework and the following object:

var Modal = Class.create({
    animate: function () {
        this.step = (this.step + 1) % 31;

        if (this.throbber) {
            this.throbber.setStyle({
                backgroundPosition: 'center ' + this.step * -33 + 'px'
            });
        }
    },
    destroy: function () {
        if (this.interval_id) {
            window.clearInterval(this.interval_id);
        }

        if (this.timeout_id) {
            window.clearTimeout(this.timeout_id);
        }

        if (this.overlay.parentNode) {
            this.overlay.remove();
        }

        if(this.window.select('select')){
            this.window.select('select').each(function(ele){
                Element.remove(ele);                
            });
        }

        this.window.select('*').invoke('remove');

        if (this.window.parentNode) {
            this.window.remove();
        }
    },
    initialize: function (element) {
        this.launch_element = element;

        this.overlay = new Element('div', {'class': 'modal_overlay'});

        $$('body').first().insert(this.overlay);

        this.close = new Element('a', {
            'class': 'modal_close'
        }).insert('Close');

        this.close.observe('click', this.destroy.bind(this));

        this.window = new Element('div', {'class': 'modal_window'});

        if(this.window.select('select')){
            this.window.select('select').each(function(ele){
                Element.remove(ele);                
            });
        }

        this.window.select('*').invoke('remove');

        this.window.insert(this.close);

        this.section = new Element('div', {'class': 'section'});

        this.show_throbber();

        this.window.insert(this.section);

        $$('body').first().observe('keypress', function (e) {
            var key_code = window.event ? event.keyCode : e.keyCode;

            var esc = window.event ? 27 : e.DOM_VK_ESCAPE;

            if (key_code === esc) {
                this.destroy();
            }
        }.bind(this));

        $$('.container').first().insert(this.window);

        if (Prototype.Browser.IE) {
            this.scroll_window();

            Event.observe(window, 'scroll', this.scroll_window.bind(this));
        }
    },
    remove_throbber: function () {
        if (this.interval_id) {
            window.clearInterval(this.interval_id);
        }

        if (this.timeout_id) {
            window.clearTimeout(this.timeout_id);
        }

        this.throbber.remove();
    },
    scroll_window: function() {
        var height, offsets;

        offsets = document.viewport.getScrollOffsets();

        this.overlay.setStyle({
            left: offsets.left + 'px',
            top: offsets.top + 'px'
        });

        height = document.viewport.getHeight();

        this.window.setStyle({
            top: offsets.top + Math.round(17 * height / 100) + 'px'
        });
    },
    show_throbber: function (text) {

        if(this.section.select('select')){
            this.section.select('select').each(function(ele){
                Element.remove(ele);                
            });
        }

        this.section.select('*').invoke('remove');

        if (!text) {
            text = 'Loading';
        }

        this.throbber = new Element('div', {
            'class' : 'modal_throbber'
        }).insert(new Element('p').insert(text + '...'));

        this.section.insert(this.throbber);

        this.step = 0;

        this.interval_id = window.setInterval(this.animate.bind(this), 50);

        this.complete = false;

        this.timeout_id = window.setTimeout(this.timeout.bind(this), 20000);
    },
    timeout: function () {
        var div, p, span;

        if (!this.complete) {
            if (this.interval_id) {
                window.clearInterval(this.interval_id);
            }

            if (this.throbber) {
                this.remove_throbber();

                span = new Element('span', {'class': 'icon icon-delete'});

                p = new Element('p', {'class': 'first'}).update(span);

                p.insert('There seems to be something wrong with eSP. ' +
                  'Please try again later.');

                div = new Element('div', {'class': 'error'}).update(p);

                this.section.update(div);
            }

            if (this.timeout_id) {
                window.clearTimeout(this.timeout_id);
            }
        }
    }
});

and is styled with the following stylesheet:

.modal_overlay {
    height: 100%;
    width: 100%;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 2999;
    opacity: 0.5;
    background: #000;
}

* html .modal_overlay {
    filter: alpha(opacity=50);
    position: absolute;
    zoom: 1;
}

.modal_window {
    display: block;
    position: fixed;
    top: 17%;
    z-index: 3000;
}

* html .modal_window {
    position: absolute;
}

.modal_close {
    background: url('/images/close.gif') no-repeat scroll 0 0;
    height: 26px;
    cursor: pointer;
    position: absolute;
    right: -13px;
    top: -8px;
    width: 26px;
    text-indent: -10000px;
}

.modal_throbber {
    background: url('/images/throbber.png') no-repeat top center;
    padding-top: 32px;
}

.modal_throbber p {
    background: #fff;
    text-align: center;
}

We are now getting reports from customers that when the modal window is taller than the screen they cannot scroll down to see the bottom part of the modal window's content.

Is it a case of us making sure that too much information isn't displayed in the modal or is there a better, more technical fix?

A: 

You can put a max-height on the modal window and overflow:scroll.

RegDwight