From ce001229accb2aff799560eec402344f0dbb1762 Mon Sep 17 00:00:00 2001 From: arno Date: Thu, 12 Aug 2010 15:20:03 +0200 Subject: [PATCH] ajax for account creation to known if a pseudo is available --- COPYING.TXT | 3 + application/configs/application.ini | 4 + application/controllers/IdxController.php | 7 +- application/controllers/UserController.php | 15 ++ application/forms/User.php | 4 +- application/languages/lang_en.po | 60 +++++--- application/languages/lang_fr.po | 62 ++++++--- application/models/UserMapper.php | 11 ++ public/icons/pseudo-throbber.gif | Bin 0 -> 1644 bytes public/js/syj.js | 155 +++++++++++++++++---- public/js/utils.js | 59 +++++++- 11 files changed, 300 insertions(+), 80 deletions(-) create mode 100644 public/icons/pseudo-throbber.gif diff --git a/COPYING.TXT b/COPYING.TXT index 5106604..b8188b7 100644 --- a/COPYING.TXT +++ b/COPYING.TXT @@ -7,6 +7,9 @@ Creative Commons Attribution 2.5 License. See http://www.famfamfam.com/lab/icons/silk/ for more informations. +- pseudo-throbber.gif files has been generated with http://ajaxload.info/ + generator and is free for use. + =============================================================================== diff --git a/application/configs/application.ini b/application/configs/application.ini index 5c37593..d6158be 100644 --- a/application/configs/application.ini +++ b/application/configs/application.ini @@ -66,6 +66,10 @@ resources.router.routes.login.defaults.action = "login" resources.router.routes.user.route = "user/" resources.router.routes.user.defaults.controller = "user" resources.router.routes.user.defaults.action = "user" +; userexists/ +resources.router.routes.userexists.route = "userexists/:name" +resources.router.routes.userexists.defaults.controller = "user" +resources.router.routes.userexists.defaults.action = "exists" ; logout/ resources.router.routes.logout.route = "logout/" resources.router.routes.logout.defaults.controller = "login" diff --git a/application/controllers/IdxController.php b/application/controllers/IdxController.php index 527f77e..9dc4300 100644 --- a/application/controllers/IdxController.php +++ b/application/controllers/IdxController.php @@ -97,14 +97,15 @@ class IdxController extends Zend_Controller_Action 'acceptTermsofuseWarn' => __("You must accept terms of use"), 'emailEmptyWarn' => __("you must enter an email"), 'emailInvalidWarn' => __("invalid email"), - 'invalidPseudo' => __("pseudo must only contain letters, digits, dots or underscores"), - 'uniqueUserError' => __("unavailable pseudo"), 'uniqueEmailError' => __("an user is already registered with this email"), 'userSuccess' => __("Account created"), 'newpwdSuccess' => __("A link to reset your password has been emailed to you"), 'canResubmit' => __("Now, you can retry to save"), 'routeBy' => __("route by"), - 'osmAttribution' => __("Map by OpenStreetMap") + 'osmAttribution' => __("Map by OpenStreetMap"), + 'pseudoChecking' => __("checking availibilty"), + 'availablePseudo' => __("available pseudo"), + 'unavailablePseudo' => __("unavailable pseudo"), ); } diff --git a/application/controllers/UserController.php b/application/controllers/UserController.php index 2bd41d3..f802b16 100644 --- a/application/controllers/UserController.php +++ b/application/controllers/UserController.php @@ -5,6 +5,21 @@ class UserController extends Zend_Controller_Action { + public function existsAction() { + $name = $this->getRequest()->getUserParam('name'); + + $userMapper = new Syj_Model_UserMapper(); + $user = new Syj_Model_User(); + + if ($userMapper->findByPseudo($name, $user)) { + $this->_helper->SyjApi->setCode(200); + } else { + // opera needs some body content with 404 code, otherwise, it + // reports a xmlhttprequest.status of 0 + $this->_helper->SyjApi->setCode(404)->setBody(' '); + } + } + public function userAction() { $formData = $this->_helper->SyjPostData->getPostData('Syj_Form_User'); diff --git a/application/forms/User.php b/application/forms/User.php index 40bd518..34a5608 100644 --- a/application/forms/User.php +++ b/application/forms/User.php @@ -7,9 +7,11 @@ class Syj_Form_User extends Syj_Form_TableAbstract public function init() { $translator = $this->getTranslator(); + $desc = $translator->translate("only letters, numbers, underscores or dots"); $name = array('Text', 'user_pseudo', array( 'label' => __("user name"), - 'attribs' => array('maxlength' => '20'), + 'attribs' => array('maxlength' => '20', 'autocomplete' => 'off'), + 'description' => $desc, 'validators' => array(new Zend_Validate_StringLength(0, 20), new Zend_Validate_Regex('/^[a-zA-Z0-9_\.]+$/')), 'required' => true diff --git a/application/languages/lang_en.po b/application/languages/lang_en.po index 298af29..fed1b8b 100644 --- a/application/languages/lang_en.po +++ b/application/languages/lang_en.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: syj\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-08-11 21:44+0200\n" +"POT-Creation-Date: 2010-08-12 14:16+0200\n" "PO-Revision-Date: \n" "Last-Translator: arno \n" "Language-Team: arno \n" @@ -110,7 +110,7 @@ msgid "Sources of the software running the website are publicly available under a agpl license. The map used to display the routes comes from openstreetmap." #: application/views/scripts/newpwd/success.phtml:4 -#: application/controllers/IdxController.php:103 +#: application/controllers/IdxController.php:101 msgid "A link to reset your password has been emailed to you" msgstr "A link to reset your password has been emailed to you" @@ -415,7 +415,7 @@ msgstr "Oups, something went wrong" #: application/controllers/TermsofuseController.php:12 #: application/layouts/scripts/footer.phtml:85 #: application/forms/Geom.php:24 -#: application/forms/User.php:41 +#: application/forms/User.php:43 msgid "terms of use" msgstr "terms of use" @@ -467,7 +467,7 @@ msgid "Wrong password" msgstr "Wrong password" #: application/controllers/AccountController.php:44 -#: application/controllers/IdxController.php:101 +#: application/controllers/IdxController.php:99 msgid "an user is already registered with this email" msgstr "an user is already registered with this email" @@ -479,7 +479,7 @@ msgstr "Password do not match" #: application/controllers/AccountController.php:73 #: application/forms/Account.php:33 -#: application/forms/User.php:18 +#: application/forms/User.php:20 #, php-format msgid "At least %d characters" msgstr "At least %d characters" @@ -520,30 +520,34 @@ msgstr "you must enter an email" msgid "invalid email" msgstr "invalid email" -#: application/controllers/IdxController.php:99 -msgid "pseudo must only contain letters, digits, dots or underscores" -msgstr "pseudo must only contain letters, digits, dots or underscores" - #: application/controllers/IdxController.php:100 -msgid "unavailable pseudo" -msgstr "unavailable pseudo" - -#: application/controllers/IdxController.php:102 msgid "Account created" msgstr "Account created" -#: application/controllers/IdxController.php:104 +#: application/controllers/IdxController.php:102 msgid "Now, you can retry to save" msgstr "Now, you can retry to save" -#: application/controllers/IdxController.php:105 +#: application/controllers/IdxController.php:103 msgid "route by" msgstr "route by" -#: application/controllers/IdxController.php:106 +#: application/controllers/IdxController.php:104 msgid "Map by OpenStreetMap" msgstr "Map by OpenStreetMap" +#: application/controllers/IdxController.php:105 +msgid "checking availibilty" +msgstr "checking availibilty" + +#: application/controllers/IdxController.php:106 +msgid "available pseudo" +msgstr "available pseudo" + +#: application/controllers/IdxController.php:107 +msgid "unavailable pseudo" +msgstr "unavailable pseudo" + #: application/layouts/scripts/footer.phtml:28 msgid "contact" msgstr "contact" @@ -554,7 +558,7 @@ msgstr "user" #: application/forms/Login.php:10 #: application/forms/Account.php:35 -#: application/forms/User.php:21 +#: application/forms/User.php:23 msgid "password" msgstr "password" @@ -591,7 +595,7 @@ msgid "optional title for this journey" msgstr "optional title for this journey" #: application/forms/Geom.php:25 -#: application/forms/User.php:42 +#: application/forms/User.php:44 #, php-format msgid "I've read and accepted %s" msgstr "I've read and accepted %s" @@ -602,13 +606,13 @@ msgid "save" msgstr "save" #: application/forms/Account.php:27 -#: application/forms/User.php:34 +#: application/forms/User.php:36 #: application/forms/Newpwd.php:28 msgid "email" msgstr "email" #: application/forms/Account.php:42 -#: application/forms/User.php:28 +#: application/forms/User.php:30 msgid "confirm password" msgstr "confirm password" @@ -620,15 +624,19 @@ msgstr "current password" msgid "modify my informations" msgstr "modify my informations" -#: application/forms/User.php:11 +#: application/forms/User.php:10 +msgid "only letters, numbers, underscores or dots" +msgstr "only letters, numbers, underscores or dots" + +#: application/forms/User.php:12 msgid "user name" msgstr "user name" -#: application/forms/User.php:35 +#: application/forms/User.php:37 msgid "After creating your account, you will receive a confirmation email. You have 7 days to confirm otherwise, your account and your routes will all be deleted." msgstr "After creating your account, you will receive a confirmation email. You have 7 days to confirm otherwise, your account and your routes will all be deleted." -#: application/forms/User.php:54 +#: application/forms/User.php:56 msgid "create account" msgstr "create account" @@ -659,6 +667,12 @@ msgstr "Someone, probably you, has registered an account %s with email address % msgid "To cancel account creation, press following button. The account and all its data will be deleted." msgstr "To cancel account creation, press following button. The account and all its data will be deleted." +#~ msgid "pseudo available" +#~ msgstr "pseudo available" +#~ msgid "pseudo not available" +#~ msgstr "pseudo not available" +#~ msgid "pseudo must only contain letters, digits, dots or underscores" +#~ msgstr "pseudo must only contain letters, digits, dots or underscores" #~ msgid "route has been deleted from the server." #~ msgstr "route has been deleted from the server." #~ msgid "You need to login before retrying to save" diff --git a/application/languages/lang_fr.po b/application/languages/lang_fr.po index 37c6d62..541112d 100644 --- a/application/languages/lang_fr.po +++ b/application/languages/lang_fr.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: syj\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-08-11 21:44+0200\n" +"POT-Creation-Date: 2010-08-12 14:16+0200\n" "PO-Revision-Date: \n" "Last-Translator: arno \n" "Language-Team: arno \n" @@ -110,7 +110,7 @@ msgid "Sources of the software running the website are disponibles publiquement sous une licence agpl. La carte utilisée pour l'affichage des itinéraires vient d'openstreetmap." #: application/views/scripts/newpwd/success.phtml:4 -#: application/controllers/IdxController.php:103 +#: application/controllers/IdxController.php:101 msgid "A link to reset your password has been emailed to you" msgstr "Un email contenant un lien pour réinitialiser votre mot de passe vous a été envoyé" @@ -417,7 +417,7 @@ msgstr "Oups, il y a eu un souci" #: application/controllers/TermsofuseController.php:12 #: application/layouts/scripts/footer.phtml:85 #: application/forms/Geom.php:24 -#: application/forms/User.php:41 +#: application/forms/User.php:43 msgid "terms of use" msgstr "conditions d'utilisation" @@ -469,7 +469,7 @@ msgid "Wrong password" msgstr "Mauvais mot de passe" #: application/controllers/AccountController.php:44 -#: application/controllers/IdxController.php:101 +#: application/controllers/IdxController.php:99 msgid "an user is already registered with this email" msgstr "il y'a déjà un utilisateur enregistré avec cet email" @@ -481,7 +481,7 @@ msgstr "Les mots de passe ne correspondent pas" #: application/controllers/AccountController.php:73 #: application/forms/Account.php:33 -#: application/forms/User.php:18 +#: application/forms/User.php:20 #, php-format msgid "At least %d characters" msgstr "Au moins %d caractères" @@ -522,30 +522,34 @@ msgstr "vous devez entrer un email" msgid "invalid email" msgstr "email invalide" -#: application/controllers/IdxController.php:99 -msgid "pseudo must only contain letters, digits, dots or underscores" -msgstr "le pseudo ne peut contenir que des lettres, des chiffres, des points ou des soulignés" - #: application/controllers/IdxController.php:100 -msgid "unavailable pseudo" -msgstr "pseudo non disponible" - -#: application/controllers/IdxController.php:102 msgid "Account created" msgstr "Compte créé" -#: application/controllers/IdxController.php:104 +#: application/controllers/IdxController.php:102 msgid "Now, you can retry to save" msgstr "Maintenant, vous pouvez réessayer de sauvegarder" -#: application/controllers/IdxController.php:105 +#: application/controllers/IdxController.php:103 msgid "route by" msgstr "tracé par" -#: application/controllers/IdxController.php:106 +#: application/controllers/IdxController.php:104 msgid "Map by OpenStreetMap" msgstr "Carte par OpenStreetMap" +#: application/controllers/IdxController.php:105 +msgid "checking availibilty" +msgstr "vérification de la disponibilité" + +#: application/controllers/IdxController.php:106 +msgid "available pseudo" +msgstr "pseudo disponible" + +#: application/controllers/IdxController.php:107 +msgid "unavailable pseudo" +msgstr "pseudo non disponible" + #: application/layouts/scripts/footer.phtml:28 msgid "contact" msgstr "contact" @@ -556,7 +560,7 @@ msgstr "utilisateur" #: application/forms/Login.php:10 #: application/forms/Account.php:35 -#: application/forms/User.php:21 +#: application/forms/User.php:23 msgid "password" msgstr "mot de passe" @@ -593,7 +597,7 @@ msgid "optional title for this journey" msgstr "titre facultatif pour ce trajet" #: application/forms/Geom.php:25 -#: application/forms/User.php:42 +#: application/forms/User.php:44 #, php-format msgid "I've read and accepted %s" msgstr "J'ai lu et accepté les %s" @@ -604,13 +608,13 @@ msgid "save" msgstr "enregistrer" #: application/forms/Account.php:27 -#: application/forms/User.php:34 +#: application/forms/User.php:36 #: application/forms/Newpwd.php:28 msgid "email" msgstr "email" #: application/forms/Account.php:42 -#: application/forms/User.php:28 +#: application/forms/User.php:30 msgid "confirm password" msgstr "confirmation du mot de passe" @@ -622,15 +626,19 @@ msgstr "mot de passe actuel" msgid "modify my informations" msgstr "modifier mes informations" -#: application/forms/User.php:11 +#: application/forms/User.php:10 +msgid "only letters, numbers, underscores or dots" +msgstr "seulement des lettres, des chiffres, des soulignés ou des points" + +#: application/forms/User.php:12 msgid "user name" msgstr "nom d'utilisateur" -#: application/forms/User.php:35 +#: application/forms/User.php:37 msgid "After creating your account, you will receive a confirmation email. You have 7 days to confirm otherwise, your account and your routes will all be deleted." msgstr "Après la création de votre compte, vous recevrez un mail de confirmation. Vous avez 7 jours pour confirmer sinon, votre compte et tous vos tracés seront supprimés." -#: application/forms/User.php:54 +#: application/forms/User.php:56 msgid "create account" msgstr "créer le compte" @@ -661,6 +669,14 @@ msgstr "Quelqu'un, probablement vous, a enregistré un compte %s avec l'adresse msgid "To cancel account creation, press following button. The account and all its data will be deleted." msgstr "Pour annuler la création du compte, pressez le bouton suivant. Le compte ainsi que toutes ses données seront supprimés." +#~ msgid "pseudo available" +#~ msgstr "pseudo disponible" +#~ msgid "pseudo not available" +#~ msgstr "pseudo non disponible" +#~ msgid "pseudo must only contain letters, digits, dots or underscores" +#~ msgstr "" +#~ "le pseudo ne peut contenir que des lettres, des chiffres, des points ou " +#~ "des soulignés" #~ msgid "You need to login before retrying to save" #~ msgstr "Vous devez vous connecter avant de réesayer de sauvegarder" #~ msgid "You need to have cookies enabled to login to SYJ" diff --git a/application/models/UserMapper.php b/application/models/UserMapper.php index 67faea8..3fc84aa 100644 --- a/application/models/UserMapper.php +++ b/application/models/UserMapper.php @@ -24,6 +24,17 @@ class Syj_Model_UserMapper return true; } + public function findByPseudo($pseudo, Syj_Model_User $user) { + $table = $this->getDbTable(); + $select = $table->select()->where('pseudo = ?', (string)$pseudo); + $row = $table->fetchRow($select); + if (!$row) { + return false; + } + $this->_itemFromRow($user, $row); + return true; + } + public function findByEmail($email, Syj_Model_User $user) { $table = $this->getDbTable(); $select = $table->select()->where('email = ?', (string)$email); diff --git a/public/icons/pseudo-throbber.gif b/public/icons/pseudo-throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..b61abe6d0275a086cf17ab3d3896c6e55e0206de GIT binary patch literal 1644 zcmbW%ZA?>F7zgmf?LD{m#rF2T7Vj;+r7M?$N~)5@WechI;%s@*vN5NE8%#hj20L}y z88T4|GO3`VyllgOOmuZoR2EDij9GPRq7s+}+`dRM7qi9Sk{R{GTvPfRM{nG? zQCV4OHk>G9Ep8{(V;*8279Yin!U+uK`PTVK9>Sy53D3svb`pIj0SDmlrwu%(^c2J#%QIDsLn#|uHdz$x_e+|jI)kLnr zj^I=kPr5#1T&eV-e1f#8DvS6DXf)s=C8sHhDz4rEXi+rCR%bNo7epIy$}I0XtD_gU zr^@n1_I(W*EIciz=iEoE$NjTVWG=MTTN|i!Tf&APf@yBv4EAmJ@a_cSG+3OJK@z|3 z3WnBn*1>M~A~$tq3)o#PlOsQ@5OSx^L=Im4yu>9R~IE;LCx)2R(fn4(A@U(=)uAmtX8n~UYJig~+erO7aIN++dB!)-=`SmI+^Kgmo&cT{W33j1AB%%_|DRCECuM z(Gi!T0)`Wy*<{w)iz0Aw_9Or?9aWW8sT^nZ|3cgCtZ&wf&h@s>WHvo$k7uCdf)6xb z(Yp9GU({xIdxg!fvkBv4>v&#|RV>==TZpH9^1+MhOuVtfF)D>o%I1&-NMjX6Y>LvP zNIY3oWJH@?0y&@Cgc>%8hf&;~Xkw4!sJ17G;jAVGJq8WB#BsRERNPXm(Sr;aHfx5< z8a^liW*EK)@YJ~6k}|2!V&PnDTO2#RYy%oAd*{2!g#gPvwbbQ9n;#L53u|$G{J_^o zw`7B+%okOAvfFNtPgGw* zr+3-~n@NUbgv55TsY%deYQ*t&=r@}zAhMP^rw^Ez*pJ|pj*X;)Ay|@=V}Qn9ZPtp- zwZ?}lQ2D|KkXVrL)MTZ2%X`*2?b_|}uE{O+4L7sLlMiQ6=QoGg)y{@no6=d(mz1CV zM?sBOqG>^dCDz3G8*o-^vO&hwV&eF4lgOf$V+;$)xO%6SVlqRt8`7|cSPSZrzHc#< z>Vv(&7@xf!1R;9#7(CTSXxDBIeBU>mix{-ad9zUCTxiG47I+$pC*aQ|9bbWl=FdHu zJV?45M*C{Aj&}DvbQh{h?PHytCr@L>rA$p4O&sO+j^x`}#mUO@YMqeXE;Y?sFI&+C z6l~*3wcaUGNLw3D8hIOK@V6Qf9HNjEMH`C)q>ygwBJfL>{BbL2GoXSf=zVbDtcF%= XNbH+)=W~8WC?aP$cyngA{#*Y5d4r^R literal 0 HcmV?d00001 diff --git a/public/js/syj.js b/public/js/syj.js index 4b7f01d..44dd2ff 100644 --- a/public/js/syj.js +++ b/public/js/syj.js @@ -1,20 +1,5 @@ /* This file is part of Syj, Copyright (c) 2010 Arnaud Renevier, and is published under the AGPL license. */ -Element.addMethods('input', { - observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) { - if (eventName === "contentchange") { - proceed(element, 'keyup', function(evt) { - if (evt.keyCode === 13) { - return; - } - handler.apply(null, arguments); - }); - proceed(element, 'paste', handler); - return proceed(element, 'change', handler); - } - return proceed(element, eventName, handler); - }) -}); // avoid openlayers alerts OpenLayers.Console.userError = function(error) { @@ -299,7 +284,7 @@ var SYJView = { }, prepareForm: function(form) { - if (!loginMgr.logged && !$("geom_accept").checked) { + if (!LoginMgr.logged && !$("geom_accept").checked) { this.messenger.setMessage(SyjStrings.acceptTermsofuseWarn, "warn"); $("geom_accept_container").highlight('#F08080'); $("geom_accept").activate(); @@ -571,6 +556,19 @@ var SYJUserClass = Class.create(SYJModalClass, { evt.stop(); }.bindAsEventListener(this)); + $("user_pseudo-desc").hide(); + $("user_pseudo").observe('contentchange', function(evt) { + var value = evt.target.value; + PseudoChecker.reset(); + if (value && !(value.match(/^[a-zA-Z0-9_.]+$/))) { + $("user_pseudo-desc").show().setMessageStatus("warn"); + } else { + $("user_pseudo-desc").hide(); + } + }).timedobserve(function() { + PseudoChecker.check(); + }); + $("user_password").observe('contentchange', function(evt) { if (evt.target.value.length < 6) { $("user_password-desc").setMessageStatus("warn"); @@ -594,12 +592,20 @@ var SYJUserClass = Class.create(SYJModalClass, { }, presubmit: function() { + this.messenger.hide(); + PseudoChecker.reset(); if (!(this.checkNotEmpty("user_pseudo", SyjStrings.userEmptyWarn))) { return false; } if (!($("user_pseudo").value.match(/^[a-zA-Z0-9_.]+$/))) { - this.messenger.setMessage(SyjStrings.invalidPseudo, "warn"); + $("user_pseudo-desc").show().setMessageStatus("warn"); + $("user_pseudo").highlight('#F08080').activate(); + return false; + } + + if (PseudoChecker.exists[$("user_pseudo").value]) { + PseudoChecker.availableMessage(false); $("user_pseudo").highlight('#F08080').activate(); return false; } @@ -636,7 +642,7 @@ var SYJUserClass = Class.create(SYJModalClass, { }, success: function(transport) { - loginMgr.login(); + LoginMgr.login(); SYJView.messenger.setMessage(SyjStrings.userSuccess, "success"); this.modalbox.hide(); if (SYJView.needsFormResubmit) { @@ -664,7 +670,7 @@ var SYJUserClass = Class.create(SYJModalClass, { focusInput = $("user_email"); break; case "uniquepseudo": - message = SyjStrings.uniqueUserError; + PseudoChecker.availableMessage(false); focusInput = $("user_pseudo"); break; case "uniqueemail": @@ -676,11 +682,11 @@ var SYJUserClass = Class.create(SYJModalClass, { break; } - if (message) { - this.messenger.setMessage(message, "error"); - if (focusInput) { - focusInput.highlight('#F08080').activate(); + if (focusInput) { + if (message) { + this.messenger.setMessage(message, "error"); } + focusInput.highlight('#F08080').activate(); return; } @@ -697,6 +703,7 @@ var SYJLoginClass = Class.create(SYJModalClass, { }, presubmit: function() { + this.messenger.hide(); if (!(this.checkNotEmpty("login_user", SyjStrings.userEmptyWarn))) { return false; } @@ -707,9 +714,9 @@ var SYJLoginClass = Class.create(SYJModalClass, { success: function(transport) { if (transport.responseText === "1") { - loginMgr.login(true); + LoginMgr.login(true); } else { - loginMgr.login(); + LoginMgr.login(); } SYJView.messenger.setMessage(SyjStrings.loginSuccess, "success"); this.modalbox.hide(); @@ -767,7 +774,7 @@ var SYJNewpwdClass = Class.create(SYJModalClass, { }); var SYJNewpwd = new SYJNewpwdClass(); -var loginMgr = Object.extend(gLoggedInfo, { +var LoginMgr = Object.extend(gLoggedInfo, { controlsdeck: null, updateUI: function() { @@ -800,10 +807,104 @@ var loginMgr = Object.extend(gLoggedInfo, { } }); +var PseudoChecker = { + req: null, + exists: {}, + currentvalue: null, + messageelt: null, + throbber: null, + + message: function(str, status, throbber) { + var row; + if (!this.messageelt) { + row = new Element('tr'); + // we can't use row.update('
') + // because gecko would mangle the s + row.insert(new Element('td')) + .insert((new Element('td')).update(new Element('div'))); + + $("user_pseudo").up('tr').insert({after: row}); + this.messageelt = new Element('span'); + this.throbber = new Element("img", { src: "icons/pseudo-throbber.gif"}); + row.down('div').insert(this.throbber).insert(this.messageelt); + } + if (throbber) { + this.throbber.show(); + } else { + this.throbber.hide(); + } + this.messageelt.up().setStyle({visibility: ''}); + this.messageelt.className = status; + this.messageelt.update(str); + }, + + availableMessage: function(available) { + var message = available ? SyjStrings.availablePseudo: SyjStrings.unavailablePseudo, + status = available ? "success": "warn"; + this.message(message, status, false); + }, + + reset: function() { + if (this.req) { + this.req.abort(); + this.req = this.currentvalue = null; + } + if (this.messageelt) { + this.messageelt.up().setStyle({visibility: 'hidden'}); + } + }, + + check: function() { + var pseudo = $("user_pseudo").value; + + this.reset(); + + if (!pseudo || !(pseudo.match(/^[a-zA-Z0-9_.]+$/))) { + return; + } + + if (typeof this.exists[pseudo] === "boolean") { + this.reset(); + this.availableMessage(!this.exists[pseudo]); + return; + } + + this.message(SyjStrings.pseudoChecking, "", true); + + this.currentvalue = pseudo; + this.req = new Ajax.TimedRequest('userexists/' + encodeURIComponent(pseudo), 20, { + onFailure: this.failure.bind(this), + onSuccess: this.success.bind(this) + }); + }, + + failure: function(transport) { + var httpCode = 0, value = this.currentvalue; + + if (transport) { + httpCode = transport.getStatus(); + } + this.reset(); + if (httpCode === 404) { + this.exists[value] = false; + this.availableMessage(true); + } + + }, + + success: function(transport) { + var httpCode = transport.getStatus(), value = this.currentvalue; + this.reset(); + this.exists[value] = true; + this.availableMessage(false); + } +}; + + document.observe("dom:loaded", function() { SYJLogin.init(); SYJUser.init(); SYJView.init(); SYJNewpwd.init(); - loginMgr.updateUI(); + LoginMgr.updateUI(); }); diff --git a/public/js/utils.js b/public/js/utils.js index b1dd910..f5817d4 100644 --- a/public/js/utils.js +++ b/public/js/utils.js @@ -85,8 +85,12 @@ Ajax.TimedRequest = Class.create(Ajax.Request, { initialize: function($super, url, delay, options) { this.delay = delay; + if (!options) { + options = {}; + } - options.onSuccess = options.onSuccess.wrap(function(proceed, transport, json) { + options.onSuccess = options.onSuccess && + options.onSuccess.wrap(function(proceed, transport, json) { if (this.timeout) { window.clearTimeout(this.timeout); this.timeout = null; @@ -98,7 +102,8 @@ Ajax.TimedRequest = Class.create(Ajax.Request, { } }).bind(this); - options.onFailure = options.onFailure.wrap(function(proceed, transport, json) { + options.onFailure = options.onFailure && + options.onFailure.wrap(function(proceed, transport, json) { if (this.timeout) { window.clearTimeout(this.timeout); this.timeout = null; @@ -111,7 +116,9 @@ Ajax.TimedRequest = Class.create(Ajax.Request, { request: function($super, url) { this.timeout = (function() { - this.options.onFailure(null); + if (this.options.onFailure) { + this.options.onFailure(null); + } this.abort(); }).bind(this).delay(this.delay); $super(url); @@ -223,6 +230,52 @@ Element.addMethods(['input', 'textarea'], { after: new Element("div", {className: 'error'}).update(errorMessage) }); return false; + }, + + observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) { + if (eventName === "contentchange") { + proceed(element, 'keyup', function(evt) { + if (evt.keyCode === 13) { + return; + } + handler.apply(null, arguments); + }); + proceed(element, 'paste', handler); + return proceed(element, 'change', handler); + } + return proceed(element, eventName, handler); + }), + + timedobserve: function(element, callback, delay) { + var timeout = null, initialvalue = element.value; + + if (typeof delay !== "number") { + delay = 0.5; + } + delay = delay * 1000; + + var canceltimer = function() { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + }; + var resettimer = function() { + canceltimer(); + timeout = setTimeout(triggercallback, delay); + }; + var triggercallback = function() { + canceltimer(); + if (initialvalue !== element.value) { + initialvalue = element.value; + callback.call(element); + } + }; + + element.observe('blur', triggercallback). + observe('keyup', resettimer). + observe('paste', resettimer); + return element; } }); -- 2.39.2