На основе схемы PrimeFaces Р:ширина selectOneMenu

Я хочу p:selectOneMenu ширина для автоматического относительно родительской клетки не в отношении к ценности его.

<p:panelGrid>
    <p:row>
        <p:column><p:outputLabel value="Value01" for="idInput01"/></p:column>
        <p:column><p:inputText  value="#{bean.input01}" id="idInput01" /></p:column>
        <p:column><p:outputLabel value="Value02" for="idSelect" /></p:column>
        <p:column>
            <p:selectOneMenu value="#{bean.selectedObject}" id="idSelect" converter="objectConverter">
                <f:selectItems value="#{bean.objectsList}" var="varObject" itemLabel="#{varObject.label}" itemValue="#{varObject}" />
            </p:selectOneMenu>
        </p:column>
    </p:row>
</p:panelGrid>

что у меня есть :

enter image description here

что я ожидаю:

enter image description here

примечание: Я не хочу указывать фиксированную ширину.

9 ответов


Я обошел .ui-selectonemenu, .ui-selectonemenu-label в:

.ui-selectonemenu{
     width: 100% !important;
}
.ui-selectonemenu-label{
     width: 100% !important;
}  

мое решение: autoWidth= "false"


единственный способ, который я нашел, это использовать jQuery для инициализации ширины во время загрузки.

вы можете создать просто класс CSS, как это (просто для использования в качестве futur селектор) :

.full-width
{

}

и добавить его в свой компонент :

<p:selectOneMenu value="#{bean.selectedObject}" id="idSelect" converter="objectConverter" styleClass="full-width">
    <f:selectItems value="#{bean.objectsList}" var="varObject"  itemLabel="{varObject.label}" itemValue="#{varObject}" />
</p:selectOneMenu>

так как вам понадобится jQuery, вы должны добавить это внутри вашего h:head если вы не используете на основе схемы PrimeFaces компоненты, которые используют его.

<h:outputScript library="primefaces" name="jquery/jquery.js" />

вот маленький скрипт, инициализирующий все p: selectOneMenu в селекторе:

<script>
    $(document).ready(
        function()
        {
            $("div.ui-selectonemenu.full-width").each(
                function()
                {
                    $(this).css("width",$(this).parent().width());
                }
            );
        }
    );
</script>

вы можете добавить значение width непосредственно в компонент, чтобы изменить его, чтобы избежать влияния на другие P: selectOneMenu, существующие на странице.

<p:selectOneMenu  style="width: 100% !important">
...
</p:selectOneMenu>

Теперь у меня есть правильное решение для этого.

Primefaces 6.0 теперь имеет новое поле с именем autoWidth, которое по умолчанию имеет значение true, и вы можете установить значение false.

Если вы делаете, как некоторые из приведенных выше ответов говорят и установить его в false, все, что вы делаете, это играть в рулетку с вами приложение css. Установив значение false, primefaces предоставит вам возможность управлять шириной. Вы можете либо иметь ширину, установленную на атрибуте selectOneMeny expliclitly by style, либо некоторый класс css в ваше приложение.

но это не то, о чем эта проблема, эта проблема заключается в том, что по умолчанию behaivor не указывает какую-либо ширину в раскрывающемся списке, что приводит к тому, что наши раскрывающиеся списки обычно слишком малы для меток там.

Так что мы на самом деле хотим, чтобы autoWidth работал proplerly.

наконец, я посмотрел на компонент и на рендерер, и очевидно, что механизм автоматической ширины не работает на задней стороне. Этот backend сторона только строит некоторые JSON как данные, которые primefaces javascript builder может использовать для правильной настройки в браузере поведение виджета.

Если вы посмотрите на исходный код primefaces 6.0, ошибка находится в META-INF\resources\primefaces\forms

поиск кода, который говорит следующее:

PrimeFaces SelectOneMenu Виджет

в этой функции javascript охота за фрагментом кода, который говорит:

_render: function() {
        if(this.cfg.autoWidth) {

в этом разделе кода вашей ошибкой является следующая строка:

this.jq.css('min-width', this.input.outerWidth());

здесь я применил следующий патч, который, надеюсь, должен работать в выпадающем списке, чтобы быть таким же толстым, как самая большая этикетка:

 _render: function() {
        if(this.cfg.autoWidth) {
            // BEGIN: PATCHING 
            // ORIGINAL CODE:
            // this.jq.css('min-width', this.input.outerWidth());            
            // BUGFIX:
            // (a) compute the original min-with primefaces 6.0 would put on the root div
            var primefacesBugWidth = this.input.outerWidth();
            // (b) compute the length of the hidden select element  with all the labels inside of it
            var widthOfHiddenDivWithSelectLabels = this.jq.find('div select').width();
            var widthOfTheDropDownTriangle = this.jq.find('.ui-selectonemenu-trigger.ui-state-default.ui-corner-right').width();
            var widthOfLabelPlusTraingle = widthOfHiddenDivWithSelectLabels + widthOfTheDropDownTriangle;
            // (c) we will use whichever length is longer
            // in bug-fixed primefaces version the outerWidth should be computed correctly
            // but this seems not to be the case 
            var maxWidthOfTwoPossibleOptions = primefacesBugWidth > widthOfLabelPlusTraingle ? primefacesBugWidth : widthOfLabelPlusTraingle;
            this.jq.css('min-width', maxWidthOfTwoPossibleOptions);
            // END: PATCHING
        }        
    }

идея кода выше: (a) посмотрите на скрытый div со всеми метками и получите ширину этого div (b) добавить к этой длине ширину, необходимую для треугольника primefaces, обращенного вниз (c) сравните вычисленную нами ширину с что это предлагается primefaces, и это кажется слишком маленьким

Примечание.: Для установки исправления необходимо скопировать весь код Primaces для SelectOneWidget. Добавьте его в файл JavaScript под вашим контролем. Убедитесь, что компиляция файла javascript выполняется только после загрузки файла javascript primefaces.

обычно primefaces отображается в голове. Поэтому, если у вас есть jasvacript как последний эмент в теле, вы должны быть штраф.

исправление отлично работает для меня. Это код, который я не люблю поддерживать, однако.


вы можете идентифицировать элемент и изменить ширину стиля через CSS. Сделать это 100% его емкости.


Если p:selectOneMenu находится в DIV с назначенной шириной, я нахожу настройку style="width:100%;" на p:selectOneMenu кажется, работает в моем случае.


проблема может быть min-width, которая установлена в отображаемом HTML. Если это ваш случай, используйте селектор CSS, фиксированной ширины, как это:

<p:selectOneMenu styleClass="fixed-width" ...

затем определите CSS

.fixed-width { min-width: 100% !important; }

, который устанавливает ширину виджета selectOneMenu в ширину родительского элемента. Чтобы он работал, ширина родительских элементов не должна быть "автоматической".


те, у кого все еще есть проблемы с selectonemenu, могут попробовать это

.ui-selectonemenu {
    min-width: 0 !important;
}

отлично сработало для меня.