Tuesday, April 24, 2012

ZK: Customize the mask for showBusy

Introduction


This post is about how to customize the mask that cover the specific area when showBusy in ZK.

The Program

customize_mask_for_show-busy.zul

<zk>
    <style>
        .busy-outer {
            position: absolute;
            left: -1000px;
            top: -1000px;
            border: 1px solid red;
            overflow: hidden;
            height: 200px;
            width: 200px;
            
            filter: alpha(opacity=60); <!-- IE -->
            opacity: .6;
            zoom: 1;
            background: #EE8888;
        }
    </style>
    <script type="text/javascript"><![CDATA[
        var override = setInterval(function () { // wait until zAu.cmd0 loaded
            if (zAu && zAu.cmd0) {
    // store the old functions
                var oldShowBusy = zAu.cmd0.showBusy;
                var oldClearBusy = zAu.cmd0.clearBusy;
                zAu.cmd0.showBusy = function (uuid, msg) {
                    var cls, // class of original busy box
                        custom, // the custom busy box
                        $body = jq(document.body),
                        bwid = $body.width()-5, // body width (slightly smaller)
                        bhgh = $body.height()-5, // body height (slightly smaller)
                        innerWid = 200, // width of inner content of custom busy box
                        innerHgh = 60, // height of inner content of custom busy box
                        wid, hgh, // width and height of busy box
                        mt, ml, key; // margin-top, margin-left and mapping key
                    // get the class of original busy box and mapping key
                    if (arguments.length == 1 || !uuid) {
                        cls = 'z-modal-mask';
                        key = 'null'
                    } else {
                        cls = 'z-apply-mask';
                        key = zk.Widget.$(uuid).uuid;
                    }
                    // do the original showBusy
                    oldShowBusy.apply(this, arguments);
                    // get the original busy box
                    var $dom = jq('.'+cls);

                    if ((custom = jq('$customBusy'))) { // custom busybox exists
                        var outer = jq(custom.find('div').clone()[0]), // clone the content of custom busy box
                            wid = $dom.width(), // get original width
                            hgh = $dom.height(), // get original height
                            inner; // the inner content

                        // shrink the size if too large
                        if (wid > bwid) wid = bwid;
                        if (hgh > bhgh) hgh = bhgh;

                        // put content into body
                        document.body.appendChild(outer[0]);
                        // get inner content
                        inner = jq(outer.find('div')[0]);

                        // apply style to outer content
                        outer.css({
                            left: $dom.offset().left + 'px',
                            top: $dom.offset().top + 'px',
                            width: wid + 'px',
                            height: hgh + 'px'
                        });
                        outer[0].style.zIndex = $dom[0].style.zIndex;

                        // calculate the appropriate margin
                        ml = wid > innerWid? ($dom.outerWidth(true) - innerWid)/2 : 0;
                        mt = hgh > innerHgh? ($dom.outerHeight(true) - innerHgh)/2 : 0;
                        // apply the style to inner content
                        inner.css({
                            marginTop: mt + 'px',
                            marginBottom: mt + 'px',
                            marginLeft: ml + 'px',
                            marginRight: ml + 'px'
                        })
                        
                        $dom.parent()[0].style.display = 'none';
                        // store the outer node with mapping key
                        zAu.cmd0[key] = outer[0];
                    }
                };
                zAu.cmd0.clearBusy = function (uuid) {
                    var key,
                        node;
                    // get the mapping key
                    if (!uuid)
                        key = 'null'
                    else
                        key = zk.Widget.$(uuid).uuid;

                    // get node and remove it by mapping key
                    if ((node = zAu.cmd0[key])
                        && node.parentNode)
                        node.parentNode.removeChild(node);
                    
                    delete node;
                    // do the original clearBusy
                    oldClearBusy.apply(this, arguments);
                }
                clearInterval(override);
            }
        });
    ]]></script>
    <!-- Show busy on full page and clear it after 3 seconds -->
    <button label="busy on page">
        <attribute name="onClick">
            Clients.showBusy("busy...");
            tmOne.start();
        </attribute>
    </button>
    <!-- Show busy on label 'lb' and clear it after 3 seconds -->
    <button label="busy on label">
        <attribute name="onClick">
            Clients.showBusy(lb, "busy...");
            tmTwo.start();
        </attribute>
    </button>
    <timer id="tmOne" delay="3000" repeats="false" running="false" onTimer="Clients.clearBusy();" />
    <timer id="tmTwo" delay="3000" repeats="false" running="false" onTimer="Clients.clearBusy(lb);" />
    <label id="lb" value="message: " width="100px" height="100px" />
    <!-- The custom busy box, can put anything in it
        currently put a window -->
    <div id="customBusy">
        <div class="busy-outer">
            <div style="background-color: white;">
                <!-- The window below can be anything -->
                <window border="normal" title="busy...">
                    <div>This is the</div>
                    <div>custom busy box</div>
                </window>
            </div>
        </div>
    </div>
</zk>

The Result
View it on line:
http://screencast.com/t/JXaDIxgbrw

or

Download demo flash:
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/customize_mask_for_show-busy.swf?raw=true


Download
customize_mask_for_show-busy.zul
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/WebContent/customize_mask_for_show-busy.zul


Reference
http://zk1.svn.sourceforge.net/viewvc/zk1/branches/6.0/zk/src/archive/web/js/zk/au.js?revision=15987&view=markup

No comments:

Post a Comment