Changing width of jquery-ui autocomplete widgets individually
Asked Answered
K

11

25

I'm working with mutiple jquery-ui autocomplete widgets on one page and want to be able to set the widths of each one individually. Currently, I'm doing it like this:

$($('.ui-autocomplete')[0]).width(150);
$($('.ui-autocomplete')[1]).width(105);
$($('.ui-autocomplete')[2]).width(80);

Which isn't really a solution since the user is able to trigger various autocompletes in different orders, and this code just styles them based on the order they are added to the DOM.

When autocomplete is triggered, it seems to create a <ul> and then position it under the input box that triggered it. Unfortunately, I can't find any unique identifiers in this generated <ul> to latch on to and apply some CSS.

My issue is different from this one, since I'm using just the default autocomplete, and not the autocomplete-combobox.

Also, digging into the autocomplete <ul> and matching different autocomplete box widths with the values inside the list doesn't work either, since the values are dynamically generated.

Any ideas?

Korney answered 5/1, 2011 at 17:29 Comment(0)
S
50

I resolved this issue using the 'open' event available. I needed a way to dynamically set the width, along with other items and did not want extra markup.

$('#input').autocomplete({  
    source: mysource,  
    appendTo: '#div',  
    open: function() { $('#div .ui-menu').width(300) }  
});
Scientism answered 19/4, 2011 at 21:46 Comment(6)
Whoa, that's totally a great solution.Korney
2014 checking in - this is still an amazing solution.Winograd
Notice in this, #div is an element on the page: appendTo: '#div'Maffick
this didnt work for me; its not clear what #div is with respect to the original #input - @Martin Lögdberg answer worked for meMayer
@Mayer that #div is another element (preferably empty and near that #input), where the ui-menu would be placed inside. This also didn't work for me, so I figured out a different way exclusively with CSS.Dissolute
I also needed to set the width dynamicly (simply adding some pixels) and then .width() failed for me, but .outerWidth() did exactly the desired thing. Might be, I misunderstand the difference between these two methods, but it also might be, I am not the only one. ;)Zeniazenith
A
33

I like luqui's answer. But if you are in a situation where you cannot use the appendTo feature (could be due to overflow hidden etc.), you can use the code below to make sure that you are making changes to the correct list.

$('#input').autocomplete({  
    source: mysource,  
    open: function() { 
        $('#input').autocomplete("widget").width(300) 
    }  
});

Ref: http://docs.jquery.com/UI/Autocomplete#method-widget

Anatol answered 22/5, 2011 at 20:35 Comment(0)
S
15

If you have multiple controls that use autocomplete, a reasonably elegant solution is to retrieve the widget attached to the control at the last moment and modify its CSS:

$(document).ready(function() {
    $("input#Foo").autocomplete({
        source: source
    });
    $("input#Bar").autocomplete({
        source: source,
        open: function(event, ui) {
            $(this).autocomplete("widget").css({
                "width": 400
            });
        }
    });
});

View Demo.

As mentioned above, the width of autocomplete list is calculated at the very last moment hence you must modify it in the open event.

Stringpiece answered 25/5, 2011 at 7:38 Comment(1)
$(this).autocomplete('widget').width(300); on open method works fine to me =), thanks much.Bacteroid
C
4

You can get "ui-menu" widget attached to the <input> having autocomplete with respect of $('#myinput').data("autocomplete").menu. So to change the width you can use

$('#myinput').autocomplete({
    source: yourUrlOrOtherSource,
    open: function () {
        $(this).data("autocomplete").menu.element.width(80);
    }
});
Cryptonym answered 7/8, 2011 at 10:0 Comment(0)
O
1

You could wrap the input box that is triggering the auto-complete in a div, give the div a specific id, and then append the auto complete ul to that div rather than to the body of the document. That way you can target it with css based upon the div.

<!- this is how i would set up the div -->
<div class='autoSuggestWrapper' id='wrapper1'>
     <input class='autocomplete'>
</div>
<script>/* this is a way to config the autocomplete*/
   $( ".autocomplete" ).autocomplete({ appendTo: ".autoSuggestWrapper" });
</script> 
Ostracon answered 5/1, 2011 at 17:42 Comment(4)
That doesn't seem to have much effect. The auto complete is still appearing outside a parent element.Korney
How do you have your html around the Input set up and how are you initializing the autocomplete?Ostracon
<span class="wrapper"><input class="autocomplete1"/></span> And I'm initializing the autocomplete through a wrapper function. The function is not called on page load, but I'm not sure that affect anything in terms of the styling.Korney
Try wrapping it in a div rather than a <span>. Then attempt the appendTo in the config above. I'm pretty certain you can't append a ul inside a span and is probably why the appendTo code didn't work. Also, you will want to add an id to each of the wrapper's so you can specify which one gets which width.Ostracon
D
1

Without using extra Javascript code, you can use 1 simple CSS line:

<style type="text/css">
    .ui-menu,.ui-menu>.ui-menu-item,.ui-menu-item>a {min-width:800px !important}
</style>

So why does this work with min-width?

Simply because width gets overwritten by the JS, sometimes even with solutions that use open: function(event, ui) { ... } (like rkever's answer, which did not work in my case). However, min-width is not overwritten, so it comes in handy.

Also, if you do not want to use !important, you can further detail the rule with the remaining classes:

.ui-autocomplete.ui-menu.ui-widget.ui-widget-content.ui-corner-all,.ui-menu>.ui-menu-item,.ui-menu-item>a
 {min-width:800px}

This avoided me further JS hacks, hope it helps!

Dissolute answered 7/12, 2015 at 17:5 Comment(1)
perfect answer...batter to use this instead of JS codeMalchus
T
0

I like @Martin Lögdberg answer but if you're using fixed sized widths rather than doing some fancy maths on the returned results to set the width, then you could also just set the width in CSS

ul .ui-autocomplete {
  width: 50%;
}
Taal answered 22/8, 2012 at 16:0 Comment(0)
C
0

An improvement on Martin Lögdberg answer. This worked better for me because I had many textboxes on the page

$('.some-class').each(function(){
   var txt = $(this);
   txt.autocomplete({  
      source: mysource,  
      open: function() { 
          txt.autocomplete("widget").width(txt.outerWidth());
      }
   });  
});
Culvert answered 1/5, 2014 at 16:6 Comment(0)
D
0

Reading API, I've just add a class ui-front to the parent's div of my input, and that works fine.

<div class="ui-front">
    <label for="autosample" class="required">example</label>
    <input name="autosample" class="default-autocomplete" type="text">
</div>

See here :

[...] the parents of the input field will be checked for a class of ui-front. If an element with the ui-front class is found, the menu will be appended to that element. Regardless of the value, if no element is found, the menu will be appended to the body.

The appended element determine the position and width of the menu.

Dara answered 10/1, 2015 at 10:12 Comment(0)
C
0

As of jQuery UI 1.10, the autocomplete widget was rewritten using the widget factory. As part of that, the autocomplete now contains a _resizeMenu extension point, which is called when sizing the menu before displaying.

$('#input').autocomplete({  
    source: mysource,  
    appendTo: '#div',  
    _resizeMenu: function() {
        this.menu.element.outerWidth( 500 );
    }
});
Calvo answered 5/11, 2015 at 15:47 Comment(0)
A
0

I managed to solve this with CSS by adding float to the autocomplete menu.

.ui-autocomplete { float: left; }

Since the autocomplete menu is positioned absolute and a direct child of the <body>. I guess it gets it's max width from the body, and since it's position absolute it can't be displayed as inline-block to avoid taking all the available space.

Also .ui-autocomplete { width: 1%; } seems to work.

Amphichroic answered 8/11, 2016 at 12:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.