Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
817 views
in Technique[技术] by (71.8m points)

javascript - Adjust width of select element according to selected option's width

I want the select element to have the default option value's width which is shorter. When the user selects another option, the select element should resize itself so the whole text is always visible in the element.

I have found a solution in the question Auto resizing the SELECT element according to selected OPTION's width, but it doesn't work with bootstrap, and I don't know why.

Here's my attempt:

$(document).ready(function() {
  $('select').change(function(){
    $("#width_tmp").html($('select option:selected').text());
    // 30 : the size of the down arrow of the select box 
    $(this).width($("#width_tmp").width()+30); 
  });
});
.btn-select {
  color: #333;
  background-color: #f5f5f5;
  border-color: #ccc;
  padding:7px;
}
select {
  width: 60px;
}

#width_tmp{
  display : none;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>

<div class="form-group">
  <div class="input-group">

    <span class="input-group-btn">
      <select class="btn btn-select align-left">
        <option>All</option>
        <option>Longer</option>
        <option>A very very long string...</option>
      </select>
      <span id="width_tmp"></span>
    </span>

    <input type="text" class="form-control" placeholder="Search by...">

    <span class="input-group-btn">
      <button class="btn btn-default" type="button">
        <i class="fa fa-search"></i>
      </button>
    </span>

  </div>
</div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This issue occurs because the #width_tmp is nested under .input-group-btn so it inherits the font-size: 0; property from bootstrap. Therefore, the calculated width of the element is always zero:

screenshot

To fix this, just move the <span id="width_tmp"></span> so it's not inside the input group.


Pure JS Solution

// resize on initial load
document.querySelectorAll("select").forEach(resizeSelect)

// delegated listener on change
document.body.addEventListener("change", (e) => {
    if (e.target.matches("select")) {
        resizeSelect(e.target)
    }
})

function resizeSelect(sel) {
  let tempOption = document.createElement('option');
  tempOption.textContent = sel.selectedOptions[0].textContent;

  let tempSelect = document.createElement('select');
  tempSelect.style.visibility = "hidden";
  tempSelect.style.position = "fixed"
  tempSelect.appendChild(tempOption);
  
  sel.after(tempSelect);
  sel.style.width = `${+tempSelect.clientWidth + 4}px`;
  tempSelect.remove();
}

Demo in jsFiddle and Stack Snippets

// resize on initial load
document.querySelectorAll("select").forEach(resizeSelect)

// delegated listener on change
document.body.addEventListener("change", (e) => {
    if (e.target.matches("select")) {
        resizeSelect(e.target)
    }
})

function resizeSelect(sel) {
  let tempOption = document.createElement('option');
  tempOption.textContent = sel.selectedOptions[0].textContent;

  let tempSelect = document.createElement('select');
  tempSelect.style.visibility = "hidden";
  tempSelect.style.position = "fixed"
  tempSelect.appendChild(tempOption);
  
  sel.after(tempSelect);
  sel.style.width = `${+tempSelect.clientWidth + 4}px`;
  tempSelect.remove();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<select>
  <option value="2">Some longer option</option>
  <option value="1">Short option</option>
  <option value="3">An very long option with a lot of text</option>
</select>

<select>
  <option>Short option 2</option>
  <option>Some longer option 2</option>
  <option selected>An very long option with a lot of text 2</option>
</select>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...