Thallius
Thallius

Reputation: 2619

How to change select2 width dynamically after init

I have a kind of info panel on the right side of my apps page. This panel can be resized in width by dragging and moving the border (E.g. Like you can resize the columns in a windows finder) In the panel I have a select2 to search for something. I initialize this select2 with

    let infoPanelSiteId = $('#infoPanelSiteId');
    infoPanelSiteId.select2(
        {
            ajax:
                {
                    dataType: 'json',
                    delay: 250,
                    url: BACKEND_URL + '/infopanel/searchsites.php',
                    processResults: function (data)
                    {
                        return {results: data.data};
                    }
                },
            width: infoPanel.width - 15,
            placeholder: i18next.t('default:infopanel.site.search')
        })
        .on('change', function ()
        {
            let data = infoPanelSiteId.select2('data');
            if (data[0])
            {
                data = data[0];
                InfoPanel.setInfoPanelSiteById(data.id);
            }
        });

Now if the user resizes the info panel the select2 is not resizing because it has a fixed width. Problem is, that the display of the panel is using display: table and display: table-cell which is necessary on other purposes. So I cannot work with width: 100% or width: auto because a table cell does ignore a css width.

So I look for a possibility to change the inlined width in the select2 container

select2 select2-container select2-container--default select2-container--below

I tried it with

$('#infoPanelSiteId').next().css('width' : (infopanel.width -10) + 'px !important');

and

$('.select2-container--below').css('width' : (infopanel.width -10) + 'px !important');

but that does not work.

Any suggestions?

Edit:

Here is a fiddle how it should work but it doesnt

https://jsfiddle.net/wazrdky2/

Upvotes: 1

Views: 1290

Answers (1)

Frenchy
Frenchy

Reputation: 17037

if you want to change the width when the class select2-container--below appears do that: (event open and close)

$('#yourselect2ID').on('select2:open', function (e) {
   $("body > span.select2-container--below").css("width", "600px");
});

$('#example').select2();



$('#example').on('select2:open', function (e) {
   $("body > span.select2-container--below").css("width", "100px");
});

$('#example').on('select2:close', function (e) {
   $("body > span.select2-container--below").css("width", "300px");
});

//$('#example').select2({dropdownCssClass : 'bigdrop'});
.bigdrop {
    width: 100px !important;
}
<html>
  <body>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>

<select id="example" multiple="multiple" style="width: 300px">
    <option value="Apple">Apple</option>
    <option value="Bat">Bat</option>
    <option value="Cat">Cat</option>
    <option value="Dog">Dog</option>
    <option value="Elephant">Elephant</option>
    <option value="View/Exposure">View/Exposure</option>
    <option value="View / Exposure">View / Exposure</option>
    <option value="Dummy - Data">Dummy - Data</option>
    <option value="Dummy-Data">Dummy-Data</option>
    <option value="Dummy:Data">Dummy:Data</option>
    <option value="Dummy(Data)">Dummy(Data)</option>    
</select>

  </body>
</html>

or you could use Custom CSS style like this:

$('#yourselect2ID').select2({dropdownCssClass : 'bbbdrop'});

.bbbdrop {
    width: 100px !important;
}

$('#example').select2({dropdownCssClass : 'bigdrop'});
.bigdrop {
    width: 100px !important;
}
<html>
  <body>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>

<select id="example" multiple="multiple" style="width: 300px">
    <option value="Apple">Apple</option>
    <option value="Bat">Bat</option>
    <option value="Cat">Cat</option>
    <option value="Dog">Dog</option>
    <option value="Elephant">Elephant</option>
    <option value="View/Exposure">View/Exposure</option>
    <option value="View / Exposure">View / Exposure</option>
    <option value="Dummy - Data">Dummy - Data</option>
    <option value="Dummy-Data">Dummy-Data</option>
    <option value="Dummy:Data">Dummy:Data</option>
    <option value="Dummy(Data)">Dummy(Data)</option>    
</select>

  </body>
</html>

you could mix both:

$('#example').select2({dropdownCssClass : 'bigdrop'});

$('#example').on('select2:open', function (e) {
   $("body > span.select2-container--below").css("width", "100px");
});

$('#example').on('select2:close', function (e) {
   $("body > span.select2-container--below").css("width", "300px");
});
.bigdrop{
    width: 100px !important;

}
<html>
  <body>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>

<select id="example" multiple="multiple" style="width: 300px">
    <option value="Apple">Apple</option>
    <option value="Bat">Bat</option>
    <option value="Cat">Cat</option>
    <option value="Dog">Dog</option>
    <option value="Elephant">Elephant</option>
    <option value="View/Exposure">View/Exposure</option>
    <option value="View / Exposure">View / Exposure</option>
    <option value="Dummy - Data">Dummy - Data</option>
    <option value="Dummy-Data">Dummy-Data</option>
    <option value="Dummy:Data">Dummy:Data</option>
    <option value="Dummy(Data)">Dummy(Data)</option>    
</select>

  </body>
</html>

if you want dynamically set the width of select2, without reinitializing it: (change the selector)

    let width = 300;
    
    let infoPanelSiteId = $('#infoPanelSiteId');
        infoPanelSiteId.select2(
            {
                
                width: "resolve",
                placeholder: 'Placeholder'
            })
            .on('change', function ()
            {
            });

    let interval = setInterval(() =>
  {
    width +=10;
    
        $(".infopanelPanel span.select2-container").css("width", width + "px");
    if(width == 500)
        clearInterval(interval);
  }, 500);
<html>
  <body>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>

    <div class = "infopanelPanel">
        <div class = "infoPanelTitleDiv">
            <div class = "infoPanelTitleText">
                <label><select id = "infoPanelSiteId" class = "editSelect" style="width:400px">
                     <option value="Apple">Apple</option>
                      <option value="Bat">Bat</option>
                      <option value="Cat">Cat</option>
                      <option value="Dog">Dog</option>
                </select></label>
            </div>
        </div>
    </div>
  </body>
</html>

Upvotes: 1

Related Questions