J'ai un étrange problème avec la validation que j'écris sur un formulaire. Il s'agit d'un bouton "Vérifier le nom d'utilisateur" à côté d'une entrée. La valeur par défaut entrée est le nom d'utilisateur par exemple 'betamax'. Lorsque j'appuie sur "Vérifier le nom d'utilisateur", il passe l'expression régulière et envoie le nom d'utilisateur au serveur. Le serveur se comporte comme prévu et renvoie "2" pour indiquer au javascript qu'il soumet son propre nom d'utilisateur.
Ensuite, lorsque je clique à nouveau sur le bouton, l'expression régulière échoue. Rien n'est envoyé au serveur évidemment parce que l'expression régulière a échoué. Si j'appuie à nouveau sur le bouton, l'expression régulière passe et le nom d'utilisateur est envoyé au serveur.
Je ne peux littéralement pas comprendre ce qui le ferait faire ça! Ça n'a aucun sens!
Edit: j'ai testé le problème dans Firefox et Chrome (mac)
Voici mon code:
$j("#username-search").click(checkUserName);
function checkUserName() {
var userName = $j("#username").val();
var invalidUserMsg = 'Invalid username (a-zA-Z0-9 _ - and not - or _ at beginning or end of string)';
var filter = /^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;
if (filter.test(userName)) {
console.log("Pass")
$j.post(
"/account/profile/username_check/",
{ q: userName },
function(data){
if(data == 0) {
$j("#username-search-results").html("Error searching for username. Try again?");
}
else if(data == 5) {
$j("#username-search-results").html(invalidUserMsg);
}
else if(data == 4) {
$j("#username-search-results").html("Username too short or too long.");
}
else if(data == 2) {
$j("#username-search-results").html("This is already your username.");
}
else if(data == 3) {
$j("#username-search-results").html("This username is taken.");
}
else if(data == 1){
$j("#username-search-results").html("This username is available!");
}
});
} else {
console.log("fail")
$j("#username-search-results").html(invalidUserMsg);
}
return false;
}
Le HTML:
<input name="username" id="username" value="{{ user.username }}" />
<input type="button" value="Is it taken?" id="username-search">
<span id="username-search-results"></span>
/^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;
Vous utilisez un g
(global) RegExp
. En JavaScript, les expressions rationnelles globales ont un état: vous les appelez (avec exec
, test
etc.) la première fois, vous obtenez la première correspondance dans une chaîne donnée. Appelez-les à nouveau et vous obtenez la correspondance suivante, et ainsi de suite jusqu'à ce que vous n'obteniez aucune correspondance et qu'elle se réinitialise au début de la chaîne suivante. Vous pouvez également écrire regex.lastIndex= 0
pour réinitialiser cet état.
(Il s'agit bien sûr d'un élément de conception absolument terrible, garanti de confondre et de provoquer des erreurs étranges. Bienvenue dans JavaScript!)
Vous pouvez omettre le g
de votre RegExp
, car vous ne testez qu'une seule correspondance.
De plus, je ne pense pas que vous vouliez [^-_]
à l'avant et à l'arrière. Cela permettra tout caractère à chaque extrémité, c'est-à-dire. *plop!
serait valide. Vous pensez probablement à des assertions lookahead/lookbehind, mais elles ne sont pas disponibles en JavaScript. (Eh bien, l'anticipation est censée l'être, mais elle est cassée dans IE.) Suggérez plutôt:
/^[a-z0-9][a-z0-9_-]{2,18}[a-z0-9]$/i
[a-z0-9-_]
C'est faux, le dernier -
doit être au début ou à la fin.
[a-z0-9_-]
Je ne sais pas si cela causerait ce problème ou non.
Notes complémentaires:
Le premier et le dernier caractère peuvent être n'importe quel caractère qui n'est pas -
ou _
plutôt que d'être limité à a-z0-9
a-z0-9
ne contient pas de majuscules. Vous avez besoin a-zA-Z0-9
pour ça. a-zA-Z0-9_
peut être raccourci en \w
dans la plupart des moteurs RegEx. Je ne l'ai pas essayé en JavaScript.