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

試著忘記壹切 提交于 2019-12-10 23:44:35

问题


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>

回答1:


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:

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

Plugin Time

A better alternative would be to use a plugin to handle the whole operation start to finish. Here's one I just whipped up.

The plugin dynamically creates and destroys the span so it doesn't clutter up your html. This helps separate concerns and lets you delegate that functionality to another file and easily re-use with multiple elements across multiple pages.

(function($, window){
  var arrowWidth = 30;

  $.fn.resizeselect = function(settings) {  
    return this.each(function() { 

      $(this).change(function(){
        var $this = $(this);

        // create test element
        var text = $this.find("option:selected").text();
        var $test = $("<span>").html(text);

        // add to body, get width, and get out
        $test.appendTo('body');
        var width = $test.width();
        $test.remove();

        // set select width
        $this.width(width + arrowWidth);

        // run on start
      }).change();

    });
  };

  // run by default
  $("select.resizeselect").resizeselect();                       

})(jQuery, window);

You can initialize the plugin in one of two ways:

  1. HTML - Add the class .resizeselect to any select element:

    <select class="btn btn-select resizeselect">
      <option>All</option>
      <option>Longer</option>
      <option>A very very long string...</option>
    </select>
    
  2. JavaScript - Call .resizeselect() on any jQuery object:

    $("select").resizeselect()
    

Here's a Demo in Stack Snippets:

(function($, window){
  var arrowWidth = 30;

  $.fn.resizeselect = function(settings) {  
    return this.each(function() { 

      $(this).change(function(){
        var $this = $(this);

        // create test element
        var text = $this.find("option:selected").text();
        var $test = $("<span>").html(text);

        // add to body, get width, and get out
        $test.appendTo('body');
        var width = $test.width();
        $test.remove();

        // set select width
        $this.width(width + arrowWidth);

        // run on start
      }).change();

    });
  };

  // run by default
  $("select.resizeselect").resizeselect();                       

})(jQuery, window);
.btn-select {
  color: #333;
  background-color: #f5f5f5;
  border-color: #ccc;
  padding:7px;
}
<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 resizeselect">
        <option>All</option>
        <option>Longer</option>
        <option>A very very long string...</option>
      </select>
    </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>


来源:https://stackoverflow.com/questions/28308103/adjust-width-of-select-element-according-to-selected-options-width

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!