banneer

Réducteur d'URL tinad:

Collez l'adresse du site:

Rechercher sur le blog du grouik:

Catégorie: Informatique › dev web

Fil des billets - Fil des commentaires

bulle_tchat-406.jpgUn tchat, mélangeant les techniques suivantes: javascript, AJAX, PHP, mysql et JSON, en moins de 150 lignes. Il y a quelques mois Hempstar proposait sur ce blog sa version du chat. Comme j'ai énormément progressé dans ces langages de programmation, je me demandais si je saurai le faire, en quelques heures, en bouffant moins de ressources réseau.

Réponse: Oui, sans trop lutter; Le voici à l'aide d'une iframe:

Mises à jour fev 2012:

  • smileys (désactivables). Ceux que j'ai mis dans le package proviennent de phpBB3 http://www.phpbb.com/ en GNU GPL licence V2 (enfin je crois).
  • Les caracteres + et & n'étaient pas pris en charge. c'est résolu.
  • la barre de défilement ne descend automatiquement que s'il y a des nouveaux messages.
  • la touche e,ntrée envoie le message, pas un retour à la ligne.

Pour l'installer:

Creez la table tchat dans une base de données:

  1. CREATE TABLE `tchat` (
  2. `time` TIMESTAMP NOT NULL ,
  3. `pseudo` TEXT NOT NULL ,
  4. `message` TEXT NOT NULL ,
  5. PRIMARY KEY ( `time` , `pseudo` ( 5 ) )
  6. ) ENGINE = MYISAM
  • Télécharger l'archive là: tchat.tar.gz
  • Décompressez la dans un dossier sur votre site
  • Editez le fichier index.php pour renseigner les paramètres de la base de données

C'est pret!

Quelques explications sur le code:

La base de données

Basique:

  1. CREATE TABLE `tchat` (
  2. `time` TIMESTAMP NOT NULL ,
  3. `pseudo` TEXT NOT NULL ,
  4. `message` TEXT NOT NULL ,
  5. PRIMARY KEY ( `time` , `pseudo` ( 5 ) )
  6. ) ENGINE = MYISAM

le code PHP

Deux fonctions: l'enregistrement d'un nouveau message et l'envoi des informations sur les nouveaux messages dans un tableau au format JSON. Lors du refresh on n'envoie que les messages dont la date est supérieure à celle passée en variable POST $lasttime. L'enregistrement se contente d'une requête et ne retourne rien.

  1. <?php
  2. //**********Options à parametrer**************
  3. $nombreDeMessagesGardes=50;
  4. $enableSmileys=true;
  5. $smileysPath="smilies/";
  6. $mysqlparam=array(
  7. 'username' => '',
  8. 'password' => '',
  9. 'host' => 'localhost',
  10. 'database' => ''
  11. );
  12. //********** Fin des options ************
  13.  
  14. //connexion mysql
  15. if (!mysql_connect($mysqlparam['host'], $mysqlparam['username'], $mysqlparam['password'])) {
  16. erreur('Impossible de se connecter à MySQL');
  17. die;
  18. }
  19. mysql_query("USE ".$mysqlparam['database']);
  20. //Nettoyer les variables en entrée
  21. foreach($_POST as $keyname =>$value){
  22. }
  23. if (!isset($act)){
  24. $act="";
  25. }
  26. switch($act)
  27. {
  28. case "refresh":
  29. if(!isset($lasttime)){
  30. die;
  31. }
  32. //echo "SELECT time,pseudo,message FROM tchat WHERE time > '".$lasttime."' ORDER BY time ASC LIMIT 0,50";
  33. $rs=mysql_query("SELECT time,pseudo,message FROM tchat WHERE time > '".$lasttime."' ORDER BY time DESC LIMIT 0".$nombreDeMessagesGardes);
  34. while($r=mysql_fetch_row($rs)){
  35. $messages[]=array($r[0],$r[1],$r[2]);
  36. }
  37. $messages=array_reverse($messages);
  38. echo(json_encode($messages));
  39. die;
  40. break;
  41. case "add":
  42. if((!isset($pseudo)) OR ($pseudo =="") OR (!isset($message)) OR ($message=="")){
  43. echo "variable vide";
  44. die; //il y a un probleme, on kill le script
  45. }
  46. if($enableSmileys AND file_exists($smileysPath."smileys.php")){
  47. //les smilays
  48. include $smileysPath."smileys.php";
  49. foreach($phpbb_smilies as $smile){
  50. $message=str_replace($smile['code'],'<img src="'.$smileysPath.$smile['smiley_url'].'" alt="'.$smile['smiley_url'].'"/>',$message);
  51. }
  52. }
  53. mysql_query("INSERT INTO tchat (time,pseudo,message) VALUES (NOW(),'".$pseudo."','".$message."')");
  54. die;
  55. break;
  56.  
  57. case "":
  58. break;
  59. default:
  60. //aucun des cas prévu, on stoppe le script.
  61. die;
  62. break;
  63. }
  64. ?>

Le code javascript

Trois function, la functrion ajax utilisée par les deux autres pour faire des appels au serveur, la function pour ajouter un message et la function pour raffraichir le tchat. Cette dernière est bouclée : t=setTimeout("refreshchat(lasttime)",3000); permet de la rappeler 3 secondes plus tard (délai qui me semble un bon compromis entre la charge réseau et la fluidité).

L'array contenant les derniers messages du tchat est récupéré de cette manière:

  1. eval ("messages = " + xhr.responseText);

Et pour les ajouter à la fin, J'utilise le DOM avec la function appendChild:

  1. var pmessage=document.createElement("p");
  2. pmessage.innerHTML='<em class="date">'+ messages[l][0] + '</em><em class="pseudo">' + messages[l][1] + ':</em>' + messages[l][2];
  3. document.getElementById("tchat").appendChild(pmessage);
  1. function onKeyEnter(key)
  2. {
  3. if (key == 13) {
  4. sendmessage(document.getElementById('pseudo').value,document.getElementById('message').value);
  5. return true;
  6. }
  7. return false;
  8. }
  9. function Ajx()
  10. {
  11. var request = false;
  12. try {request = new ActiveXObject('Msxml2.XMLHTTP');}
  13. catch (err2) {try {request = new ActiveXObject('Microsoft.XMLHTTP');}
  14. catch (err3) {try {request = new XMLHttpRequest();}
  15. catch (err1) {request = false;}
  16. }
  17. }
  18. return request;
  19. }
  20. function refreshchat(time)
  21. {
  22. var xhr = Ajx();
  23. xhr.onreadystatechange = function(){if(xhr.readyState == 4){
  24. if(xhr.status == 200) {
  25. var messages= new Array();
  26. eval ("messages = " + xhr.responseText);
  27. var yaDesNouveauxMessages=false;
  28. for (var l in messages){
  29. yaDesNouveauxMessages=true;
  30. var pmessage=document.createElement("p");
  31. pmessage.innerHTML='<em class="date">'+ messages[l][0] + '</em><em class="pseudo">' + messages[l][1] + ':</em>' + messages[l][2];
  32. document.getElementById("tchat").appendChild(pmessage);
  33. lasttime=messages[l][0];
  34. }
  35. if (yaDesNouveauxMessages){
  36. //on redescend la scrollbar
  37. document.getElementById("tchat").scrollTop=document.getElementById("tchat").scrollHeight;
  38. }
  39. t=setTimeout("refreshchat(lasttime)",3000);
  40. }else{
  41. alert("Error code " + xhr.status);
  42. }
  43. }};
  44. xhr.open("POST", "index.php", true);
  45. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  46. xhr.send('act=refresh&lasttime=' + time);
  47. }
  48. function sendmessage(pseudo,message)
  49. {
  50. pseudo = pseudo.replace(/&/g,"%26");
  51. message= message.replace(/&/g,"%26");
  52. pseudo = pseudo.replace(/\+/g,"%2B");
  53. message= message.replace(/\+/g,"%2B");
  54. if ((message=='') || (pseudo=='')){
  55. alert('Veuillez mettre un pseudo et un message');
  56. }
  57. var xhr = Ajx();
  58. xhr.onreadystatechange = function(){if(xhr.readyState == 4){
  59. if(xhr.status == 200) {
  60. document.getElementById("message").value="";
  61. }else{
  62. alert("Error code " + xhr.status);
  63. }
  64. }};
  65. xhr.open("POST", "index.php", true);
  66. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  67. xhr.send('act=add&pseudo=' + pseudo + '&message=' + message );
  68. }

Le Body HTML:

<body>
<div id="page">
<div id="tchat">
  <script type="text/javascript">
	<!--
		lasttime='0';
		refreshchat(lasttime);
	//-->
  </script>
</div>
<div id="reponse">
  <fieldset><legend>Envoyer un message</legend>
    <label for="pseudo">Pseudonyme:</label><input type="text" id="pseudo"/>
    <label for="message">Message</label><textarea onkeypress="onKeyEnter(event.keyCode);" id="message"></textarea>
    <input type="button" value="Envoyer" onClick="sendmessage(document.getElementById('pseudo').value,document.getElementById('message').value);"/>
  </fieldset>
</div>
</div>
</body>

C'est super sommaire comme tchat.

Il vous faudra probablement coder certains certains compléments, comme l'authentification des utilisateurs, faire des salons différents etc... L'objectif ici était juste de montrer que c'est pas tres dur, pas de fournir un produit fini, mais plutot un struc simple et facilement intégrable sur un blog, site ou extranet...

Je m'envoie quelques fleurs:

Au niveau de la charge serveur, il n'y a pas de session ouverte (mémoire économisée), Le retour d'information est relativement optimisé grâce au JSON. Idéalement on pourrait mettre en cache la valeur du dernier timestamp pour n'ouvrir une connexion mysql que s'il y a des messages au timestamp supérieur à celui envoyé par la navigateur (et donc dans la majorité des cas ne même pas ouvrir de connexion mysql).


E-mailVoici une fonction pour envoyer un e-mail en PHP avec des pièces jointes quelque soit leur extension (ou presque).

La machine qui m'a servi à faire les tests est un champs MX du domaine, et l'adresse de l'expéditeur appartient au domaine (ça aide.)

Le résultat des essais:

  • Vers une boite e-mail free -> OK
  • Vers une boite e-mail du travail (c'est un postfix maison) -> OK
  • Vers une boite hotmail -> OK
  • Vers une boite aol: ça passe dans les spam
  • Vers une boite gmail -> OK

Plusieurs façons de fournir les pièces jointes sont possibles. les explications sont données au deuxième bloc de commentaire.

L'écriture de ce script a été possible grace à un tutoriel du site du zéro qui m'a bien servi de support.

Voici quelques exemples d'utilisation (qui m'ont servi pour les tests):

  1. //on post files
  2. SendEmailwidthJoin($_POST['messageTXT'],$_POST['messageHTML'],$_POST['destinataire'],$_POST['expediteur'],$_FILES,$_POST['objet']);
  3. // on array files
  4. SendEmailwidthJoin($_POST['messageTXT'],$_POST['messageHTML'],$_POST['destinataire'],$_POST['expediteur'],array('/var/www/AAPC.doc','/var/www/consultation.doc'),$_POST['objet']);
  5. //juste un string
  6. SendEmailwidthJoin($_POST['messageTXT'],$_POST['messageHTML'],$_POST['destinataire'],$_POST['expediteur'],'/var/www/AAPC.doc',$_POST['objet']);

Voici la function:

  1. <?php
  2. function FilePathToArray($leFichier)
  3. {
  4. if (!file_exists($leFichier)){
  5. return false;
  6. }
  7. $AboutTheFile=pathinfo($leFichier);
  8. return array(
  9. 'chemin' => $leFichier,
  10. 'nom' => $AboutTheFile['filename'],
  11. 'extension'=>$AboutTheFile['extension'],
  12. 'mimeType'=> mime_content_type($leFichier),// mime_content_type est une function obsolète (je sais), mais bien pratique.
  13. 'contenu' => chunk_split(base64_encode(file_get_contents($leFichier))) //ounch les ressources
  14. );
  15.  
  16. }
  17. function SendEmailwidthJoin($message_txt,$message_html,$destinataire,$expediteur,$fichiersAJoindre,$objet,$replyTo="" )
  18. {
  19. /*
  20.   * Envoie un e-mail "propre" avec des pièces jointes
  21.   *
  22.   * Codé par gnieark http://blog-du-grouik.tinad.fr février 2012
  23.   * Distribué sans aucune garantie dans les conditions établies là http://blog-du-grouik.tinad.fr/pages/Mentions-l%C3%A9gales
  24.   *
  25.   * Vous ne devez pas supprimer ce bloc de commentaires.
  26.   *
  27.   * La création de ce code est en tres grande partie basée sur le tutoriel de Weaponsb qui a sévi sur le site du zéro:
  28.   * "Envoyer un e-mail en PHP" http://www.siteduzero.com/tutoriel-3-35146-e-mail-envoyer-un-e-mail-en-php.html
  29.   *
  30.   */
  31.  
  32. /*
  33.   * *** How to use this function ***
  34.   * $fichiersAJoindre peut être:
  35.   * - un string contenant le chemin vers un seul fichier
  36.   * - un array sous la forme array('Chemin/Vers/Fichier1.ext','/chemin/vers/fichiers2', etc...);
  37.   * - un array structuré comme la super variable globale PHP $_FILES:
  38.   * $array('file1' => array('
  39.   * 'name' => ,
  40.   * 'type' => ,
  41.   * 'tmp_name' => ,
  42.   * 'error' => ,
  43.   * 'size' => ),
  44.   * 'file2' => array(
  45.   * (..)etc)
  46.   * )
  47.   * /!\ Aucune vérification sur du directory transversal n'est faite au niveau de cette function.
  48.   * En cas de variables fournies par l'utilisateur, prenez le soin de protéger en amont de cette function.
  49.   * $message_txt (obligatoire contient le message au format txt)
  50.   * $message_html facultatif (envoyez une string vide "" si vous ne souhaitez pas envoyer votre message en html)
  51.   * $destinataire : 'nom@fai.com' ou '"Nom Prenom<nom@fai.com>"' ou '"Nom1 Prenom1<nom1@fai.com>,Nom2 Prenom2<nom2@fai.com>"'
  52.   * $expediteur: idem
  53.   * $replyTo: facultatif, si différent de l'expéditeur.
  54.   */
  55.  
  56.  
  57. //=== vérifier et préparer les pieces jointes:
  58. $arrayFiles=array();
  59. if (is_string($fichiersAJoindre)){
  60. $lesFichiers[]= FilePathToArray($fichiersAJoindre);
  61. }
  62. if (is_array($fichiersAJoindre)){
  63. //tester si c'est du type $_FILES
  64. if ((isset($fichiersAJoindre[0])) AND (is_string($fichiersAJoindre[0])) ){
  65. //un array simple avec des strings
  66. foreach($fichiersAJoindre as $stringFile){
  67. $lesFichiers[]= FilePathToArray($stringFile);
  68. }
  69. }else{
  70. //de type $_FILES
  71. foreach($fichiersAJoindre as $arrayFiles){
  72. $aboutFile=pathinfo($arrayFiles['name']);
  73. $lesFichiers[]=array(
  74. 'chemin' => getenv('TMP')."/".$arrayFiles['tmp_name'],
  75. 'nom' => $aboutFile['filename'],
  76. 'extension'=>$aboutFile['extension'],
  77. 'mimeType'=> mime_content_type(getenv('TMP')."/".$arrayFiles['tmp_name']),// mime_content_type est une function obsolète (je sais), mais bien pratique.
  78. 'contenu' => chunk_split(base64_encode(file_get_contents($arrayFiles['tmp_name']))) //ounch les ressources
  79. );
  80. }
  81. }
  82. }
  83.  
  84.  
  85. //===générer les délimiteurs dans l'email ===
  86. do{
  87. $leRand=md5(rand());
  88. $boundary = "-----=".$leRand;
  89. }while(!strpos($message_txt.$message_html, $leRand) === false); // oui, la vérification là , c'est du zèle.
  90.  
  91. do{
  92. $leRand=md5(rand());
  93. $boundary_alt = "-----=".md5(rand());
  94. $isOK=true;
  95. foreach($lesFichiers as $fichier){
  96. if(!strpos($fichier['contenu'], $leRand) === false){
  97. $isOK=false;
  98. }
  99. }
  100. }while($isOK==false);//là en plus d'etre du zele, ça bouffe les ressources
  101.  
  102. //=== le type de retour à la ligne ===
  103. if (!preg_match("#^[a-z0-9._-]+@(hotmail|live|msn).[a-z]{2,4}$#", $destinataire)){
  104. $passage_ligne = "\r\n";
  105. }else{
  106. $passage_ligne = "\n";
  107. }
  108.  
  109. //=== header ===
  110. $headers ="From: ".$expediteur.$passage_ligne;
  111. if ($replyTo==""){
  112. $headers.= "Reply-to: ".$expediteur.$passage_ligne;
  113. }else{
  114. $headers.= "Reply-to: ".$replyTo.$passage_ligne;
  115. }
  116.  
  117. $headers.= "MIME-Version: 1.0".$passage_ligne;
  118. $headers.= "Content-Type: multipart/mixed;".$passage_ligne." boundary=\"".$boundary."\"".$passage_ligne;
  119.  
  120. //=====Création du message.
  121. $message = $passage_ligne."--".$boundary.$passage_ligne;
  122. $message.= "Content-Type: multipart/alternative;".$passage_ligne." boundary=\"$boundary_alt\"".$passage_ligne;
  123.  
  124. //=====Ajout du message au format texte.
  125. if ($message_txt!=""){
  126. $message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
  127. $message.= "Content-Type: text/plain; charset=\"ISO-8859-1\"".$passage_ligne;
  128. $message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
  129. $message.= $passage_ligne.$message_txt.$passage_ligne;
  130. }
  131. //==========
  132.  
  133. //=====Ajout du message au format HTML.
  134. if ($message_html!=""){
  135. $message.= $passage_ligne."--".$boundary_alt.$passage_ligne;
  136. $message.= "Content-Type: text/html; charset=\"ISO-8859-1\"".$passage_ligne;
  137. $message.= "Content-Transfer-Encoding: 8bit".$passage_ligne;
  138. $message.= $passage_ligne.$message_html.$passage_ligne;
  139. //On ferme la boundary alternative.
  140. $message.= $passage_ligne."--".$boundary_alt."--".$passage_ligne;
  141. }
  142. //==========
  143.  
  144. //pièces jointes
  145. foreach($lesFichiers as $fileArray)
  146. {
  147. $message.= $passage_ligne."--".$boundary.$passage_ligne;
  148.  
  149. $message.="Content-Type: ".$fileArray['mimeType']."; name=\"".$fileArray['nom'].".".$fileArray['extension']."\"".$passage_ligne;
  150. $message.="Content-Transfer-Encoding: base64".$passage_ligne;
  151. $message.="Content-Disposition: attachment; filename=\"".$fileArray['nom'].".".$fileArray['extension']."\"".$passage_ligne;
  152. $message.= $passage_ligne.$fileArray['contenu'].$passage_ligne.$passage_ligne;
  153. }
  154. $message.= $passage_ligne."--".$boundary."--".$passage_ligne;
  155. //echo $message;
  156. //Envoi du mail
  157. mail($destinataire, $objet, $message, $headers);
  158. }
  159. ?>

l'icone "e-mail" en en tête de ce billet provient du site economie-numerique.net



Internet explorer interprète mal ou pas du tout la function setAttribute. Ci dessous mon prototype à insérer en début de script pour patcher ce navigateur. Il manque surement des cas particuliers que je n'ai pas pris en compte, il suffira de rajouter des "case" dans ce prototype.

  1. if(navigator.appName == 'Microsoft Internet Explorer'){
  2. //patch pour IE
  3. Element.prototype.setAttribute = function(attribut,valeur){
  4. switch(attribut)
  5. {
  6. case "onClick":
  7. case "onMouseOut":
  8. case "onMouseOver":
  9. eval('this.' + attribut.toLowerCase() + '=function(){' + valeur +'}');
  10. return;
  11. break;
  12. /*
  13. *EDIT
  14. * Meme De cette manière le changement de type ne fonctionne pas sous IE9
  15. * Il ne veut pas prendre le parentNode de l'objet prototypé.
  16. * Du coup la function this.parentNode.replaceChild génére une erreur
  17. * Il vaut mieux se passer de changer le type d'un input.
  18. * setAttribute("type".... fonctionne quand même
  19. * pour un objet dont le type n'a pas encore été défini.
  20. case "type":
  21. //detruire entierement pour le refaire
  22. var newObject = document.createElement(this.tagName);
  23. newObject.type = valeur;
  24. if(this.size) newObject.size = this.size;
  25. if(this.value) newObject.value = this.value;
  26. if(this.name) newObject.name = this.name;
  27. if(this.id) newObject.id = this.id;
  28. if(this.className) newObject.className = this.className;
  29. this.parentNode.replaceChild(newObject,this);
  30. return;
  31. break;
  32. */
  33. case "class":
  34. var correctAttribut="className";
  35. break;
  36. default:
  37. var correctAttribut=attribut;
  38. break;
  39. }
  40. eval('this.' + correctAttribut + '="' + valeur +'"');
  41. }
  42. }

Voila, avec ça, je vais corriger mon sélecteur de dates pour qu'il marche avec IE


calendriers.jpg

Edit du 17/11/2011, passage en version 0.3.1 pour patcher internet explorer. test ok sur IE8 et IE 9, les autres versions n'ont pas été testées.

L'objet de ce codage est de permettre l'intégration simple (#feignasse) sur des sites web d'un sélecteur de date plus sexy que 3 listes déroulantes. Je me suis inspiré du "datetimepicker" que l'on trouve dans les objets comdlg [1] Voici la version 0.3 .1du sélecteur de dates en javascript By gnieark. Les modifications par rapport à la précédente sont:

  • Le code se greffe sur un <input type="text"> permettant aux personnes ayant désactivé javascript de quand même avoir un moyen de renseigner la date.
  • Il détecte si l'écran est tactile[2]. Si c'est le cas, ce sont 3 listes déroulantes (jour, mois, année) qui sont générées. Le datetimepicker n'étant pas idéal pour les gros doigts.
  • On peut naviguer dans le temps (Doctor Who tu es là?) par le mois et l'année pour aller plus vite.
  • Lors du déroulement, il ne décale plus tout ce qui est autours de lui, mais se place par dessus (CSS Powa!).

J'ai pris en compte une partie des remarques de Franck, de Zigazou et les trucs qui me chiffonnaient pour cette évolution.

Présentation du sélecteur de date:

Le voici dans une iframe (URL de la page: http://blog-du-grouik.tinad.fr/public/datetimepicker/)

Intégration et code source:

Creez un script javascript sur votre page ou ajoutez ceci au js existant:

J'ai volontairement mis des noms de function assez tordus afin d'éviter les collisions avec d'autres codes lors de l'intégration. De plus, seules les array lesJours, lesJoursFull,lesMois sont des variables globales. Vous avez peu de chance que ce code parasite vos autres scripts javascript.

Voir le code non minifié --- datepicker.js

Créez ou ajoutez ceci au CSS de votre page:

  1. .dateTimePicker{ height: 15px; font-size: 10px;}
  2. .dateTimePicker table {
  3. position: absolute;
  4. margin: 0px;
  5. padding: 0px;
  6. background-color:#FFF0F5;
  7. width: 200px;
  8.  
  9. }
  10. .dateTimePicker table tbody{
  11. position: relative;
  12.  
  13. }
  14. .dateTimePicker table tbody tr td{
  15. text-align: center;
  16.  
  17. }
  18. .dateTimePicker table tbody tr td.dayUnSelected{
  19. background-color: #A3AED3;
  20. cursor: pointer;
  21. }
  22. .dateTimePicker table tbody tr td.daySelected{
  23. color : #666;
  24. background-color: #DDDDDD;
  25. cursor: pointer;
  26. border:1px solid #005BAA;
  27. }
  28. .dateTimePicker table tbody tr td.dayWrongMonth{
  29. background-color: #fff;
  30. cursor: pointer;
  31. }
  32. .dateTimePicker table tbody tr td.dayUnSelected:hover{
  33. color : #fff;
  34. }
  35. .dateTimePicker table tr th{
  36. color : #fff;
  37. background-color: #59627A;
  38. cursor: pointer;
  39. }
  40. .dtPickerOff {
  41. display: none;
  42. }
  43. .dtPickerEmButton{
  44. cursor: pointer;
  45. }
  46. .dtPickerEmButton:hover{
  47. color : #fff;
  48. background-color: #59627A;
  49. }
  50. .dtPickerOn{}
  51. .dateTimePicker table tbody tr.dtPickerNavTr td{border:1px solid #005BAA;}

Intégration sur la page

Sur votre page web: Insérez un input de type text. c'est lui qui prendra la valeur de la date au format mysql: AAAA-MM-JJ. De cette manière si un visiteur n'active pas le javascript il pourra quand meme répondre.

De plus au niveau de l'intégration dans une <form> que la méthode soit en GET ou en POST, vous ne vous souciez pas du datetime picker en javascript pour récupérer la date. Ce dernier se charge de masquer le "input" en le transformant en <input type="hidden"> et de mettre à jour son attribut "value" lors des changements de date par l'utilisateur.

Juste après l'input vous appellez la function javascript dateTimePicker(elementInputDate, déroulé); où:

  • elementInputDate désigne l'input qui reçoit la date que l'on soite transformer. On peut l'appeller par son id comme ceci:document.getElementById("dtPicker")
  • déroulé est un boolean. true, il sera plié et se déroulera lors du survol du curseur; false: il est déplié en permanance.
  • Le sélecteur de date s'initialisera sur la date qu'il trouve dans l'input. S'il n'y arrive pas (champs vide ou mauvais format), il prendra la date actuelle.

Exemple:

  1. <input type="text" id="dtPicker" name="ladate" maxlength="9" value="2011-09-02"/>
  2. <script type="text/javascript">
  3. <!--
  4. dateTimePicker(document.getElementById("dtPicker"), true);
  5. -->
  6. </script>

L'input qui reçoit la date doit avoir un id unique sur la page (normal). Son "name" doit aussi être unique par rapport aux autres datetimepicker de la même date.

Ah j'oubliais; sous un écran tactile la sélection de dates par des listes déroulantes se présente ainsi: dtpicker-listes.jpeg

Notes

[1] Rah l'époque de Visual studio 6.0

[2] Testé sur Android 3 et 4 via le SDK


kill the spamJ'ai remarqué que les spammeurs qui sévissent sur mon blog, ont souvent ces deux points communs:

  • Le nom de l'auteur contient la description du site dont il fait la promotion, souvent plus de trois mots.
  • Il a renseigné un lien vers un site internet, évidemment.

Vu que dans les commentaires légitimes, je n'en trouve pas un seul répondant à ces deux contraintes, je viens d'écrire le petit pluggin qui ajoute le filtre "3Words1Link".

Il est tout simple:

Un lien renseigné + le nom découpé en au moins 3 mots = spam

Vous pouvez le télécharger là: filter3Words1Link.zip

Il s'installe comme n'importe quel pluggin, et apparait dans la liste des filtres de l'antispam de dotclear.

- page 1 de 15


Tous les billets de cette catégorie:

Propulsé par Dotclear