How to get the minimum required width for a Dijit ComboBox or FilteringSelect?

I use ComboBox and FilteringSelect in a dialog box and so far have not been able to get the controls to have the minimum required width, i.e. be large enough to display the longest text from the drop-down list. In addition, the control should not be set to a fixed width, since the actual contents of the drop-down lists are populated from the translation database.

In simple html with simple text input, it only works by default. However, since even all the examples on dojotoolkit.org show the same behavior, it seems to me that dojo introduces a minimum width for all of these input controls. So I wonder if this can be done at all ...

Thanks in advance!

+3
source share
2 answers

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

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

, dijit, - select (getAllDropdowns), , , , ( , getWidth); , , 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);
});
0
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

Source: https://habr.com/ru/post/1790121/


All Articles