2011-02-05 52 views
3

我在对话框中使用了ComboBox和FilteringSelect,但仍然无法使控件仅具有最小的所需宽度,即仅够大到显示下拉列表中最长的文本。此外,控件不得设置为固定宽度,因为下拉列表的实际内容会从翻译数据库填充。如何获得dijit ComboBox或FilteringSelect所需的最小宽度?

在简单的输入类型文本的纯html中,它默认工作平稳。然而,即使dojotoolkit.org上的所有示例都显示出相同的行为,我认为dojo为所有这些输入控件引入了最小宽度。因此,我想知道它是否可以完成...

在此先感谢!

回答

0

我有同样的问题;经过一番努力,我决定改编this来解决我的问题。

就我而言,我被迫使用旧版本的dojo,而FilteringSelect是声明式的,所以我必须使用hack(以下代码的最后三行)来确保我的函数将被执行在正确的时间。

所以,以下的功能通吃dijit的小部件,查找这些存储单元是selectgetAllDropdowns),并为每个需要它的选项,复制一个新的元素内容移动可视屏幕的外侧,采用了该元素的宽度,用填充调整(这可能不是你的情况,所以请检查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 
}