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:
- place RadDatePicker/RadDateTimePicker/RadComboBox control inside a scrollable container;
- ensure that the content of the scrollable container element is large enough to make the scrollbars visible;
- click the popup button to show calendar/time/combobox popup;
- 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