nyroModal

NyroModal :: jQuery Plugin

Cette page documente nyroModal v1. Cette version n'est plus supportée et maintenue.
RDV svp sur la page actuelle du projet pour nyroModal v2.

Edito

Les graphistes aiment de plus en plus utiliser des fenêtre modales; elles fournissent en effet un moyen rapide et efficace pour montrer des informations sans recharger une page entière. C'est facile d'utiliser et de designer.
Le gros problème auquel j'ai été confonté avec tous les plugins que j'ai essayés —utilisant Prototype/Scriptaculous ou jQuery— est la personnalisation. Tous disent que vous pouvez programmer ce que vous voulez très simplement mais ce n'est pas aussi simple. La CSS par défaut fonctionne bien mais dans la plupart des cas est un mélange entre les éléments obligatoires et optionnels. Ce qui implique que vous devez être très attentif quand vous l'éditez.
L'autre problème concerne les animations. C'est le pire. Je n'ai jamais trouvé un plugin permettant de redéfénir simplement les animations.

J'ai essayé de résoudre ces problèmes avec mon plugin. J'ai documenté le plus possible. La CSS par défaut ne contient que les options graphiques. Sans elle, le plugin marchera parfaitement —mais sera aussi très laid. Concernant les animations, vous pouvez simplement les redéfinir de A à Z. Grâce aux fonctions d'animation de jQuery comme animate, fadeTo ou le futur enchant, c'est très simple.
De plus, j'ai aujouté la possibilité de définir beaucoup de callback à différents moments durant le processus pour vous permettre de modifier les paramètres, le contenu ou exécuter ce que vous voulez.

Assez parlé, essayez-le et apprenez à l'utiliser!

Fonctionnalités

Démos

Montrer tous les codes

Ajax
Ajax avec ciblage du contenu #test
Ajax avec ciblage du contenu #blabla

<a href="demoSent.php" class="nyroModal">Ajax</a>
<a href="demoSent.php#test" class="nyroModal">Ajax avec ciblage du contenu  #test</a>
<a href="demoSent.php#blabla" class="nyroModal">Ajax avec ciblage du contenu  #blabla</a>

Ajax sans fermeture

<a href="demoSent.php" class="nyroModal" rev="modal">Ajax sans fermeture</a>

Image

<a href="img/img2.jpg" class="nyroModal" title="3rd Street Promenade">Image</a>

Galerie Img 1
Galerie Img 2
Youtube dans une gallerie
Galerie Img 3

<script type="text/javascript">
$(function() {
  $.nyroModalSettings({
    processHandler: function(settings) {
      var from = settings.from;
      if (from && from.href && from.href.indexOf('http://www.youtube.com/watch?v=') == 0) {
        $.nyroModalSettings({
          type: 'swf',
          height: 355,
          width: 425,
          url: from.href.replace(new RegExp("watch\\?v=", "i"), 'v/')
        });
      }
    }
  });
});
</script>
<a href="img/img1.jpg" id="imgFiche" class="nyroModal" title="UCLA" rel="gal">Gallerie Img 1</a>
<a href="img/img2.jpg" class="nyroModal" title="3rd Street Promenade by Night" rel="gal">Gallerie Img 2</a>
<a href="http://www.youtube.com/watch?v=lddUnv1R5y0" class="nyroModal" title="Hockey Goal fight" rel="gal">Youtube dans une gallerie</a>
<a href="img/img3.jpg" class="nyroModal" title="Sunset at Santa Monica" rel="gal">Gallerie Img 3</a>

DOM Element (div cachée)

<a href="#test" class="nyroModal">DOM Element (div cachée)</a>
<div id="test" style="display: none; width: 600px;">
  <a href="demoSent.php" class="nyroModal">Ouvrir une nouvelle fenêtre</a><br />
  Test
</div>

Youtube Via Process Handler

<script type="text/javascript">
$(function() {
  $.nyroModalSettings({
    processHandler: function(settings) {
      var from = settings.from;
      if (from && from.href && from.href.indexOf('http://www.youtube.com/watch?v=') == 0) {
        $.nyroModalSettings({
          type: 'swf',
          height: 355,
          width: 425,
          url: from.href.replace(new RegExp("watch\\?v=", "i"), 'v/')
        });
      }
    }
  });
});
</script>
<a href="http://www.youtube.com/watch?v=lddUnv1R5y0" class="nyroModal">Youtube Via Process Handler</a>

Appel Manuel
Appel Manuel avec un contenu Ajax
Appel Manuel utilisant un autre lien

<script type="text/javascript">
$(function() {
  $('#manual').click(function(e) {
    e.preventDefault();
    var content = 'Content wrote in JavaScript<br />';
    jQuery.each(jQuery.browser, function(i, val) {
      content+= i + " : " + val+'<br />';
    });
    $.nyroModalManual({
      bgColor: '#3333cc',
      content: content
    });
    return false;
  });
  $('#manual2').click(function(e) {
    e.preventDefault();
    $.nyroModalManual({
      url: 'demoSent.php'
    });
    return false;
  });
  $('#manual3').click(function(e) {
    e.preventDefault();
    $('#imgFiche').nyroModalManual({
      bgColor: '#cc3333'
    });
    return false;
  });
  $('#myValidForm').submit(function(e) {
    e.preventDefault();
    if ($("#myValidForm :text").val() != '') {
      $('#myValidForm').nyroModalManual();
    } else {
      alert("Entrez une valeur avant d'aller a " + $('#myValidForm').attr("action"));
    }
    return false;
  });
});
</script>
<a id="manual" href="#">Appel Manuel</a>
<a id="manual2" href="#">Appel Manuel avec un contenu Ajax</a>
<a id="manual3" href="#">Appel Manuel utilisant un autre lien</a>
<form id="myValidForm" method="post" action="demoSent.php">
  <input type="text" name="wouhou" />
  <input type="submit" value="form avec validation" />
</form>

Iframe automatique via un autre nom de domaine
Iframe automatique via target=_blank

<a href="http://www.perdu.com/" class="nyroModal">Iframe automatique via un autre nom de domaine</a>
<a href="demoIframe.php" target="_blank" class="nyroModal">Iframe automatique via target=_blank</a>
<form method="post" action="demoSent.php" class="nyroModal">
  <input type="text" name="wouhou" />
  <input type="submit" value="simple formulaire"/>
</form>
<form method="post" action="demoSent.php" class="nyroModal" target="_blank">
  <input type="text" name="wouhou" />
  <input type="submit" value="simple formulaire dans une iframe"/>
</form>
<form method="post" action="demoSent.php#test" class="nyroModal">
  <input type="text" name="wouhou" />
  <input type="submit" value="simple formulaire avec ciblage du contenu"/>
</form>
<form method="post" enctype="multipart/form-data" action="demoSent.php" class="nyroModal">
  <input type="file" name="file" />
  <input type="submit" value="formulaire avec fichier"/>
</form>
<form method="post" enctype="multipart/form-data" action="demoSent.php#blabla" class="nyroModal">
  <input type="file" name="file" />
  <input type="submit" value="formulaire avec fichier et ciblage du contenu"/>
</form>

modale bloqué

<div id="blocker"></div>
<a href="demoSent.php" id="block">modale bloqué</a>
<script type="text/javascript">
$(function() {
  $('#block').nyroModal({
    'blocker': '#blocker'
  });
});

URL inexistante
Image inexistante
Element ID inexistant
Element ID inexistant dans une requête Ajax

<a href="invalidUrl.php" class="nyroModal">URL inexistante</a><br />
<a href="invalidUrl.jpg" class="nyroModal">Image inexistante</a><br />
<a href="#inexistent" class="nyroModal">Element ID inexistant</a><br />
<a href="demoSent.php#inexistent" class="nyroModal">Element ID inexistant dans une requête Ajax</a>

Le préchargement des images n'est pas considéré comme une part du plugin, comme vous devez probablement précharger d'autres images pour votre site internet.
Si vous avez besoin de le faire, vous pouvez utiliser le code ci-dessous.

<script type="text/javascript">
$(function() {
  function preloadImg(image) {
    var img = new Image();
    img.src = image;
  }

  preloadImg('img/ajaxLoader.gif');
  preloadImg('img/prev.gif');
  preloadImg('img/next.gif');
});
</script>

Utilisation

Le plugin fournit quelques fonctions avec lesquelles vous pouvez travailler :

Quand vous utilisez la gallerie, Vous pouvez aussi utilisez ces fonctions :

Lorsque vous ouvrez une modale avec une requête Ajax, les scripts inclus dans la page chargée sont inclus selon les règles suivantes :

Si vous avez besoin de savoir ce qu'il se passe avec votre modal, vous pouvez activer le debug. Mais parfois, ce n'est pas assez et vous voulez plus. Vous pouvez écraser la fonction nyroModalDebug(msg, elts, settings); pour faire ce que vous voulez.

Paramètres

Vous avez 3 différents moyens pour modifier les paramètres:

  1. Modifier directement $.fn.nyroModal.settings. Ces paramètres seront ceux utilisés par défaut par toutes les modales qui seront ouvertes
  2. Passer en paramètre de la fonction nyroModal();. Exemple:
    $('a.nyroModal').nyroModal({bgColor: '#ffffff'});
  3. Utiliser la fonction $.nyroModalSettings(settings);

Ci-dessous est la liste complète des paramètres utilisable, avec leur défénition par défaut.

$.fn.nyroModal.settings = {
  debug: false, // Montre les informations de debuggage dans le fond
  blocker: false, // El´ment qui sera bloqu´ par la modale
  windowResize: true, // Indique si la modale doit être redimensionnée quand la fenêtre du navigateur change de taille
  modal: false, // Touche Esc et click sur le fond autorisé ou non
  type: '', // nyroModal type (form, formData, iframe, image, etc...)
  forceType: null, // Utilisé pour forcer le type
  from: '', // Dom object d'où provient l'appel
  hash: '', // Eventuel hash dans l'URL
  processHandler: null, // Handler juste avant le réel processus
  selIndicator: 'nyroModalSel', // Valeur ajoutée wuand un formulaire ou un requète Ajax est envoyé avec un ciblage de contenu
  formIndicator: 'nyroModal', // Valeu ajoutée quand un formulaire est envoyé
  content: null, // Contenu brut si le type 'content' est utilisé
  bgColor: '#000000', // couleur du fond
  ajax: {}, // Option Ajax (url, data, type et success seront écrasés pour un formulaire, url et success seulement pour un appel Ajax)
  swf: { // Options du player Swf si le type swf est utilisé
    wmode: 'transparent'
  },
  width: null, // Largeur par défaut Si null, sera calculé automatiquement
  height: null, // Hauteur par défaut Si null, sera calculé automatiquement
  minWidth: 400, // Largeur minimale
  minHeight: 300, // Hauteur minimale
  resizable: true, // Indique si le contenu est redimensionnable. Sera défini à false pour le type swf
  autoSizable: true, // Indique si le contenu est auto dimensionnable. Si false, les tailles minimales seront utilisées
  padding: 20, // padding pour la taille de modale maximale
  regexImg: '[^\.]\.(jpg|jpeg|png|tiff|gif|bmp)\s*$', // Regex pour trouver les images
  addImageDivTitle: false, // Indique si la div de titre doit être insérée
  defaultImgAlt: 'Image', // Défaut alt attribut pour les images
  setWidthImgTitle: true, // Définir la largeur pour le titre de l'image
  ltr: true, // Droite à gauche par défaut. Définir à false pour Hébreu ou Langage de gauche à droite
  gallery: null, // Nom de la gallerie si existante
  galleryLinks: '<a href="#" class="nyroModalPrev">Prev</a><a href="#"  class="nyroModalNext">Next</a>', // Utiliser .nyroModalPrev et .nyroModalNext pour paramétrer les boutons de navigation
  galleryCounts: galleryCounts, // Callback pour monter le compteur de galerie
  galleryLoop: false, // Indique si la gallerie doit boucler
  zIndexStart: 100,
  cssOpt: { // Propriétés CSS pour les div de nyroModal. Certaines seront écrasées ou mises à jour pour IE6
    bg: {
      position: 'absolute',
      overflow: 'hidden',
      top: 0,
      left: 0,
      height: '100%',
      width: '100%'
    },
    wrapper: {
      position: 'absolute',
      top: '50%',
      left: '50%'
    },
    wrapper2: {
    },
    content: {
    },
    loading: {
      position: 'absolute',
      top: '50%',
      left: '50%',
      marginTop: '-50px',
      marginLeft: '-50px'
    }
  },
  wrap: { // Div Wrapper utilisées pour stylés la modale suivant le type de contenu
    div: '<div class="wrapper"></div>',
    ajax: '<div class="wrapper"></div>',
    form: '<div class="wrapper"></div>',
    formData: '<div class="wrapper"></div>',
    image: '<div class="wrapperImg"></div>',
    swf: '<div class="wrapperSwf"></div>',
    iframe: '<div class="wrapperIframe"></div>',
	iframeForm: '<div class="wrapperIframe"></div>',
    manual: '<div class="wrapper"></div>'
  },
  closeButton: '<a href="#" class="nyroModalClose" id="closeBut" title="fermer">Fermer</a>', // Ajouter automatiquement comme premier enfant de #nyroModalWrapper 
  title: null, // Titre de la modale
  titleFromIframe: true, // Avec uen iframe sur le même domaine, prends le titre de l'iframe pour la modale
  openSelector: '.nyroModal', // Sélécteur pour ouvrir une nouvelle modale. Sera utilisé pour parser automatiquement la page au chargement
  closeSelector: '.nyroModalClose', // sélécteur pour fermer la modale
  contentLoading: '<a href="#" class="nyroModalClose">Cancel</a>', // Contenu de la div de chargement
  errorClass: 'error', // Classe CSS d'erreur ajoutée à la div de chargement en cas d'erreur
  contentError: 'Le contenu demandé ne peut pas être chargé..<br />Essayer plus tard svp.<br /><a href="#" class="nyroModalClose">Fermer</a>', // Contenu placé dans la div de chargement en cas d'erreur
  handleError: null, // Callback en cas d'erreur
  showBackground: showBackground, // Show background animation function
  hideBackground: hideBackground, // Hide background animation function
  endFillContent: null, // Sera appelé après que le contenu soit placé et avant qu'il ne soit parsé pour closeSelector et openSelector, et montré
  beforeHideContent: null, // Sera appelé juste avant que la modale soit fermé
  showContent: showContent, // Show content animation function
  endShowContent: null, // Sera appelé une fois que le contenu est visible
  hideContent: hideContent, // Hide content animation function
  showTransition: showTransition, // Show the transition animation (a modal is already shown and a new one is requested)
  hideTransition: hideTransition, // Hide the transition animation to show the content
  showLoading: showLoading, // show loading animation function
  hideLoading: hideLoading, // hide loading animation function
  resize: resize, // Resize animation function
  endResize: null, // Sera appelé une fois que le contenu est redimensionné
  updateBgColor: updateBgColor, // Change background color animation function
  endRemove: null // Sera appelé une fois que la modale est totalement enlevée
};

Callbacks

Dans un effort d'être aussi flexible que possible, le plugin fournit de nombreux callbacks que vous pouvez utiliser pour modifier le contenu à différents moments du processus. Pour être plus clair, voici le schéma complet avec tous les callbacks possible:

  1. L'utilisateur clique sur un lien ou vous avez écrit du code pour ouvrir une modale
  2. processHandler(settings);: Utilisez ce callback pour changer le type, les dimensions, etc...
  3. S'il s'agit d'une nouvelle modale:
    1. showBackground(elts, settings, callback);: elts.bg doit être visible après
    2. showLoading(elts, settings, callback);: elts.loading doit être visible après
    3. handleError(elts, settings);: sera appelé en cas d'erreur, juste avant de montrer le contenu du message d'erreur
    4. hideLoading(elts, settings, callback);: elts.loading doit être masqué après
    5. S'il s'agit d'un appel Ajax ou d'un formulaire, les éventuels blocs Javascript à l'intérieur seront appelés à ce moment là
    6. endFillContent(elts, settings);: modal.content est déjà wrappé. Les liens pour ouvrir ou fermer ne sont pas encore paramétrer. C'est sans doute le bon endroit pour modifier le contenu, les dimensions ou ajouter des liens de fermeture
    7. showContent(elts, settings, callback);: modal.contentWrapper doit être visible après
    Ou si la model existe déjà (appel depuis une modale, navigation dans une gallerie):
    1. showTransition(elts, settings, callback);: elts.loading doit être visible après et elts.contentWrapper doit être masqué
    2. S'il s'agit d'un appel Ajax ou d'un formulaire, les éventuels blocs Javascript à l'intérieur seront appelés à ce moment là
    3. handleError(elts, settings);: sera appelé en cas d'erreur, juste avant de montrer le contenu du message d'erreur
    4. endFillContent(elts, settings);: modal.content est déjà wrappé. Les liens pour ouvrir ou fermer ne sont pas encore paramétrer. C'est sans doute le bon endroit pour modifier le contenu, les dimensions ou ajouter des liens de fermeture
    5. hideTransition(elts, settings, callback);: elts.loading doit être masqué et elts.contentWrapper doit être visible après
  4. beforeHideContent(elts, settings, callback);: appelé juste avant l'enlèvement de la modale. utilisez ce callback pour enlever des éléments qui peuvent poser problème pendant l'animation de cachage
  5. endShowContent(elts, settings);: la modale est maintenant totalement visible. C'est ici le moment pour ajouter des éléments visuels qui peuvent poser problème avec quelques navigateurs
  6. L'utilisateur consulte la modale. Un jour ou l'autre, il voudra probablement fermer la modale ou cliquer sur un lien pour en ouvrir un autre
  7. Vous avez la possibilité de redimensionner la modale en utilisant $.nyroModalSettings avec les paramètres width et/ou height. Dans ce cas:
    1. resize(elts, settings, callback);: elts.contentWrapper doit être aux nouvelles dimensions après
    2. endResize(elts, settings);: sera appelé quand la modale est redimensionnée
    Il est aussi possible de modifier la couleur de fond en utilisant $.nyroModalSettings avec le paramètre bgColor :
    1. updateBgColor(elts, settings, callback);: elts.bg doit avoir la nouvelle couleur. Pour animer la couleur, utiliser le plugin color.
  8. hideContent(elts, settings, callback);: modal.contentWrapper doit être masqué après
  9. Si une nouvelle modale est demandée, on retourne au 2ème point (NB: la fonction showBackground ne sera pas rappelée). Sinon, on ferme la modale aux étapes suivantes
  10. hideBackground(elts, settings, callback);: modal.bg doit être masqué après
  11. Tout ce qui a été créé par le plugin sera enlevé
  12. endRemove(elts, settings);: sera appelé quand la modale est totalement supprimée. Les éléments dans l'objet elts sont pour la plupart inutilisable

L'object elts contiendra les paramètres suivants :

Pour en savoir plus sur les callbacks d'animation, regarder ci-dessous.

Callbacks d'Animation

Vous pouvez redéfinir les animations que vous voulez. Pour ce faire, vous devez réécrire complètement la fonction d'animation. Ce qui veut dire que vous pouvez faire absolument ce que vous voulez. Si vous voulez simplement montrer l'élément sans aucune animation, vous pouvez simplement utiliser show sur l'élément et exécuter le callback. C'est tout.

Pour être plus pratique, toutes les fonctions d'animation prennent exactement les mêmes paramètres :

  1. elts: sera utilisé pour accéder aux éléments. Pour être sûr d'être libre de faire tout ce que vous voulez, vous pouvez accéder tous les éléments. Vous êtes libre de tout casser si vous voulez ! Lisez le chapitre précédent pour savoir ce qu'il contient
  2. settings: contient l'object complet des paramètres actuels. Vous devez utilisez quelques éléments dans cet objet pour être sûr de faire quelque chose qui fonctionnera bien
  3. callback: n'oublier pas de l'exécuter! Si vous ne le faites pas, la modale ne fonctionnera plus du tout. Vous pouvez l'appeler en la passant au paramètre complete de l'animation, ou simplement en faisant comme ceci : callback();

Le moyen le plus simple pour commencer à écrire une fonction d'animation est sans doute de copier/coller son code depuis le plugin, comprendre comment elle fonctionne et ensuite de commencer à la modifier.

Quand vous positionner la div loading ou content, vous voudrez sans doute la centrée. Pour ce faire, on procède généralement de cette façon avec les CSS:

#element {
  position: fixed;
  width: 500px;
  height: 300px;
  margin-left: -250px; // -width / 2
  margin-top: -150px; // -height / 2
}

Et ça devrait marcher. Mais vous savez probablement qu'IE6 ne comprend pas la position fixed. C'est pourquoi vous devez utiliser settings.marginScrollTop et settings.marginScrollLeft pour être sûr que l'élément soit bien centré. Ces valeurs seront égales à zéro dans les navigateurs compréhensifs, et égales aux valeurs du scroll pour IE6. Pour montrer le contenu, 2 autres valeurs sont disponibles pour définir les marges: settings.marginLeft et settings.marginTop. Par exemple, la fonction d'animation pour montrer le wrapper du contenu est :

function showContent(elts, settings, callback) {
  elts.contentWrapper
    .css({ // Reset the CSS at the start position
      marginTop: (-100/2 + settings.marginScrollTop)+'px',
      marginLeft: (-100/2 + settings.marginScrollLeft)+'px',
      height: '100px',
      width: '100px',
      opacity: 0
    })
    .show()
    .animate({ // Set the width
      width: settings.width+'px',
      marginLeft: (settings.marginLeft)+'px',
      opacity: 0.5
    }, {duration: 350})
    .animate({ // Set the height
      height: settings.height+'px',
      marginTop: (settings.marginTop)+'px',
      opacity: 1
    }, {complete: callback, duration: 350});
}

Dimensions de la modale

Parce que comprendre comment la modale est redimensionnée peut être un cauchemar, voici les explications comment fonctionne nyroModal.

Tout d'abord, il y a les paramètres minWidth et minHeight qui s'appliquent tout le temps sans se soucier du type de contenu de la modale. Par défaut, ces valeurs sont définies à 150 par 150.

Ensuite la modale sera toujours entièrement visible. Si une dimension ira en dehors de la fenêtre, elle sera diminuée.
Il y a un paramètre padding (20 par défaut) utilisé pour espacer la limite externe de la modale avec les bordures de la fenêtre.

Pour les images, elle seront redimensionnées proportionnelement si elles sont trop grandes pour respecter le padding décrit ci-dessus.

Quand vous effectuez une requête Ajax, vous afficherez du contenu HTML. Avec nyroModal, la taille demandée sera la taille réelle disponible à l'intérieur de la div #nyroModalContent. Ce qui veut dire que le contenu à l'intérieur du padding de #nyroModalContent sera la taille demandée. Par exemple, demander une taille de 500 par 500 pixels aura pour résultat pour #nyroModalContent (capture d'écran réalisée avec Firebug):

nyroModal Dimensions

Pourquoi faire ça ?
Vous travailler sur un projet utilisant nyroModal. Quand vous ouvrez les modales avec différentes tailles, vous faites attentions à ce que le contenu s'ajuste parfaitement avec le design. Ça marche et tout le monde est content.
Mais 3 mois plus tard, le design doit être changé, notamment l'aspect des nyroModal, en ajoutant des nouvelles marges ou bordrures.
Comme les dimensions sont le contenu à l'intérieur de la modale, changer les CSS des marges, bordures ou padding du wrapper ou du contenu ne changera pas les dimensions affichées. Pour effectuer ce changement, vous devez simplement modifier votre CSS et vérifier que le résultat obtenu est le bon pour quelques modales.

Télécharger

nyroModal est sous la licence MIT.
nyroModal est hébergé par Google code.
Vous pouvez télécharger la derniàre version ici.

Dans l'archive vous trouverez les sources complètes et les sources packed et minified.
Vous trouverez aussi 2 versions CSS et les images par défaut. La version full de la CSS est just ici pour montrer la structure HTML complète afin que vous puissiez la personnalisée exactement comme vous le voulez, si besoin.

Changelog

Support

Si vous vous demandez comment faire quelque chose avec nyroModal, commencer par regarder dans le wiki et vous trouverez peut-être une solution. Sinon, vous pouvez demander dans les Page Google Code des Issues.

Si vous trouvez des bogues ou avez des suggesstions/requêtes qui peuvent être utile à tout le monde, vous pouvez les reportez dans les Page Google Code des Issues.

Si vous avez créé des améliorations ou de belles fonctions d'animations, je serai heureux de les partager. Utilisez aussi les Issues pour les partager.