7

有没有办法在文本输入上方显示自动完成结果集?

问题是我在灯箱应用程序中使用它。背景元素设置为页面高度和宽度的 100%,它自然不会随内容扩展。因此,如果文本框上方的内容增加太多,以至于输入被迫朝向页面底部,然后用户在其中输入内容,则会出现自动完成菜单,并且输入接近页面末尾,菜单导致出现滚动条

由于背景元素(深色)不会扩展以适应它,因为菜单是绝对定位的,所以页面底部显示为白色(与实际页面的颜色一致)而页面顶部变暗在视觉上看起来很难看.

那么有没有办法做到这一点,在自动完成菜单出现之前,应该检查输入的位置。如果距离顶部超过 300 像素,那么菜​​单应该出现在输入上方吗?这是代码:

<!DOCTYPE html>
<html>
<head>
<title>Filter</title>
<link type="text/css" href="ui/ui.css" rel="stylesheet" />
        <script type="text/javascript" src="jquery.js"></script>
        <script type="text/javascript" src="ui.js"></script>
<style>
div.filtertab { display: inline-block; height: 30px; background:url(filter.png); border-radius: 5px; position: relative;  margin: 10px 45px 10px 8px; cursor: pointer; -moz-user-select: none; box-shadow: 4px 2px 2px #aaaaaa; }

div.filtertab span.filtertext { position: relative;  margin-top: 4px; margin-left: 11px; margin-right: 1px;font-family:cursive,"Comic Sans"; font-size: 0.9em; float: left; display: inline-block; }

span.arrow { display: inline-block; border-top: 5px solid transparent; width: 0px; height: 0px; border-bottom: 5px solid transparent; border-right: 8.66px solid transparent; border-left: 8.66px solid #333333; margin-left: 7px; margin-top: 10.5px; }

.dateheaders { background: url(select.png); width: 120px; height: 28px; position: absolute; top: 0px; left: 0px; border-radius: 5px; cursor: pointer; display: inline-block; z-index: 55; }

.toheader { left: 183px }

.spandatew { font-weight: bold; position: relative; top: 2px; left: 6px; color: white; font-family: "lucida grande",tahoma,verdana,arial,sans-serif; font-weight: bold; color: white; font-size: 0.8em; }

div.arrow { height: 0px; width: 0px; position: absolute; display: inline-block; border-bottom: 5px solid transparent; border-right: 5px solid transparent; border-left: 5px solid transparent; border-top: 5px solid white;  right: 8px; top: 12px; }

input#from,input#to {width:107px;height:20px; position: relative; top: -30px; opacity: 0.01; cursor: pointer; }

input#from { left: 22px; }

input#to { left: 79px; }

div#ui-datepicker-div { left: -10px; }

div#diva1 {  width: 190px; position: absolute; display: none; z-index: 10; outline: none;}

div#diva2 {  width: 190px; position: absolute; display: none; z-index: 10; outline: none;}

#datecontainer { position: relative; width: 400px; height: 30px; background: red; left: 10px; }

.inpdiv { position: relative; margin-top: 6px; margin-left: 7px; background: #E2E6FF;  border-radius: 3px;  margin-bottom: 5px; display inline-block; float: left; margin-right: 3px; }

.inpdiv span.content { position: relative; top: 1px; left: 2px; padding: 2px 5px 6px 2px; font-size: 0.9em; display: inline-block; font-family: cursive,"Comic Sans";}

.inpdiv span.cancel { display: inline-block; border-radius: 3px; position: relative; top: 5px; margin: 3px 3px 3px 4px; height: 12px; width:12px; background: #bdbbae; cursor: pointer; }

.letter { position: absolute; display: inline-block; right: 4.4px; top: 4.7px; cursor: pointer; FONT-FAMILY: SANS-SERIF; FONT-SIZE: 0.9EM; }

div.friends { width: 400px;   position: relative;  overflow: hidden; border: 1px solid #4496e7; border-radius: 5px; cursor: text; height: 35px; height: auto !important; min-height: 35px;  left: 5px; }
div.friends2 { margin-top: 10px; }

div.friendsc { position: relative; top: 100px; left: 350px; width: 410px;  padding: 10px 0px; height: auto !important; height: 80px; min-height: 80px; background: green;}

div.clear { clear: both; width: 100%; height: 10px; }

button { position: absolute; top: 300px; left: 450px; }

input { position: relative; margin: 9px 0px 10px 10px; border: 0px solid white; float: left; max-width: 382px; }

div#outerfilter { width: 900px; background: grey;  position: relative; min-height: 400px; max-height: 500px; margin:auto; top: 10px; overflow: auto; padding-bottom: 20px; }
div#innerfilter { position: relative; top: 0px; left: 0px; width: 880px; min-height: 400px;background: #eaeaea; }
.filtersection { position: relative; float: left; width: 440px; min-height: 400px; height: auto !important; }
</style>
<script type="text/javascript">
$(document).ready(function(){
(function($){

$.fn.autoGrowInput = function(o) {

            o = $.extend({
                maxWidth: 1000,
                minWidth: 0,
                comfortZone: 70
            }, o);

            this.filter('input:text').each(function(){

                var minWidth = o.minWidth || $(this).width(),
                    val = '',
                    input = $(this),
                    testSubject = $('<tester/>').css({
                        position: 'absolute',
                        top: -9999,
                        left: -9999,
                        width: 'auto',
                        fontSize: input.css('fontSize'),
                        fontFamily: input.css('fontFamily'),
                        fontWeight: input.css('fontWeight'),
                        letterSpacing: input.css('letterSpacing'),
                        whiteSpace: 'nowrap'
                    }),
                    check = function() {

                        if (val === (val = input.val())) {return;}

                        // Enter new content into testSubject
                        var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                        testSubject.html(escaped);

                        // Calculate new width + whether to change
                        var testerWidth = testSubject.width(),
                            newWidth = Math.min((testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth, o.maxWidth - 1),
                            currentWidth = input.width(),
                            isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
                                                 || (newWidth > minWidth && newWidth < o.maxWidth);

                        // Animate width
                        if (isValidWidthChange) {
                            input.width(newWidth);
                        }

                    };

                testSubject.insertAfter(input);

                $(this).bind('keyup keydown blur update', check);

            });

            return this;

        };

    })(jQuery);

arr = ["Soumyashree Chakraborty", "Payel","Jinia","Soujinia","Apoorva","Mona","Shamarpita","Pratik","Pranendra","Bhushan","Bijesh","Salma","Swift","Anushka","Radhe","Amol","Bardha","Sujata","Rohit","Amit","Anuradha","Amrita","Ajay","Sumil","Sachin","Sourav","Anmol","Britannia","Anamika","Priyanka"];
$("span.letter").live('click',function() {
$(this).parent().parent().find("input").focus();
$(this).parent().remove();
  });

options = {
            source: arr.slice(0,5),
            minLength: 1,
            select: function(event,ui) {
            $('<span class = "inpdiv"><span class = "content">'+ui.item.value+'</span><span class = "cancel"></span><span class="letter">X</span></span>').replaceAll(this);
            $("<input type='text' size='3' />").appendTo(curautocomp).focus();
            event.preventDefault();
            },
            focus: function(e,ui) {
            e.preventDefault();
            },
            autoFocus: true,
            delay: 0
            };
$("input").live("focus", function (event) {
curautocomp = $(this).parent();
$(this).autocomplete(options);
$(this).autoGrowInput({
    comfortZone: 5,
    minWidth: 15,
    maxWidth: 382
});
});
















});
</script>
</head>
<body>
<div id = 'outerfilter'>
<div id = 'innerfilter'>
<div class = 'filtersection'>
<div class="filtertab"><span class="filtertext">Filter by Forum</span><span class='arrow'></span></div>
<br />
<div class = "friends">
<input type = "text" size = "2" value = "" />
</div>
<div class="filtertab"><span class="filtertext">Not Asked by</span><span class='arrow'></span></div>
<br />
<div class = "friends">
<input type = "text" size = "2" value = "" />
</div>
<div class="filtertab"><span class="filtertext">Has No Answer by</span><span class='arrow'></span></div>
<br />
<div class = "friends">
<input type = "text" size = "2" value = "" />
</div>
<div class="filtertab"><span class="filtertext">No of Answers</span><span class='arrow'></span></div>
<br />
<div class = "friends">
<input type = "text" size = "2" value = "" />
</div>
</div>
<div class = 'filtersection'>
<div class="filtertab"><span class="filtertext">Asked by</span><span class='arrow'></span></div>
<br />
<div class = "friends">
<input type = "text" size = "2" value = "" />
</div>
<div class="filtertab"><span class="filtertext">Has Answer by</span><span class='arrow'></span></div>
<br />
<div class = "friends">
<input type = "text" size = "2" value = "" />
</div>
<div class="filtertab"><span class="filtertext">Filter by Date</span><span class='arrow'></span></div>
<br />
<div id = 'datecontainer'>
<div class = 'dateheaders fromheader'>
<span class = 'spandatew'>Select a date</span>
<div class = 'arrow'></div>
</div>
<div class = 'dateheaders toheader'>
<span class = 'spandatew'>Select a date</span>
<div class = 'arrow'></div>
</div>
<div id = 'diva1'></div>
<div id = 'diva2'></div>
</div>
</div>
<div class = 'clear'></div>
</div>
</div>
</body>
</html>
4

3 回答 3

7

您需要open在自动完成选项中添加一个功能。从那里,您可以根据其当前位置和高度调整结果。这应该让你接近:

open: function(event, ui){
    var $input = $(event.target),
        $results = $input.autocomplete("widget"),
        top = $results.position().top,
        height = $results.height(),
        inputHeight = $input.height(),
        newTop = top - height - inputHeight;

    $results.css("top", newTop + "px");
}
于 2012-07-16T15:45:46.310 回答
5

这将 Ibstr 的解决方案和 Cupidvogel 的评论放在一起,同时添加窗口滚动位置检测:

open: function (event, ui) {
    var $input = $(event.target);
    var $results = $input.autocomplete("widget");
    var scrollTop = $(window).scrollTop();
    var top = $results.position().top; 
    var height = $results.outerHeight();
    if (top + height > $(window).innerHeight() + scrollTop) {
        newTop = top - height - $input.outerHeight();
        if (newTop > scrollTop)
            $results.css("top", newTop + "px");
    }
}

请注意,我使用的是 outerHeight 而不是 height,因为我还想考虑边框厚度。

只有当有足够的空间让它完全适合输入框上方时,自动完成才会将自己定位到顶部。

于 2012-08-23T12:16:55.463 回答
1
$( "#input_box input" ).autocomplete({
      position: { my: "left bottom", at: "left top"},
      source: availableTags
    });

这段代码意味着自动完成菜单(我的)的“左下角”应该放在输入框(at)的“左上角”。

尝试演示以了解这一点:https ://www.plus2net.com/jquery/msg-demo/autocomplete-position.php

于 2019-05-28T14:20:13.013 回答