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:
Ce que j'attends:
Remarque: je ne veux pas spécifier une largeur fixe.
Je remplace .ui-selectonemenu, .ui-selectonemenu-label
à:
.ui-selectonemenu{
width: 100% !important;
}
.ui-selectonemenu-label{
width: 100% !important;
}
Ma solution: autoWidth = "false"
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>
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>
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.
Vous pouvez identifier l'élément et modifier la largeur du style via CSS. Faites-en 100% de son contenant.
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.
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".
Ceux qui ont encore des problèmes avec selectonemenu peuvent essayer ceci
.ui-selectonemenu {
min-width: 0 !important;
}
Parfaitement travaillé pour moi.