web-dev-qa-db-fra.com

PrimeFaces p: selectOneMenu width

Je veux que p:selectOneMenu width soit automatiquement considéré par rapport à la cellule parente par rapport aux valeurs dont il dispose.

<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>

Ce que j'ai:

enter image description here

Ce que j'attends:

enter image description here

Remarque: je ne veux pas spécifier une largeur fixe.

8
ehab refaat

Je remplace .ui-selectonemenu, .ui-selectonemenu-label à:

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

Ma solution: autoWidth = "false"

14
Marcos Abrahão

Le seul moyen que j'ai trouvé est d'utiliser jQuery pour initialiser la largeur au moment du chargement.

Vous pouvez simplement créer une classe CSS comme ceci (juste pour être utilisé comme futur selector ):

.full-width
{

}

Et ajoutez-le à votre composant:

<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>

Puisque vous aurez besoin de jQuery , vous devriez l’ajouter dans votre h:head si vous n’utilisez pas déjà PrimeFaces les composants qui l’utilisent.

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

Voici le petit script qui initialise tous les p: selectOneMenu dans le sélecteur:

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

vous pouvez ajouter la valeur de width directement dans le composant pour le modifier, afin d'éviter tout impact sur d'autres p: selectOneMenu existant dans la page.

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

J'ai maintenant une solution appropriée pour cela.

Primefaces 6.0 a maintenant un nouveau champ appelé autoWidth qui, par défaut, est défini sur true et vous pouvez définir sur false.

SI vous faites comme certaines des réponses ci-dessus et le définissez sur false, tout ce que vous faites est de jouer à la roulette avec vous css. En le définissant sur false, Primefaces vous laissera le soin de gérer la largeur . Vous pouvez définir explicitement la largeur sur l'attribut selectOneMeny par style, ou une classe css dans votre application.

Mais ce n’est pas l’objet de ce problème, c’est le fait que le comportement par défaut de ne spécifier aucune largeur à une liste déroulante fait que nos listes déroulantes sont normalement trop petites pour les étiquettes.

Nous voulons donc que autoWidth fonctionne correctement.

Enfin, j’ai examiné le composant et le rendu, et il est évident que le mécanisme de largeur automatique ne fonctionne pas à l’arrière-plan. L’arrière-plan ne construit que des données de type JSON que le constructeur JavaScript peut utiliser. pour régler correctement sur le navigateur le comportement du widget.

Si vous observez le code source de primefaces 6.0, le bogue se trouve dans META-INF\resources\primefaces\forms 

Recherchez le code indiquant ce qui suit:

PrimeFaces SelectOneMenu Widget

Dans cette fonction javascript, recherchez le code qui dit:

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

Dans cette section de code, votre bogue est la ligne suivante:

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

Ici, j'ai appliqué le correctif suivant qui, espérons-le, devrait permettre à la liste déroulante de devenir aussi grosse que la plus grande étiquette:

 _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
        }        
    }

L'idée du code ci-dessus est la suivante: (A) regardez le div caché avec toutes les étiquettes et obtenez la largeur de ce div (B) ajoutez à cette longueur la largeur nécessaire pour le triangle de primefaces vers le bas (c) compare la largeur que nous avons calculée à celle suggérée par primefaces et qui semble bien trop petite

REMARQUE: Pour installer le correctif, vous devez copier tout le code Primaces du SelectOneWidget. Ajoutez-le à un fichier javascript sous votre contrôle. Assurez-vous de ne lancer que le compilation de votre fichier javascript après le chargement du fichier javascript de primefaces.

Normalement, primefaces est rendu au niveau de la tête. Donc, si vous avez jasvacript comme dernier élément dans le corps, tout devrait bien aller.

Le correctif fonctionne bien pour moi. C’est un code que je n’aime pas conserver.

3
99Sono

Vous pouvez identifier l'élément et modifier la largeur du style via CSS. Faites-en 100% de son contenant.

1
infiniteStacks

Si votre p:selectOneMenu est dans une DIV avec une largeur assignée, je trouve que le réglage de style="width:100%;" sur le p:selectOneMenu semble fonctionner dans mon cas.

1
peater

Le problème pourrait être min-width, défini dans le code HTML affiché. Si tel est votre cas, utilisez un sélecteur CSS à largeur fixe comme ceci:

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

puis définir CSS

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

Cela définit la largeur du widget selectOneMenu sur la largeur de l'élément parent. Pour que cela fonctionne, la largeur des éléments parents ne doit pas être "auto".

0
DoraCet

Ceux qui ont encore des problèmes avec selectonemenu peuvent essayer ceci

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

Parfaitement travaillé pour moi.

0
Prakash Bist