skip to main | skip to sidebar
Code 18
Manuel du savoir-faire à l'usage des geeks et des curieux
RSS
  • Accueil
  • Le web au Québec
  • Liens
  • Twitter
  • Facebook
  • À propos

mercredi 28 novembre 2012

Click unique sur un bouton jQueryUI dialog

Publié par Infinite Loop, à 13 h 05 0 commentaire

Il y a de ces bogues que les développeurs ont tendance à oublier car ils connaissent suffisamment bien la mécanique du système pour savoir comment l'utiliser et contourner les comportements indésirables. Pour l'utilisateur normal, la façon d'utiliser un système est généralement plus intuitive et fait ressortir les surprises malgré lui. Il peut avoir tendance à recommencer à nouveau s'il ne voit pas d'indicateur ou de changement visuel en guise d'indice de progression. D'autres sont adeptes du double-clic sur les contrôles pour être certains que le système ait bien saisi ce qu'il doit faire. Si ça ne fonctionne pas, pèse plus fort! Pour l'action qui en résulte, on a qu'à penser à l'envoi répété d'un courriel ou pire, un paiement qui passe en double. C'est ce qui est arrivé dans un projet utilisant le composant Dialog de jQueryUI.

L'idéal est de pouvoir détecter le doublon d'appel côté serveur mais parfois une contrainte nous en empêche. Une solution simple et efficace est de modifier l'interface utilisateur et de restreindre la possibilité de cliquer sur les boutons d'action, en les désactivant ou en les cachant.



Ici, chaque fois qu'on clique sur le bouton "Accepter",  une requête Ajax se fait sur le serveur et du code est exécuté. D'ordinaire, il aurait dû s'exécuter une seule fois mais comme la requête Ajax doit attendre la réponse du serveur qui vient plus ou moins vite selon sa charge de travail, les utilisateurs n'ont pas d'indicateur visuel pour indiquer que le processus est en cours.

Comment solutionner ce problème ?

Dès qu'un bouton d'action du dialogue est cliqué, on peut désactiver tous les boutons à l'intérieur. Par cette contrainte, il n'est plus possible de cliquer à nouveau dessus et lancer par erreur d'autres requêtes vers le serveur. Par contre, le thème CSS de jQueryUI fait que l'apparence ne change pas. L'ajout d'une classe pour griser les boutons pourrait s'avérer suffisant. Dans ma solution, j'ai préféré cacher les boutons et remplacer le contenu du dialogue par un GIF animé montrant une progression de chargement accompagné d'un message indiquant de patienter.


Code d'exemple épuré pour reproduire la problématique

Inclusion de jQueryUI et ses dépendances
<link type="text/css" rel="stylesheet" href="/js/jquery-ui-1.9.2.custom/css/ui-lightness/jquery-ui-1.9.2.custom.min.css" />

<script type="text/javascript" src="/js/jquery-ui-1.9.2.custom/js/jquery-1.8.3.js"></script>
<script type="text/javascript" src="/js/jquery-ui-1.9.2.custom/js/jquery-ui-1.9.2.custom.min.js"></script>

Le code HTML
<h1>jQueryUI dialog</h1>

<p><input type="button" id="btnOpenDialog" value="Ouvrir le dialogue" /></p>

<div id="divDialog" title="Confirmation" style="display:none;">
    Faites un choix
</div>

JavaScript 
var dialogConfig =
{
    autoOpen: false,
    modal: true,
    resizable: true,
    draggable: true,
    buttons: {
        'Accepter': function(){
            // closure
            var dialogContainer = $('#divDialog').parent();

            // chercher ces classes à l'intérieur du HTML de dialogContainer
            $('.ui-dialog-content, .ui-dialog-buttonpane button', dialogContainer).hide();
   
            // Si vous préférez désactiver les boutons plutôt que les cacher
            // $('.ui-dialog-content, .ui-dialog-buttonpane button', dialogContainer).attr('disabled','disabled');
  
            $('div.ui-dialog-buttonpane', dialogContainer)
                .css('text-align', 'center')
                .append( $('')
                .attr({'src':'/images/ajax-loader.gif'}) )
                .append(' ' + ' Veuillez patienter...');

            var theDialog = this;

            $.ajax({
                url: 'ajax/long-process.php',
                success: function(data){
                    $(theDialog).dialog('close');
                }
            });

        },
        'Refuser': function(){
            $(this).dialog('close');
        }
    },
    close: function(){
        // réinitialisation du dialogue à son état d'origine
        $('#divDialog').parent().html(dialogHtml);
        $('#divDialog').dialog(dialogConfig);
    }
};

var dialogHtml = null;

$(document).ready(
    function(){
        dialogHtml = $('#divDialog').parent().html();

        $('#divDialog').dialog(dialogConfig);

        $('#btnOpenDialog').click(
            function(){
                $('#divDialog').dialog('open');
            }
        );
    }
);

Comme le code JavaScript altère le contenu du dialogue généré par jQueryUI, il perdra son état initial lors d'une réouverture éventuelle. C'est pourquoi lors du chargement de la page, le balisage (markup) HTML initial est conservé dans la variable dialogHtml avant d'être transformé par jQuery pour pouvoir être réinitialisé au moment de fermer la boîte de dialogue.

Sinon, la clé de la solution réside dans l'inspection du code HTML généré par le contrôle Dialog. C'est seulement en regardant le HTML généré qu'on peut découvrir le nom des classes utilisées à l'interne par jQueryUI et les utiliser dans un sélecteur CSS pour altérer le DOM. À noter qu'on doit référer au contenur parent ajouté par jQueryUI pour englober le DIV utilisé pour générer le dialogue et lui donner son look.

Finalement, pour ceux qui désirent reproduire cet exemple, voici tout ce que long-process.php contient pour simuler une exécution plus lente côté serveur:
sleep(3);
echo 'OK'; 


Tags: JavaScript, Programmation

dimanche 25 novembre 2012

Citation no. 156 sur le talent

Publié par Infinite Loop, à 16 h 48 0 commentaire

Tout le monde a du talent. Ce qui est rare est le courage de suivre le talent à l'endroit obscur où il mène.

- Erica Jong


Tags: Citations

samedi 24 novembre 2012

Comme du jus de pieds de boeuf

Publié par Infinite Loop, à 09 h 27 1 commentaire

Dans mon sous-sol se cache un vrai bric-à-brac qui avait autrefois appartenu au propriétaire initial de la maison et dont j'ai hérité la responsabilité d'en faire le ménage lorsque je l'ai acquise suite à son décès. Entre le boulot et les rénovations, je n'avais pas eu beaucoup le temps de trier ce que j'allais garder et me départir jusqu'à tout récemment.

Une bouteille de verre graduée, très sale :


Sur l'étiquette à peine lisible :


 Huile de pieds de boeuf.

Rx Pharmacie Trépanier
Prescriptions - Analyses
Jacques Trépanier,  B.Ph., L.Ph.
7330 St-Hubert - Montréal
Tel. CA. 2124

Malgré son apparence banale, j'aime bien ce flacon, comme une antiquité qui témoigne d'une page d'histoire du quartier Villeray de Montréal. Surtout parce qu'une adresse, le nom d'un spécialiste et un numéro de téléphone y sont inscrits sur l'étiquette, on en connait l'origine.

Qu'est-ce qu'on peut bien faire avec de l'huile de pieds de boeuf ? À première vue, ça me semble un peu dégeulasse. Depuis combien d'années cette bouteille n'a pas été ouverte ? Je n'ose pas l'ouvrir et découvrir ce que ça sent. Et puis oui, j'ose. Ça ne sent rien de trop répugnant. Je goûte ? On se calme ! ;-)

Au XVIIIe siècle, elle était utilisée médicalement en pommade pour traiter les problèmes de peau sèche. De façon pratique, l'huile serait considérée comme le meilleur produit pour le traitement des cuirs désséchés. Selon ce que j'ai lu, ce serait à appliquer avec un pinceau sur le cuir jusqu'à ce qu'il l'ait tout absorbé (plusieurs couches peuvent être nécessaires). Est-ce encore aussi efficace après tant d'années ? Je l'ignore. Et quelle est la probabilité qu'un produit acheté au XXe siècle en pharmacie soit dédié à la restauration du cuir ? Les pharmacies de l'époque n'étaient pas comme celles d'aujourd'hui qui vendent à peu près n'importe quoi.

Jusqu'à quelle année les numéros de téléphone débutaient par des lettres, suivies de 4 chiffres ?

Selon la section La multiplication des numéros de téléphone sur les 125 ans de Bell Canada, on indique que :
Avec la croissance des appels interurbains, l'utilisation d'indicatifs régionaux s'impose. En 1945, pour uniformiser les numéros de téléphone, l'Amérique du Nord établit à sept le nombre de chiffres d'un numéro de téléphone et maintient l'indicatif régional à trois chiffres. Jusque dans les années 1950, les numéros de téléphone comprennent des lettres qui renvoient aux noms des centraux téléphoniques qui desservent les abonnés. Quelques années plus tard, en 1960, Bell Canada remplace les lettres par des chiffres.

Donc on suppose que la bouteille date au maximum des années 50.

Si je me fie à l'adresse actuelle dans le quartier Villeray, la vocation médicale du lieu n'aurait pas changée puisqu'on y trouve Lan Nguyen Pharmacienne. Le rôle foncier de la ville de Montréal indique que le bâtiment actuel aurait été construit en 1928.

J'en conclus que ça doit dater d'entre 1928 et 1950 et qu'elle est agée de 60 à 80 ans. Si quelqu'un a plus de précisions, n'hésitez pas à me contacter.

Des items comme ceux-là ont souvent pris le chemin des poubelles, ce qui en fait un objet d'une certaine rareté. Si, par hasard, quelqu'un de sa famille lit ce billet, je sais que ça peut avoir une valeur symbolique et je serais heureux de vous la remettre gratuitement. Pour l'instant, elle demeure dans ma collection.

Conclusion
Mis à jour le 21 décembre 2012

Lorsqu'on lance une bouteille à la mer, les chances qu'elle soit retrouvée sont minces. Si le hasard le veut bien, c'est à force de patience qu'elle pourra être recueillie un jour, peut-être bien des années plus tard. Coup de chance, ou la magie des internets, celle-ci n'aura eu besoin que quelques semaines pour être découverte par une lectrice de ce blogue qui a fait le rapprochement entre un Monsieur Trépanier qu'elle connait qui avait jadis été pharmacien. Une fois le lien confirmé, c'est sa fille, Lucie, qui m'a contacté pour récupérer le flacon dans le but d'en faire une surprise et de l'offrir à son père lors d'un souper familial.

Il y a quelques jours, je suis allé à la rencontre de Lucie pour la lui remettre. C'est une expérience peu ordinaire quand deux inconnus, avec pour seul lien commun un simple flacon, se donnent rendez-vous dans un centre d'achat pour échanger sur son histoire. Il n'aurait pas été surprenant de voir des gens attablés autour de nous jeter un coup d'oeil curieux face à deux étrangers qui contemplaient des photos d'époque et une petite bouteille de liquide jaunâtre... Rendu là, who cares!

Lucie m'a confirmé que l'origine du flacon devait dater des années 50, époque où son père a ouvert sa pharmacie sur la rue St-Hubert. Cette petite curiosité allait donc se retrouver entre les mains de celui qui l'avait jadis concocté, avec son lot d'histoire, anecdotes et secrets. J'ai de la difficulté à m'imaginer l'émotion qu'on peut ressentir quand on est en présence d'un objet qu'on a tenu dans ses mains une soixantaine d'années plus tôt, sans doute au tout début de sa carrière. Un objet aussi banal soit-il, qui n'a aucune valeur marchande mais qui, en même temps, n'a pas de prix.

Jusqu'à ce que je reçoive des photos de l'événement où Monsieur Trépanier était entouré de ses enfants, petits-enfants et arrières-petits-enfants. À l'approche de Noël, la conclusion de cette histoire a quelque chose de magique.


Dans notre dernière communication, Lucie n'aurait pas pu trouver plus juste que cette citation de Dominique Bretodeau dans Le fabuleux destin d’Amélie Poulain :
C'est drôle la vie. Quand on est gosse, le temps n'en finit pas de se traîner et puis, du jour au lendemain, on a comme ça 50 ans. Et l'enfance, tout ce qu'il en reste, ça tient dans une petite boîte. Une petite boîte rouillée.


C'est tellement vrai.

À l'approche de Noël, je tiens à souhaiter à la famille Trépanier, mes voeux les plus sincères. Je lève mon verre à cette rencontre fortuite qui a pu ajouter un brin de bonheur, autant de votre côté que du mien.

Salutations,

Mathieu


Tags: Histoire, Montréal

samedi 10 novembre 2012

Le traducteur de Bing est presque impressionnant

Publié par Infinite Loop, à 08 h 44 0 commentaire

En regardant les commentaires de la page Facebook de Code 18 à propos d'une publication, un utilisateur écrivit : "Awesome!". Oh oh, l'algorithme de la plateforme détecta un anglicisme sur une page francophone et après une analyse approfondie, il conclua en un risque élevé de mêler les lecteurs entre les langues de Molière et de Shakespeare. Fort d'un partenariat avec Microsoft (qui détient 1.6% du réseau social), les engrenages se mirent à tourner pour trouver une solution à ce problème gênant.

L'outil de traduction de Bing pourrait sauver la situation. Et comme rien n'est laissé au hasard, il est intégré à même Facebook avec pour mission de sauver les âmes égarées. À la vue du lien "Voir la traduction", je me suis senti rassuré au point de pouvoir mettre de côté mon inhalateur contre l'asthme.

Ma quiétude fut de courte durée...


Mis à part l'ajout d'un espace entre le mot et le point d'exclamation, Bing est incapable de traduire adéquatement ce simple mot du dictionnaire. Vous en aurez la preuve si vous en faites l'essai directement sur l'outil. Pourtant, en faisant parti de la phrase "It's awesome", il réussit à nous sortir "c'est génial".

Techniquement, c'est aussi possible que si Facebook détecte un commentaire dans une autre langue, qu'il lance un appel à l'API de Bing pour obtenir la traduction correspondante et qu'il l'affiche uniquement si les deux termes sont différents, ce qui est le cas en raison de l'espace inséré.

Dans les autres moteurs de traduction :
  • BabelFish échoue (il est maintenant propulsé par Bing)
  • Google Translate fonctionne à merveille
  • Systran traduit correctement Awesome en Impressionnant mais peine à comprendre le sens de la phrase "bill is a great fan of mark messier" si les noms propres ne débutent pas par un lettre majuscule.
Donc Bing Translator a fait un fail. En bon français, un fail.


Tags: Curiosités

mardi 6 novembre 2012

Tracer une étoile en SVG

Publié par Infinite Loop, à 07 h 33 0 commentaire

Après plusieurs semaines de temps supplémentaire au travail, je retrouve un semblant de vie normale. J'ai pris du retard sur toutes mes obligations, j'ai des heures de sommeil à récupérer et malgré l'épuisement, je trouve le moyen de me réveiller à 4h30 du matin et ce même si je suis en vacances. Alors quoi de mieux que de profiter de l'insomnie pour dessiner des étoiles en SVG et en faire un petit article à la volée...

Dans un fichier texte vierge, insérez le code ci-dessous et enregistrez-le sous le nom etoile.svg.

<?xml version="1.0" standalone="yes"?>
<svg version="1.1"
viewBox="0.0 0.0 360.0 270.0"
stroke-miterlimit="10"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path
    d="M 120
       74 L 149
       74 L 158
       48 L 167
       74 L 196
       74 L 172.5
       90 L 181.5
       116 L 158
       100 L 134.5
       116 L 143.5
       90
       Z"
    fill="#FFD300"
    fill-opacity="0.4"
    stroke="#FFD300"
    stroke-width="3.0"
>
</path>
</svg>

Comme vous l'auriez fait pour une image PNG, JPG ou GIF, vous pouvez spécifier le chemin du fichier comme source de la balise IMG :
<img src="etoile.svg" />

Résultat + variante aux coins ronds


Définition SVG
  • viewBox : le canvas défini par les coordonnées x, y, largeur et hauteur
  • stroke-miterlimit : la distance du biseautage de l'angle de deux segments qui se rencontrent
Path
  • d : les données du tracé où
    • M = move to
    • L = line to
    • Z = fin du tracé
  • fill : couleur de remplissage
  • fill-opacity : opacité du remplissage (valeur entre 0 et 1)
  • stroke : couleur du contour
  • stroke-width : épaisseur du contour
  • stroke-linejoin : la bordure des jointures de lignes
  • Pour des coins arrondis, il suffira d'ajouter la propriété stroke-linejoin="round"


Tags: HTML

Messages plus récents Messages plus anciens Accueil
S'abonner à : Messages (Atom)
    Suivre @code18 sur Twitter

    Catégories

    • Apache (21)
    • Citations (167)
    • Club Vidéo (24)
    • Coffre à outils (55)
    • CSS (8)
    • Curiosités (117)
    • Design Pattern (2)
    • Drupal (8)
    • Easter Eggs (22)
    • Extensions Firefox (20)
    • GIMP (7)
    • Histoire (21)
    • HTML (32)
    • Humour (57)
    • Intégration (34)
    • iPod (12)
    • JavaScript (110)
    • Jeu de combat (6)
    • Le coin du geek (128)
    • Liens (12)
    • Linux (56)
    • Livres (78)
    • Lois et principes (46)
    • Marché des saveurs (26)
    • Mathématique (18)
    • Mobile (5)
    • Montréal (32)
    • Musique (112)
    • Pancartes et écriteaux (16)
    • Perl (8)
    • Pérou (1)
    • PHP (130)
    • PostgreSQL (44)
    • Programmation (105)
    • Saviez-vous que (55)
    • Sécurité (22)
    • SEO (5)
    • SQL Server (22)
    • Vieilles publicités (6)
    • Virtualisation (8)
    • Voyages (1)
    • Zend Framework (26)

    Divers

    Archives

    • ►  2015 (6)
      • ►  août 2015 (1)
      • ►  juillet 2015 (1)
      • ►  février 2015 (3)
      • ►  janvier 2015 (1)
    • ►  2014 (8)
      • ►  décembre 2014 (1)
      • ►  novembre 2014 (1)
      • ►  octobre 2014 (1)
      • ►  août 2014 (2)
      • ►  juillet 2014 (2)
      • ►  janvier 2014 (1)
    • ►  2013 (53)
      • ►  décembre 2013 (2)
      • ►  novembre 2013 (1)
      • ►  octobre 2013 (3)
      • ►  septembre 2013 (2)
      • ►  août 2013 (5)
      • ►  juillet 2013 (3)
      • ►  juin 2013 (5)
      • ►  mai 2013 (3)
      • ►  avril 2013 (7)
      • ►  mars 2013 (7)
      • ►  février 2013 (11)
      • ►  janvier 2013 (4)
    • ▼  2012 (105)
      • ►  décembre 2012 (8)
      • ▼  novembre 2012 (5)
        • Click unique sur un bouton jQueryUI dialog
        • Citation no. 156 sur le talent
        • Comme du jus de pieds de boeuf
        • Le traducteur de Bing est presque impressionnant
        • Tracer une étoile en SVG
      • ►  octobre 2012 (4)
      • ►  septembre 2012 (1)
      • ►  août 2012 (8)
      • ►  juillet 2012 (7)
      • ►  juin 2012 (7)
      • ►  mai 2012 (10)
      • ►  avril 2012 (13)
      • ►  mars 2012 (15)
      • ►  février 2012 (15)
      • ►  janvier 2012 (12)
    • ►  2011 (146)
      • ►  décembre 2011 (14)
      • ►  novembre 2011 (11)
      • ►  octobre 2011 (12)
      • ►  septembre 2011 (13)
      • ►  août 2011 (15)
      • ►  juillet 2011 (17)
      • ►  juin 2011 (18)
      • ►  mai 2011 (15)
      • ►  avril 2011 (9)
      • ►  mars 2011 (7)
      • ►  février 2011 (3)
      • ►  janvier 2011 (12)
    • ►  2010 (398)
      • ►  décembre 2010 (29)
      • ►  novembre 2010 (28)
      • ►  octobre 2010 (32)
      • ►  septembre 2010 (34)
      • ►  août 2010 (22)
      • ►  juillet 2010 (35)
      • ►  juin 2010 (42)
      • ►  mai 2010 (36)
      • ►  avril 2010 (37)
      • ►  mars 2010 (34)
      • ►  février 2010 (32)
      • ►  janvier 2010 (37)
    • ►  2009 (429)
      • ►  décembre 2009 (32)
      • ►  novembre 2009 (34)
      • ►  octobre 2009 (33)
      • ►  septembre 2009 (37)
      • ►  août 2009 (37)
      • ►  juillet 2009 (39)
      • ►  juin 2009 (38)
      • ►  mai 2009 (37)
      • ►  avril 2009 (35)
      • ►  mars 2009 (36)
      • ►  février 2009 (32)
      • ►  janvier 2009 (39)
    • ►  2008 (84)
      • ►  décembre 2008 (34)
      • ►  novembre 2008 (39)
      • ►  octobre 2008 (11)

    Abonnés

Copyright © All Rights Reserved. Code 18 | Converted into Blogger Templates by Theme Craft