开发者

How to get the minimal required width for a dijit ComboBox or FilteringSelect?

开发者 https://www.devze.com 2023-02-08 11:25 出处:网络
I\'m using ComboBox and FilteringSelect in a dialog and have yet been unable to make the controls have the minimal required width only, i.e. being just large enough to display the longest text from a

I'm using ComboBox and FilteringSelect in a dialog and have yet been unable to make the controls have the minimal required width only, i.e. being just large enough to display the longest text from a drop-down list. Also the control must not be set 开发者_JAVA百科to a fixed width since the actual content of the drop-down lists gets filled in from a translation database.

In plain html with a simple input of type text it works smooth just by default. However since even all examples at dojotoolkit.org show the very same behavior it seems to me that dojo introduces a minimum width for all those input controls. Thus I wonder if it can be done at all...

Thanks in advance!


I had the same problem; after some struggle, I decided to adapt this to my problem.

In my case, I was forced to use an old version of dojo, and the FilteringSelect were declarative, so I had to use a hack (the last three lines of the code below) to be sure my function would be executed at the right time.

So, the function below takes all dijit widgets, looks for those stored element is a select (getAllDropdowns), and for each it takes its options, copies the content in a new element moved outside of the visible screen and takes the width of that element, adjusted with padding (this may not be your case, so check getWidth); then it takes the max of those widths and compare it with the current length of the input element, and if the longest option is bigger, adjust the input and the outmost div widths.

This answer comes quite late, but since it was not easy for me to come to this solution, I thought it may be worth sharing.

// change dropdowns width to fit the largest option
function fixDropdownWidth() {
  var getAllDropdowns = function() {
    var dropdowns = [];
    dijit.registry.forEach(function(widget, idx, hash) {
      if (widget.store) {
        var root = widget.store.root;
        if (root && root.nodeName.toLowerCase() == 'select') {
          dropdowns.push(widget);
        }
      }
    });
    return dropdowns;
  };

  var getTesterElement = function() {
    var ret = dojo.query('tester');
    if (ret.length) {
      return ret;
    }
    else {
      document.body.appendChild(document.createElement('tester'));
      return dojo.query('tester');
    }
  };

  var getWidth = function(el) {
    var style = dojo.getComputedStyle(el);
    return el.clientWidth + parseInt(style.paddingLeft) + parseInt(style.paddingRight);
  };

  var getOptionWidth = function(option) {
    var testEl = getTesterElement();
    testEl[0].innerHTML = option.innerHTML;
    return getWidth(testEl[0]);
  };

  var dropdowns = getAllDropdowns();
  var testEl = getTesterElement();
  dojo.style(testEl[0], {
    position: 'absolute',
    top: -9999,
    left: -9999,
    width: 'auto',
    whiteSpace: 'nowrap'
  });
  for (var i = 0; i < dropdowns.length; i++) {
    var input = dropdowns[i].textbox;
    dojo.style(testEl[0], {
      fontSize: dojo.style(input, 'fontSize'),
      fontFamily: dojo.style(input, 'fontFamily'),
      fontWeight: dojo.style(input, 'fontWeight'),
      letterSpacing: dojo.style(input, 'letterSpacing')
    });
    var max = 0;
    var treshold = 5;
    dojo.query('option', dropdowns[i].store.root).forEach(function(el, idx, list) {
      max = Math.max(max, getOptionWidth(el) + treshold);
    });
    if (max > getWidth(dropdowns[i].textbox)) {
      var icon = dojo.query('.dijitValidationIcon', dropdowns[i].domNode)[0];
      dojo.style(dropdowns[i].textbox, {width: max + 'px'});
      var width = max + getWidth(icon) + getWidth(dropdowns[i].downArrowNode) + treshold;
      dojo.style(dropdowns[i].domNode, {
        width: width + 'px'
      });
    }
  }
}


dojo.addOnLoad(function() {
  dojo._loaders.push(fixDropdownWidth);
});


var dropDowns = [];
var getAllDropdowns = function (dropDowns) {
    array.forEach(dijit.registry.toArray(), function (widget) {
        if (widget.store) {
            if (widget.domNode.classList.contains("dijitComboBox")) { 
                dropDowns.push(widget);
            }
        }
    });
};

getAllDropdowns(dropDowns);

var maxLength = 0;
array.forEach(dropDowns, function (dropDown) {
    var opts = dropDown.get("store").data;
    array.forEach(opts, function (option) {
    var optionValue = option[dropDown.get("searchAttr")];
    var dropDownCurrentStyle = window.getComputedStyle(dropDown.domNode);
    var currentOptionWidth = getTextWidth(optionValue, dropDownCurrentStyle.fontStyle, dropDownCurrentStyle.fontVariant, dropDownCurrentStyle.fontWeight, dropDownCurrentStyle.fontSize, dropDownCurrentStyle.fontFamily);
    if (currentOptionWidth > maxLength) {
        maxLength = currentOptionWidth;
    }
});

dropDown.domNode.style.width = maxLength + "px";
    maxLength = 0;
});

function getTextWidth(text, fontStyle, fontVariant, fontWeight, fontSize, fontFamily) {
    // re-use canvas object for better performance
    var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
    var context = canvas.getContext("2d");
    var font = fontStyle + " " + fontVariant + " " + fontWeight + " " + fontSize + " " + fontFamily;
    context.font = font;
    canvas.innerText = text;
    var metrics = context.measureText(text);

    return metrics.width + 25; //change this to what you need it to be
}               
0

精彩评论

暂无评论...
验证码 换一张
取 消