How to collapse callendar/time/combobox popup when parent container scrolls

2 posts, 0 answers
  1. Volodymyr Oliinyk
    Volodymyr Oliinyk avatar
    35 posts
    Member since:
    Nov 2006

    Posted 23 Jul 2010 Link to this post

    Requirements

    RadControls version

    Telerik.Web.UI.2008.3 -
    Telerik.Web.UI.2010.2

    .NET version

    any    

    Visual Studio version

    any

    programming language

    any

    browser support

    all browsers supported by RadControls


    PROJECT DESCRIPTION
    The issue raised when a RadDatePicker/RadDateTimePicker/RadComboBox control is placed inside a scrollable container element, for example in RadSplitter pane or in simple <div style="overflow:auto">.
    STR:
    1. place RadDatePicker/RadDateTimePicker/RadComboBox control inside a scrollable container;
    2. ensure that the content of the scrollable container element is large enough to make the scrollbars visible;
    3. click the popup button to show calendar/time/combobox popup;
    4. scroll the parent element;

    * content is scrolled along with the control, the control's popup is misplaced.

    The problem is inherent to the control structure since the popup element is appended to the topmost body/form element and does not know anything about owner control location.

    SOLUTION
    Implement a workaround which tracks scroll event and calls hide popup methods when appropriate.

    IMPLEMENTATION
    Fixing of the control prototypes implemented in the scope of the fix utility. Methods of the utility are called on the page init.
    The code below contains calls to utility methods with self-describing names.

    // fixes the prototype of the control with popup functionality so that 
    // it closes the popup when a scrollable parent element, if any, scrolls. 
    this.fixPopupControlForScroll = function(controlPrototype, hideMethod){ 
        var base_initialize = controlPrototype.initialize; 
        controlPrototype.initialize = function(){ 
            base_initialize.apply(this); 
        
            // find parent scrollable element 
            var scrollableParent = $wf.dom.findUp(this.get_element(), function(node){ 
                var style = $wf.dom.getCurrentStyle(node); 
                return style && (style.overflowX == "auto"
                  || style.overflowX == "scroll"
                  || style.overflowY == "auto"
                  || style.overflowY == "scroll"); 
            }); 
        
            if (!scrollableParent) 
                return
        
            var me = this
                scrollableParent_scroll = function(e){ 
                    hideMethod.apply(me, [e]); 
                }; 
        
                $addHandler(scrollableParent, "scroll", scrollableParent_scroll); 
        
            this.add_disposing(function(){ 
                if (scrollableParent._events) // when parent is not disposed first 
                    $removeHandler(scrollableParent, "scroll", scrollableParent_scroll); 
                me = scrollableParent = scrollableParent_scroll = null
            }); 
        }; 
    }; 
        
    ... 
        
    // fix date/time pickers 
    this.fixPopupControlForScroll(datePickerPrototype, function(e){ 
        if (this.isPopupVisible()){ 
            var calendarPopup = this.get__popup(); 
                
            // change the hide animation duration to 0 
            // in order to make it hide at once 
            var hideDuration = calendarPopup.HideAnimationDuration; 
            calendarPopup.HideAnimationDuration = 0; 
            try
                this.hidePopup(); 
            } finally { 
                calendarPopup.HideAnimationDuration = hideDuration; 
            
        
            
        var timePopup; 
        if (this.get_timeView && this.get_timeView() 
          && (timePopup = this.get__TimePopup()).IsVisible()){ 
            // change the hide animation duration to 0 
            // in order to make it hide at once 
            var hideDuration = timePopup.HideAnimationDuration; 
            timePopup.HideAnimationDuration = 0; 
            try
                this.hideTimePopup(); 
            } finally { 
                timePopup.HideAnimationDuration = hideDuration; 
            
        
    }); 
        
    // fix combobox 
    this.fixPopupControlForScroll(radComboBoxPrototype, function(e){ 
        if (!this.get_dropDownVisible()) 
            return
        
        // change the collapse animation type to None 
        // in order to make it close at once 
        var collapseAnimType = this._slide._collapseAnimation._type; 
        this._slide._collapseAnimation._type = Telerik.Web.UI.AnimationType.None; 
        try
            this._hideDropDown(e); 
        } finally { 
            this._slide._collapseAnimation._type = collapseAnimType; 
        
    }); 

    Would be nice to implement such functionality in the core telerik controls, however it might introduce unwanted overhead.

    Enjoy,
    Vadim

  2. Radoslav
    Admin
    Radoslav avatar
    1564 posts

    Posted 28 Jul 2010 Link to this post

    Hi Vadimko,

    Thank you for sharing your solution with the community. As a small token of gratitude for your involvement I have updated your Telerik points.

    Kind regards,
    Radoslav
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Back to Top