3.2.0

Proposed change for popup template

The idea is, as I wrote in a previous post, to make the popup from the combobox to appear above the control when opened and there is not enough space left on the window below the control to show the popup list.

At this moment, if the combo popup exceds the bottom of the window:
- in Firefox the div is partially or even completely hidden
- in IE it will force the bottom of the popup to be on the page bottom which will cause overlapping the two elements.

The solution I found is to change the Popup template in order to automatically move the list above the combo when the bottom space is not enough for it.

I have tested in IE7, IE6 and Firefox 1.5

the changes are:

For IE:

....
        width = Math.max(doc.body.scrollWidth, width);
    height = Math.max(doc.body.scrollHeight+1, 20);
        if (AW.getTop(ref) + height > document.body.scrollHeight+1)
        {
            top = -height;
        }
        else
        {
            top = ref.offsetHeight
        }


and later ...

this.setTimeout(function(){
            try {
                if (AW.getTop(this.element()) + height > document.body.scrollHeight+1)
                {
                    top = -height;
                }
                else
                {
                    top = this.element().offsetHeight;
                }
                width = Math.max(doc.body.scrollWidth, width);
                height = Math.max(doc.body.scrollHeight+1, 20);
                if (popup.isOpen){
                    popup.show(left, top, width, height, ref);
                }
                popup = null;
                ref = null;
            }
            catch(err){
            }
        }, 500); // timeout for resizing popup


and for Firefox:

....
var height = this.getPopupTemplate().getStyle('height').replace("px","")/1;  
        var left = AW.getLeft(ref);
        var top;
        var refTop = AW.getTop(ref);
        if (refTop + height > document.body.scrollHeight+1)
        {
            top = refTop - height -4;// -4 ??? borders ? paddings ? margins ?
        }
        else
        {
            top = refTop + ref.offsetHeight;
        }
....


note that
var height = this.getPopupTemplate().getStyle('height').replace("px","")/1;
used in Firefox version.
I have also set the setSize() for the list widget used to populate the popup.
It is probably a wrong approach but I am sure there is also the correct way to find the height.

Also a request: the popup - that is the list used - should have a maxHeight and a minWidth property. I have implemented this in a rather trivial manner by setting some variables to the list widgets.

maxHeight should be used to allow us define the maximum height when calculating the real height of the list. So it will enter in a Math.min(maxHeight,realHeight) approach.

minWidth should be used to allow setting a better width for the list in the dropdown. I have used a Math.max(minWidth,cellWidth||ComboWidth) in order to set a minimum visible area to the popup and also to make the widths of the combo and its popup the same.

setSize(Math.max(minWidth,cellWidth||comboWidth),Math.min(maxHeight,realHeight));
would display a better popup for the combobox

Dear Alex I hope you will find my post good enough in order to add this idea in the normal functionality of the popup template.

I think it is best for all that each would try to improve this amazing work that you are doing.

Below I send the entire AW.Templates.Popup file with the note that in firefox I am using the height set by setSize() method in AW.UI.List

Best Regards,
Bogdan

AW.Templates.Popup.create = function(){

    var obj = this.prototype;

    obj.setClass("popup", "normal");

    obj.showPopup = function(){

        var popup = window.createPopup();
        this.$popup = popup;
        AW.$popup = this;

        var doc = popup.document;
        doc.open();

        if (AW.strict){
            doc.write("<!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01\/\/EN\" \"http:\/\/www.w3.org/TR/html4/strict.dtd\">");
        }

        doc.write("<html class=\"aw-popup-window aw-system-control " + AW._htmlClasses + "\"><head>");

        AW.register(doc.parentWindow);

        for (var i=0; i<document.styleSheets.length; i++){
            doc.write(document.styleSheets[i].owningElement.outerHTML);
        }

        doc.write("</head><body onselectstart=\"return false\" oncontextmenu=\"return false\">");
        doc.write(this.getPopupTemplate().toString());
        doc.write("</body></html>");
        doc.close();

        var ref = this.element();

        var left = 0;
        var top = ref.offsetHeight;
        
        var width = ref.offsetWidth;
        var height = 1;

        popup.show(left, top, width, height, ref);

        width = Math.max(doc.body.scrollWidth, width);
        height = Math.max(doc.body.scrollHeight+1, 20);
        if (AW.getTop(ref) + height > document.body.scrollHeight+1)
        {
            top = -height;
        }
        else
        {
            top = ref.offsetHeight
        }
        
        popup.show(left, top, width, height, ref);

        this.setTimeout(function(){
            try {
                if (AW.getTop(this.element()) + height > document.body.scrollHeight+1)
                {
                    top = -height;
                }
                else
                {
                    top = this.element().offsetHeight;
                }
                width = Math.max(doc.body.scrollWidth, width);
                height = Math.max(doc.body.scrollHeight+1, 20);
                if (popup.isOpen){
                    popup.show(left, top, width, height, ref);
                }
                popup = null;
                ref = null;
            }
            catch(err){
            }
        }, 500); // timeout for resizing popup
    };

    obj.hidePopup = function(){
        if (this.$popup && this.$popup.isOpen ){
            this.$popup.hide();
        }
        if (this.$popup){
            this.$popup = null;
        }
        if (AW.$popup){
            AW.$popup = null;
        }
    };

if (!AW.ie){

    obj.showPopup = function(){

        if (this.$popup){
            document.body.removeChild(this.$popup);
            this.$popup = null;
        }

        var ref = this.element() ? this.element() : document.body;
        
        var height = this.getPopupTemplate().getStyle('height').replace("px","")/1;  
        var left = AW.getLeft(ref);
        var top;
        var refTop = AW.getTop(ref);
        if (refTop + height > document.body.scrollHeight+1)
        {
            top = refTop - height -4;// -4 ??? borders ? paddings ? margins ?
        }
        else
        {
            top = refTop + ref.offsetHeight;
        }
        
        var popup = document.createElement("div");
        this.$popup = popup;
        AW.$popup = this;
        
        document.body.appendChild(popup);
        popup.className = "aw-popup-window aw-system-control";
        popup.style.left = left + "px";
        popup.style.top = top + "px";
        popup.innerHTML = this.getPopupTemplate().toString();

    };

    obj.hidePopup = function(){
        if (this.$popup){
            this.setTimeout(function(){
                document.body.removeChild(this.$popup);
                this.$popup = null;
                AW.$popup = null;
            });
        }
    };

    obj.onControlDeactivated = function(){
        this.hidePopup();
    }
}

};
Bogdan
April 27,

This topic is archived.

See also:


Back to support forum