I have a dynamically populated div-based dropdown that extends past the end of the screen when the customer puts lots of entries in it, hiding the lower entries. It is on one column in a set of data entry rows (td elements), so the available space varies on which row is being entered.
Unfortunately this is an application I've inherited, don't have any help with, and don't really have the skill set to maintain, so I would appreciate a bit of 'explain like I'm five'. Also, my apologies for the wall of text.
From extensive Googling and examination of other code in the application I believe an optionsCollection would solve this specific problem, but I need to fire off a function to set other data when the selected value changes and haven't found a way to do that with optionsCollection.
Unfortunately this thing is simply too big to post, and I would likely mangle it if I tried to package the problem in a standalone, so here's what I think is the relevant code.
The div
<div class="empform">
<html:form action="/processBlank">
<div id="divJobClass" style="visibility: hidden; position: absolute; height="50px"
border-color: #fff; border-style:solid; border-width: 1px; background: white; opacity: 1">
<table id="tableJobClass" cellspacing="0" style="border-color: #9090ff; border-style:solid; border-width:1px;" cellpadding="0"> <%
ctr = 0;
for (JobClassVO jc : jcList) { // href="setJC(<%=jc.getGuid()% >, '< %=jc.getJcIdDesc()% >')" %>
<tr><td><input style="border: none; background: white" type="text"
id="jc<%=ctr%>" size="50" value="<%=jc.getJcIdDesc()%>" readonly="readonly"
onclick="setJC(<%=jc.getGuid()%>, '<%=jc.getJcIdDesc()%>', <%=ctr%>)"
onkeydown='jcListCheck(event);'></td></tr><%
ctr++;
}
%>
Where the dropdown gets triggered by clicking on the field
<td>
<html:hidden name="erfEmployee" property="jcGUIDString" indexed="true"/>
<html:text name="erfEmployee" property="jcId" indexed="true"
size="8" maxlength="25" onblur='<%= "isLastRow('JobClass', " + count + ");" %>'
onclick='<%= "showJcList(" + count + ");" %>'
onkeydown='<%= "jcCheck(event," + count + ");" %>'
onchange='<%= "verifyHoursClass(" + count + ");" %>' readonly="true" />
</td>
isLastRow, jcCheck and onChange are not related to the appearance. The functions used to make the div appear
function showJcList(index) {
var fld = elem("erfEmployee[" + index + "].erfEeSsnFormatted");
if (fld.value == "")
return;
var div = elem_("divJobClass");
jcGuidTarget = elem("erfEmployee["+index+"].jcGUIDString");
jcIdTarget = elem("erfEmployee["+index+"].jcId");
showList(jcIdTarget, div, jcGuidTarget);
focusSelected("jc", null, <%=jcList.size()-1%>);
}
function showList(idTarget, div, guidTarget) {
ddDiv = div;
if (ddDiv.style.visibility == "visible") {
ddDiv.style.visibility = "hidden";
return;
}
var iTop = 0, oNode = idTarget, iLeft = 0;
while(oNode.tagName != "BODY" && oNode.tagName != "HTML") {
iTop += oNode.offsetTop;
oNode = oNode.offsetParent;
}
oNode = idTarget;
while(oNode.tagName != "BODY" && oNode.tagName != "HTML") {
iLeft += oNode.offsetLeft;
oNode = oNode.offsetParent;
}
ddDiv.style.left = "" + iLeft + "px";
ddDiv.style.top = "" + (iTop + idTarget.offsetHeight) + "px";
ddDiv.style.visibility = "visible";
ddIdTarget = idTarget;
ddGuidTarget = guidTarget;
}
Several sites I searched suggested overflow:auto and setting a size, but that didn't seem to change anything. Maybe I messed up setting the size? But it seems to me a fixed size wouldn't help as the available space depends on which row is being entered. I found that overflow:scroll gave me horizontal and vertical scroll bars, but the bars just extend with the div right off the end of the screen. I've considered trying to figure out how much room is left, and making the div appear high enough to fit, but I think that would be ugly. I'll go there if I have to though.
Any tips, help, pointers to ideas would be very appreciated. Thanks.
This is a common problem when writing expanding widgets.
You simply need to
max-height
to the element;overflow-y: auto
to instruct it to add scrollbars only when needed;top
position of the element plus the height
of the element is higher than the height
of the viewport (the visible area of the window); Take a look at the jsFiddle example made using jQuery (for convenience). Resize the window, and see what happens to the overflowing element.
Or just run the following code snippet:
$(".dropdown li").on('mouseenter mouseleave', function(e) {
var submenu = $('ul:first', this);
var submenuTop = submenu.offset().top;
var submenuHeight = submenu.height();
var viewportHeight = $(window).height();
var isOverflowing = (submenuTop + submenuHeight > viewportHeight);
if (isOverflowing) {
submenu.css("top", $(this).height() - submenuHeight);
} else {
submenu.css("top", 0);
}
});
* {
box-sizing: border-box;
}
body {
background: dodgerBlue;
}
.dropdown,
.dropdown li,
.dropdown ul {
list-style: none;
margin: 0;
padding: 0;
}
.dropdown {
width: 100%;
}
.dropdown ul {
position: absolute;
top: 100%;
left: 100%;
visibility: hidden;
display: none;
z-index: 1;
width: 200px;
max-height: 150px;
overflow-y: auto;
overflow-x: hidden;
}
.dropdown li {
position: relative;
float: left;
clear: both;
}
.dropdown li:hover {
z-index: 910;
}
.dropdown ul:hover,
.dropdown li:hover>ul,
.dropdown a:hover+ul,
.dropdown a:focus+ul {
visibility: visible;
display: block;
}
.dropdown a {
display: block;
background: #000;
color: #fff;
padding: 5px 20px;
text-decoration: none;
}
.dropdown ul li {
width: 100%;
}
.dropdown li:hover a {
background: #333;
}
.dropdown li a:focus,
.dropdown li a:hover {
background: #666;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<ul class="dropdown">
<li><a href="#">Link 1</a>
<ul>
<li><a href="#">Link 1</a>
</li>
<li><a href="#">Link 2</a>
</li>
<li><a href="#">Link 3</a>
</li>
<li><a href="#">Link 4</a>
</li>
<li><a href="#">Link 5</a>
</li>
</ul>
</li>
<li><a href="#">Link 2</a>
<ul>
<li><a href="#">Link 1</a>
</li>
<li><a href="#">Link 2</a>
</li>
<li><a href="#">Link 3</a>
</li>
</ul>
</li>
<li><a href="#">Link 3</a>
<ul>
<li><a href="#">Link 1</a>
</li>
<li><a href="#">Link 2</a>
</li>
</ul>
</li>
<li><a href="#">Link 4</a>
<ul>
<li><a href="#">Link 1</a>
</li>
<li><a href="#">Link 2</a>
</li>
<li><a href="#">Link 3</a>
</li>
<li><a href="#">Link 4</a>
</li>
<li><a href="#">Link 5</a>
</li>
<li><a href="#">Link 6</a>
</li>
<li><a href="#">Link 7</a>
</li>
<li><a href="#">Link 8</a>
</li>
</ul>
</li>
<li><a href="#">Link 5</a>
<ul>
<li><a href="#">Link 1</a>
</li>
<li><a href="#">Link 2</a>
</li>
<li><a href="#">Link 3</a>
</li>
<li><a href="#">Link 4</a>
</li>
<li><a href="#">Link 5</a>
</li>
</ul>
</li>
<li><a href="#">Link 6</a>
<ul>
<li><a href="#">Link 1</a>
</li>
<li><a href="#">Link 2</a>
</li>
<li><a href="#">Link 3</a>
</li>
<li><a href="#">Link 4</a>
</li>
<li><a href="#">Link 5</a>
</li>
</ul>
</li>
<li><a href="#">Link 7</a>
<ul>
<li><a href="#">Link 1</a>
</li>
<li><a href="#">Link 2</a>
</li>
<li><a href="#">Link 3</a>
</li>
<li><a href="#">Link 4</a>
</li>
<li><a href="#">Link 5</a>
</li>
<li><a href="#">Link 6</a>
</li>
<li><a href="#">Link 7</a>
</li>
<li><a href="#">Link 8</a>
</li>
</ul>
</li>
</ul>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With