Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with responsive width #3278

Closed
fredmalone opened this issue Apr 23, 2015 · 36 comments · Fixed by #5559
Closed

Issues with responsive width #3278

fredmalone opened this issue Apr 23, 2015 · 36 comments · Fixed by #5559

Comments

@fredmalone
Copy link

Unless I am missing something (I apologize if I have), select2 is not fully responsive. Look at this code:

    <div class="col-sm-6">
        <div class="form-group">
            <label>Submit to</label>
            <select class="form-control" id="SubmitQueue" name="SubmitQueue">
                <option value="1">Subsequent Civil</option>
                <option value="2">Subsequent Criminal</option>
                <option value="3">Judge Order - Civil</option>
                <option value="4">Review Sign</option>
                <option value="5">Subsequent Domestic Family</option>
                <option value="6">Judge Order - Criminal</option>
            </select>
        </div>
    </div>

The original select has 100% width from the form-control class. Select2 is creating a fixed width container. Thus, when I resize the window the select2 container does not resize as it should since the col-sm-6 class is a percentage.

So did I miss something in my initialization or is this an issue?

EDIT: OK. I looked throught the code and I noticed that the _resolveWidth doesn't even attempt to get a percentage width from CSS and only works with an inline style. I can live with that. How did it work in 3.5.2 without the inline style?

@eobeda
Copy link

eobeda commented Apr 26, 2015

What I was seeing, is that the 100% width is being converted into 100px. Hence the loss in responsiveness. Are your element initially hidden ? I was setting the option width to 100%
for example: options.width = '100%';
and additionally using the following to work-around some of the issues. I never got the place-holder text working on long strings, they get truncated at approx 100px. Manually clearing the selection worked, but I never got a programmatic solution.
//// Fix a select2 ver 4.x issue with widths on initially hidden elements
if ($(element).not(':visible')) {
$('.select2-search__field').width("100%"); // The placeholder text needs help as well.

@fredmalone
Copy link
Author

No, they are not initially hidden. I will look at that options.width to see if it works for me.

@alexcroox
Copy link

I've found that if you have select 2 in a hidden div, when you later reveal that div the width is wrong, is there a method to re-initialise the positioning?

@alexcroox
Copy link

Temporary workaround is to specify width in the init() I can get away with this as all mine happen to work fine 100% width.

.select2({ width: '100%' });

@hhubik
Copy link

hhubik commented Sep 24, 2015

Also having this issue. Have a select2 (v4) in a Bootstrap v3 accordion panel that is closed on page load. When I expand the panel for the first time, the width of the placeholder text is set to 100px even though the select2 element is much wider based on the markup and the browser window size. After I enter one or two values and then delete them, the placeholder displays correctly.

My HTML markup is
<select id="mySelect" class="form-control" style="width: 80%;" multiple="multiple"></select>

The select2 is getting remote data via Ajax, in case it matters.

Also using the bootstrap theme for select2.

This is happening on a desktop (IE 11), and I am not changing the display/window size, so I don't think this can be dismissed by saying select2 is not responsive.

Setting width to 100% as recommended above does not seem to fix this.

@abr4xas
Copy link

abr4xas commented Apr 16, 2016

I have the same problem using https://github.com/select2/select2-bootstrap-theme
js

    // Select2
    $('#mySelect').select2({
        theme: "bootstrap",
        placeholder: 'Categorias...',
        allowClear: true,
        tags: true,
        maximumSelectionLength: 3,
        width: '100%'
    });

html

<div class="form-group">
  <label class="sr-only" for="categorias">Categorias</label>
  <select id="mySelect" class="form-control" style="width: 100%;" multiple="multiple">
    <option>Tour de Compras</option>
    <option>Guia</option>
    <option>Internacional</option>
    <option>Desayuno</option>
    <option>Traslados</option>
  </select>
</div>

animacion

screenshot from 2016-04-16 17 50 52

@ShalluOodles
Copy link

I have problem with select tag .i.e when i resize the windows , it doesn't work, doesn't show the options list.

@tchiotludo
Copy link
Contributor

I use the select2-bootstrap-theme and with this simple hack
$(self._select2).parent().find(".select2-container").css('width', ''); all is working fine on my side.

why not allow a an option width:'none' that doesn't set the width on :

  Select2.prototype._resolveWidth = function ($element, method) {
    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
    // +++
    if (method == 'none') {
        return null;
    }
    // end +++

    if (method == 'resolve') {
      var styleWidth = this._resolveWidth($element, 'style');

      if (styleWidth != null) {
        return styleWidth;
      }

      return this._resolveWidth($element, 'element');
    }

Only the css will be responsible on width on the select2 container.

@seanjamu
Copy link

seanjamu commented Nov 4, 2016

Hello, I add custom.css

@media screen and (max-width: 767px) {
    .select2 {
        width: 100% !important;
    }
}

and solved

@mohammad-melhem
Copy link

I tried adding the media query that seanjamu suggested but it's still not working. I'm lost what is the real solution for not breaking on window resize with bootstrap? it still breaks even on the demo page when you zoom in and out. Also using the theme above didn't solve it.

Any advice would be really appreciated. Thx.

@drvid
Copy link

drvid commented Nov 17, 2016

Using Bootstrap theme I have the same issue. @seanjamu 's CSS override works well enough for now, but why on earth are they defining the width of an input using an inline style with pixels?

@s0By
Copy link

s0By commented Nov 30, 2016

@tchiotludo props for this method. I think it would be nice to have this implemented for "more advanced" users. I had css widths set since select2 3.5 and now I either need to either add !important to every class (which is lame) or have a width: 'none' solution, which is pretty neat.

@kevin-brown could you consider this?

@BallisticPain
Copy link

@tchiotludo solution worked for me with Angular 2.

this.element.nativeElement.parent().find(".select2-container").css('width', '');

@pixelplant
Copy link

pixelplant commented Jan 29, 2017

It was probably not the case when @tchiotludo commented on his lines of code, but now you can just pass a width: '' (empty string) parameter to your select2 config and no width will be added. You will need to handle the width in your css code though, so add a width:100% or whatever you need depending on the screen resolution.

To be more precise, here is how I call my code:
$('.my-select').select2({ theme: 'custom', minimumResultsForSearch: -1, width: '' });

@nelson6e65
Copy link
Contributor

In the HTML5 data-* attribute, you can solve this by setting data-width:

<select id="customer" name="customer" class="form-control select2"
    data-width="100%" required>
</select>

@pfleu
Copy link

pfleu commented Apr 28, 2017

For those experiencing truncated placeholder with v4 of select2, here is a working solution by @labster found here:
.select2-selection--multiple .select2-search--inline .select2-search__field { width: auto !important; }

@demedos
Copy link

demedos commented Oct 12, 2017

Thanks @tchiotludo , your comment was really useful. It seems like the problem is select2-bootstrap-theme setting a fixed with on the select container; this solves the problem for me:

$(function() { 
  $('#controlID').select2({ theme: 'bootstrap' }); 
  $('#controlID').parent().find('.select2-container').css('width', ''); 
});

@besi
Copy link

besi commented Oct 15, 2017

I do the following to accomplish @alexcroox's suggestion in a global scope:

$.fn.select2.defaults.set( "width", "100%" );

@aManNamedJed
Copy link

You're the real MVP @alexcroox

@alexweissman alexweissman changed the title Select2 is not fully responsive Issues with responsive width Dec 14, 2017
campersau pushed a commit to campersau/select2 that referenced this issue Mar 22, 2018
@wnunez09
Copy link

wnunez09 commented May 26, 2018

@klawrow
Copy link

klawrow commented Jul 24, 2018

Thanks @alexcroox! My instance was with the select being initially hidden, then upon display the width would reset to 100px versus what I set as 100%. It's a bit of a shotgun solution, but hey it works for my case.

Update:
Found that if you explicitly set the style/width of the select2 will render properly regardless if initially hidden in a div.

@pedrofurtado
Copy link
Contributor

We don't have immediate plans to provide this. We are focused to fix some major UI bugs (that are majority of issues and PR's). But if you open a PR with unit tests, I will be glad to review and approve if everything is ok 👍

@hussonkevin
Copy link

hussonkevin commented Oct 17, 2018

correctly fixed with sass code (for long placeholder) :

.select2-selection--multiple{
    .select2-selection__rendered{
        li:first-child{
            &.select2-search{
                width: 100% !important;
                input{width: 100% !important;}
            }
        }
    }
}

@rishav00a
Copy link

Finally Solved this issue,
previously i was overriding the styling using JQuery but it was not able to find that element.
As a solution what is did is

-> Create a js function

function chsize() {
$(".select2-container--default").css("width","100%"); // this onw works only on Desktop
$("head").append($("")); // this will work everyehere whether it is Mobile, Desktop
}

-> Call the function on page load inside body tag

-> Here is my CSS file override.css
.select2-container--default
{
width: 100%;
}

Enjoy :)

@ikarthikng
Copy link

Using @alexcroox method I added the following CSS to my page

.select2 { width: 100% !important; }

and removed placeholder option during initialization in JavaScript. This is the only hack which has worked for me so far after spending many hours searching for a work around using CSS and JavaScript. I am using 4.0.2 version of select2.

@Tahirhan
Copy link

Tahirhan commented Apr 8, 2019

Hi, I had same issue in table element and managed to solve the issue with this code :

                td_element.appendChild(select_element);
                
                var selectWidth = document.getElementById('select_element_id').clientWidth;

                $("#select_element_id").select2({
                    placeholder: "Placeholder..",
                    allowClear: true,
                    width: selectWidth.toString()+'px'
                });

kevin-brown pushed a commit that referenced this issue Jul 9, 2019
This allows for more accurate resolution of the width when compared
to the `resolve` method. This is more relevant for jQuery 1.x, where
the `resolve` method cannot find the width of a hidden select box,
but it also applies to newer versions of jQuery where the `width()`
method provided by jQuery doesn't fully match `getComputedStyle()`.

Fixes #3278
Fixes #5502
Closes #5259
kevin-brown added a commit that referenced this issue Jul 9, 2019
This allows for more accurate resolution of the width when compared
to the `resolve` method. This is more relevant for jQuery 1.x, where
the `resolve` method cannot find the width of a hidden select box,
but it also applies to newer versions of jQuery where the `width()`
method provided by jQuery doesn't fully match `getComputedStyle()`.

Fixes #3278
Fixes #5502
Closes #5259
@irshdweb
Copy link

irshdweb commented Dec 5, 2019

I had the same issue in angular. I added
::ng-deep .select2-container{
display:block !important;
width: 100% !important;
}

and it's working

@oesah
Copy link

oesah commented Aug 15, 2020

In the HTML5 data-* attribute, you can solve this by setting data-width:

<select id="customer" name="customer" class="form-control select2"
    data-width="100%" required>
</select>

This is a better solution than using css width: 100%, because that might impact the outer html DOM, as it did with my project. If I used css and clicked on the select button, I could scroll on the x and x axis. Using data-width="100%" on the element, that issue was resolved and still gave the same styling as with css.

@noobkisser
Copy link

In the HTML5 data-* attribute, you can solve this by setting data-width:

<select id="customer" name="customer" class="form-control select2"
    data-width="100%" required>
</select>

This was by far the best solution with minimal cognitive load. Thumbs up

@nelson6e65
Copy link
Contributor

This was by far the best solution with minimal cognitive load. Thumbs up

Thanks!

@LufoX11
Copy link

LufoX11 commented Nov 28, 2021

I'm working with Bootstrap 4 and tabs. The select2 elements are using some wrappers around them, so width 100% doesn't work for me since it breaks those wrapping elements:
image
image
I also have a lot of specific configuration including parsing functions and a general initialization function like $(".select2").select2({...}), so simply calling .select2() will also break functionality. I tried to, at least, get the object initial configuration from the element, but I wasn't be able to do it (do somebody know how to do it?).

My solution was to put all of this initialization function inside a global scope var and call it after tab is shown:

// General initialization
window.__initSelect2 = function () {
    function parser(state) {...}
    $(".select2").select2({
        templateResult: parser,
        templateSelection: parser
    }).off("select2:unselecting").on("select2:unselecting", function () {
        ...
    }).off("select2:opening").on("select2:opening", function (e) {
        ...   
    });
};
__initSelect2();
// Tabs (I'm using CoreUI theme, so the event name is a slightly different than the original "shown.bs.tab"
$('#tabs a[data-toggle="tab"]').on("shown.coreui.tab", function (e) {
    if (e.target.dataset.tab == "my-desired-tab") {
        __initSelect2();
    }
});

Fortunately bindings (like $(...).on("change", ...)) are not being detached after reinitializating the element, so you won't lose functionality.

I wish you people include something like .select2("refresh") in the future to avoid doing horrible workarounds like this one 😞

@mertsei
Copy link

mertsei commented Feb 10, 2023

Found a simple and hassle-free solution, without the need to manually set any styles or anything like that.
I would just add an addEventListener('resize') along with a function that calls .select2('destroy') on all the inputs that I want to be resized, so that they could be initialized again — with a slight delay, which seems to be necessary but is unperceivable amidst other resizing/replacement happening on the page:

window.addEventListener('resize', fleetFiltersResize);

function fleetFiltersResize() {
    setTimeout(function() {
        for (let i = 1; i <= filtersItem.length; i++) {
          $(`.fleet-filters__item.${i}`).select2('destroy');
        }

        fleetFiltersInitialize();
    }, 300);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet