IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JSF Java Discussion :

Ajuster un rich:modalpanel à la résolution


Sujet :

JSF Java

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut Ajuster un rich:modalpanel à la résolution
    Bonjour,

    ma question de ce jour concerne un rich:modalpanel très simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <rich:modalPanel 
      id="importPanel" height="500" width="500" style="overflow:auto">
      <f:facet name="header">
        <h:outputText value="#{bundle.somevalue}" />
      </f:facet>
      <ui:include src="importFile.xhtml" flush="true"/>
    </rich:modalPanel>
    Seulement, j'aimerais aussi que mon modalPanel puisse être défini comme un composant HTML classique avec les comportements suivants :
    1. Qqchose de type "height:100%;overflow-y:auto"
    2. Une taille max (de type "max-height:700px"
    3. une taille min


    Seulement, après près de 3h passées à triturer mon panneau dans tous les sens, je n'arrive pas à faire même le premier... principalement car rich:modalpanel n'accepte pas les dimensions dynamiques (autant que je sache!)
    Je pourrais bien travailler directement avec la résolution de l'écran (screen.width et screen.height) mais je ne sais pas comment les transmettre directement à rich:modalpanel (width=??0.9*screen.width??).
    D'autre part, ça ne résoudrait qu'une partie de mon problème (resterait les tailles min et max).

    Donc j'ai l'intuition que la solution se trouverait plutôt dans la redéfinition des styles internes du composant (.rich-mpnl-panel si je ne m'abuse).
    Seulement, mes connaissances en CSS sont faibles, et je ne suis pas certain de pouvoir faire un "ajout" sur ce sytle sans automatiquement effacer tout ce que je ne définis pas explicitement. Et mes essais ont surtout foutu une pagaille pas possible dans mes autres modals...
    Ca ressemble à ça (et ce sera certainement une horreur aux yeux des experts!):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <style type="text/css">
    	.rich-mpnl-panel {overflow:auto;width:100%;height:100%;}
    </style>
    Au final... si quelqu'un a une idée sur le comment de ce problème, elle sera évidemment la bienvenue!

    En attendant, merci déjà de m'avoir lu, et éventuellement d'avance pour vos suggestions.

  2. #2
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    Bonjour,

    Alors effectivement, un <rich:modalPanel> doit disposer de dimensions fixes. Les attributs height et width n'accepte que des entiers, qui sont des valeurs en pixels.

    Ensuite, redéfinir une classe CSS comme tu l'as fait c'est bien, mais cela implique que tous les composants modalPanel seront impactés. Si tu souhaites définir exceptionnellement des propriétés CSS sans affecter tous les autres composants, il faudra utiliser les attributs styleClass ou style d'un composant.

    Sinon, dernière solution : modifier les dimensions en utilisant un peu de code JavaScript, exécuté par le onbeforeshow du composant...
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    merci Romain.

    Tu as confirmé ce que je pensais... par contre je n'ai pas réussi dans les pistes que tu as suggérées (peut-être est-ce que j'ai mal compris!).


    Ce que j'ai essayé :
    • onbeforeshow
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
          function doChangePercentPanelDims(panel,widthPercent,heightPercent)
          {
             panel.width=widthPercent*screen.width/100;
             alert("screen.width : "+screen.width+", panel.width : "+panel.width);
             panel.height=heightPercent*screen.height/100;
             alert("screen.height : "+screen.height+", panel.height : "+panel.height);
          }
           ;
      >> les alertes sont cohéreantes.
      Par contre si je fais l'alerte avant le set, le résultat pour panel.width est "undefined"

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      <rich:modalPanel 
        id="importPanel" 
                  onbeforeshow="doChangePercentPanelDims(this,100,100);">
        <f:facet name="header">
          <h:outputText value="#{bundle.somevalue}" />
        </f:facet>
        <ui:include src="importFile.xhtml" flush="true"/>
      </rich:modalPanel>
      >> Au final, ça n'a aucun effet de toutes façons

    • style
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
       <rich:modalPanel
                  id="importPanel"
                  autosized="true"
      			style="overflow:auto;width:100%;height:100%;">
      	            <f:facet name="header">
      	                <h:outputText value="#{bundle.somevalue}" />
      	            </f:facet>
      	            <ui:include src="importFile.xhtml" />
              </rich:modalPanel>
      => Absolument sans effet

    • styleClass
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      <style type="text/css">
      	.totoStyle {overflow:auto;width:100%;height:100%;}
      </style>
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
       <rich:modalPanel
                  id="importPanel"
                  autosized="true"
      			styleClass="totoStyle">
      	            <f:facet name="header">
      	                <h:outputText value="#{bundle.somevalue}" />
      	            </f:facet>
      	            <ui:include src="importFile.xhtml" />
              </rich:modalPanel>
      >> A première vue il ne se passe absolument rien... mais en regardant de plus près, il semble y avoir un effet en arrière plan (une espèce de masque blanc de la largeur et la hauteur de l'écran.. seulement Firebug ne me permet pas d'inspecter ces effets (inactif sur les éléments en arrière-plan) pour confirmer de quel objet il s'agit.


    Voilà... je patauge... en résumé

    PS : j'ai aussi essayé à chaque fois avec ET sans le autosize = true;

  4. #4
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    Hello,

    Pour la solution JavaScript, je pense qu'il faut opter pour quelque chose de légèrement différent. En fait, tu passes this à ta fonction. Le souci, c'est que cela ne fait pas référence à ton panel. En effet, ça marcherait bien si la méthode liée à onbeforeshow été affectée à une balise HTML. Or la fonction a appelée est donnée à du code JavaScript (qui est le constructeur de l'objet modalPanel). Donc le this fera référence non plus à un objet HTML, mais à une fonction JavaScript. Du coup, modifier des valeurs de dimensions n'a plus de sens ici...

    Il faut à mon avis que tu retrouves ton modal panel dans le code JavaScript, en utilisant l'ID qui doit être écrit comme ça :

    formId:panelIdContentDiv

    Ainsi, si ton panel s'appelle toto, il faudra chercher le DIV à l'ID totoContentDiv, préfixé, si je ne dis pas de bêtise, par l'éventuel form qui le contient (à vérifier).

    Du coup, tu fais quelque chose comme ça dans ta fonction JavaScript, à laquelle tu passes ton ID de form et ton ID de panel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function doBidule(formId, panelId) {
        var widthToSet = ...;
        var heightToSet = ...;
        jQuery("#" + formId + "\\:" + panelId + "ContentDiv").width(widthToSet).height(heightToSet);
    }
    Bon, je ne sais pas si cela est plus clair, j'essaierais de voir demain sinon.
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    Romain,

    j'ai tenté ta solution, mais j'ai l'impression que l'id du form n'est pas invoqué ici.. j'ai donc tenté (en dur) de faire jQuery("importFilePanelContentDiv") (si ça peut être une info utile : si je fais une alerte sur ce que me renvoie jQuery, je reçois un [Object object]). Rien ne se passe dans les deux cas.

    Je liste ci-dessous le généré (visible via firebug) dont je me sers pour mes tests (erreurs de recopie possible) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      <div id="importContactFilePanelContainer" class="rich-modalpanel" style="position:absolute;z-index:100;background-color:inherit;">
        <div id="importFilePanelDiv" class="rich-mpnl-mask-div-opaque rich-mpnl-mask-div" style="z-index:-1;">
          <div class="rich-mpnl-panel">
            <div id="importFilePanelCDiv" class="rich-mp-container" style="position:absolute;left:257px;top:88px;z-index:9;">
              <div id="importFilePanelShadowDiv" class="rich-mp-shadow" style="width:750px;height:604px;"> </div>
              <div id="importFilePanelContentDiv" class="rich-mp-shadow" style="width:750px;height:604px;">
      ................
              </div>
            </div>
          </div>
        </div>
      </div>
    J'ai tenté de faire des sets un peu violents de chacun des éléments :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            var panel0 = document.getElementById('importFilePanelDiv');
            var panel1 = document.getElementById('importFilePanelCDiv');
            var panel2 = document.getElementById('importFilePanelShadowDiv');
            var panel3 = document.getElementById('importFilePanelContentDiv');
            var panel4 = document.getElementById('importFilePanelContentTable');
     
         	panel0.style.width="1270px";
         	panel1.style.width="1270px";
         	panel2.style.width="1270px";
         	panel3.style.width="1270px";
         	panel4.style.width="1270px";
    Mais la largeur n'est appliquée que sur les 4 premiers panneaux.
    Le dernier (panel4 => importContactFilePanelContentTable) est automatiquement remis à la taille que j'ai fixée au départ...

    Par contre, si je le fais à la main via firebug (width:1270px) sur le importFilePanelContentTable, là ça fonctionne... (c'est très frustrant d'ailleurs!)

  6. #6
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    jQuery("importFilePanelContentDiv"); ne donnera rien, mais normalement jQuery("#importFilePanelContentDiv"); oui
    Le "#" est utilisé pour indiquer que l'on parle d'un ID ici...

    Sinon, je me demande si le problème n'est pas que le onbeforeshow est appelé, donne la taille voulue, puis le code JavaScript du modal panel vient remettre la bonne taille au moment d'afficher la popup.

    Essaie de mettre ton code JavaScript dans l'événement onshow plutôt...
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    Citation Envoyé par romaintaz Voir le message
    jQuery("importFilePanelContentDiv"); ne donnera rien, mais normalement jQuery("#importFilePanelContentDiv"); oui
    Le "#" est utilisé pour indiquer que l'on parle d'un ID ici...
    Oups! Je ne suis pas encore très à l'aise avec jQuery... J'ai donc remplacé tous mes gros sabots par de jolis mocassins...

    Mais au final : VICTOIRE!
    Après qqs bidouilles, et inspiré par tes nombreuses remarques, je suis enfin arrivé à un premier résultat très satisfaisant (visuellement)... tout ce qui me manquait au final était le "overflow:auto"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <script>
    <!--  
          function doChangePercentPanelDims(widthPercent,heightPercent)
        {	
            // with autosized = "true" the starting dims must be the best suited one
            // thus, we store it as max dims
            var maxWidth=jQuery("#importContactFilePanelContentDiv").css("width");
            var maxHeight=jQuery("#importContactFilePanelContentDiv").css("height");
        	jQuery("#importContactFilePanelContentDiv").css("overflow","auto");
        	jQuery("#importContactFilePanelContentDiv").css("max-height",maxHeight);
            // if one of the value is -1, means that the default dimension is maintained
            // elsewhere the new dimensions are computed according to a ratio on 
            // current screen dims
            var width=widthPercent!=-1?screen.width*widthPercent:maxWidth;
            alert('width :'+width);
        	var height=heightPercent!=-1?screen.height*heightPercent:maxHeight;
            alert('height :'+height);
        	jQuery("#importContactFilePanelContentDiv").width(width).height(height);
        	jQuery("#importContactFilePanelContentDiv").css("max-width",maxWidth);
        }
        -->
    </script>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <rich:modalPanel
        id="importFilePanel"
        autosized="true"
        onshow="doChangePercentPanelDims(0.9,0.6)"
        >
          <f:facet name="header">
              <h:outputText value="#{bundle.some_label}" />
          </f:facet>
          <ui:include src="importFile.xhtml" />
    </rich:modalPanel>

    Cette fois, je peux descendre en 800x600, et le comportement est niquel :
    la fenêtre se réduit en-deçà des dimensions calculées par l'option "autosized".
    Et lorsque la résolution le permet, ce sont les dimensions renvoyées par l'"autosized" qui prennent le pas.

    Par contre, ma méconnaissance de jQuery m'a peut-être fait écrire les choses de façon compliquées. Il est fort possible qu'on puisse compresser un peu le code.

    Qqs remarques pour compléter:
    • effectivement, l'astuce de "onshow" à la place de "onbeforeshow" était judicieuse : sur le second, mes dimensions (height, width) étaient à "auto". Sur la première ce sont bien les dimensions générées que je reçois.
    • les dimensions en pourcentage que j'indique sont empiriques : étant donné que le navigateur lui même s'adapte à la résolution, les dimensions du "screen" ne sont pas forcément les mieux adaptées pour faire mon calcul. Peut-être existe-t'il une méthode pour connaître la taille du conteneur du navigateur?
    • cette solution interdit l'usage de l'option "resizable", du coup
    • si on change de résolution alors que la modale est affiché, cette dernière ne sera évidemment pas réajustée.


    Je ne doute pas que tu auras des remarques / réserves sur ce sujet, mais dors et déjà, j'ai réussi à faire quelque chose de satisfaisant. Donc pour terminer, un grand merci à toi, une fois encore.

  8. #8
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    Hello,

    Citation Envoyé par Roger_Rabbit Voir le message
    Par contre, ma méconnaissance de jQuery m'a peut-être fait écrire les choses de façon compliquées. Il est fort possible qu'on puisse compresser un peu le code.
    Oui, effectivement. La simplification la plus importante serait de stocker le jQuery("#importContactFilePanelContentDiv") que tu utilises partout dans une variable, afin d'éviter qu'à chaque fois jQuery aille chercher dans le DOM le DIV ayant l'ID spécifié.
    Tu peux aussi aligner les statements, plutôt que d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    jQuery("#importContactFilePanelContentDiv").width(width).height(height);
    jQuery("#importContactFilePanelContentDiv").css("max-width",maxWidth);
    tu peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jQuery("#importContactFilePanelContentDiv").width(width).height(height).css("max-width",maxWidth);

    Citation Envoyé par Roger_Rabbit Voir le message
    les dimensions en pourcentage que j'indique sont empiriques : étant donné que le navigateur lui même s'adapte à la résolution, les dimensions du "screen" ne sont pas forcément les mieux adaptées pour faire mon calcul. Peut-être existe-t'il une méthode pour connaître la taille du conteneur du navigateur?
    screen.width et screen.height donnent les résolutions de l'écran.
    Si tu veux connaitre la résolution du contenu du navigateur, tu utiliseras plutôt window.innerWidth et window.innerHeight.

    Citation Envoyé par Roger_Rabbit Voir le message
    cette solution interdit l'usage de l'option "resizable", du coup
    Pourquoi ?

    Citation Envoyé par Roger_Rabbit Voir le message
    si on change de résolution alors que la modale est affiché, cette dernière ne sera évidemment pas réajustée.
    Je n'ai pas testé, mais tu dois pouvoir relancer le redimensionnement de ta popup sur l'événement window.onresize ...

    Faire quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    jQuery(window).resize(function() {
        // Redimensionnement de la popup...
    });
    mais bon, je ne suis pas certain que cela soit forcément intéressant. Est-ce que les utilisateurs s'amusent souvent à redimensionner leur navigateur ?
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    Citation Envoyé par romaintaz Voir le message

    screen.width et screen.height donnent les résolutions de l'écran.
    Si tu veux connaitre la résolution du contenu du navigateur, tu utiliseras plutôt window.innerWidth et window.innerHeight.
    Exact! Ca fonctionne à merveille. J'ai maintenant une vraie taille en pourcent et je n'ai plus besoin de faire des bidouillages pour l'ajuster bien à toutes les résolutions!

    Citation Envoyé par romaintaz Voir le message
    Pourquoi ? (à propos du resizable)
    C'est techniquement possible, mais à cause des max-width/height qui va de toutes façons bloquer l'agrandissement, ça sera déjà tronqué. En plus, ça n'a plus guère de sens dans l'esprit d'une taille dynamique qui s'ajuste à son contenu et à la résolution. Je m'étais mal exprimé cependant : j'aurais du dire que ce choix devrait exclure de laisser l'utilisateur redimensionner la fenêtre.

    Citation Envoyé par romaintaz Voir le message
    mais bon, je ne suis pas certain que cela soit forcément intéressant. Est-ce que les utilisateurs s'amusent souvent à redimensionner leur navigateur ?
    Là je crois qu'on est bien d'accord.
    J'ai cependant testé ton bout de code tel quel, mais je n'ai pas réussi à le faire fonctionner. Je retenterai ça un soir lorsque j'aurai un peu plus de temps, et ferai un retour ici.

    En attendant, je te renouvelle mes remerciements!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/05/2009, 09h28
  2. Réponses: 8
    Dernier message: 27/02/2009, 16h03
  3. ajustement des cadres selon la résolution de l'écran
    Par tomy29 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 14/11/2008, 15h37
  4. rich:modalPanel erreur dans la page
    Par JAMINF dans le forum JSF
    Réponses: 2
    Dernier message: 21/10/2008, 13h23
  5. lenteur de rich:modalPanel
    Par ng.phung dans le forum JSF
    Réponses: 2
    Dernier message: 11/08/2008, 12h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo