dojo 如何获得dijit ComboBox或FilteringSelect所需的最小宽度?

1mrurvl1  于 2022-12-20  发布在  Dojo
关注(0)|答案(2)|浏览(285)

我在一个对话框中使用ComboBox和FilteringSelect,但还不能使控件只具有所需的最小宽度,即足够大以显示下拉列表中最长的文本。此外,控件不能设置为固定宽度,因为下拉列表的实际内容是从翻译数据库中填充的。
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...
先谢了!

but5z9lq

but5z9lq1#

我也有同样的问题经过一番努力,我决定使用this来解决我的问题。
在我的例子中,我被迫使用旧版本的dojo,并且FilteringSelect是声明性的,因此我必须使用hack(下面代码的最后三行)来确保我的函数将在正确的时间执行。
因此,下面的函数获取所有dijit小工具,查找那些存储的元素是selectgetAllDropdowns),并为每个元素获取其选项,将内容复制到可见屏幕外的新元素中,并获取该元素的宽度,使用填充进行调整(您可能不是这种情况,所以请检查getWidth);然后它取这些宽度中的最大值,并将其与input元素的当前长度进行比较,如果最长的选项更大,则调整input和最外面的div宽度。
这个答案来得相当晚,但由于我得出这个解决方案并不容易,我认为它可能值得分享。

// 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);
});
d6kp6zgx

d6kp6zgx2#

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
}

相关问题