J'ai un objet de PHP, dont les propriétés sont initialisés de la façon suivante:comportement Erratic lorsque l'on compare PHP implosé tableaux avec des valeurs de champ de formulaire en utilisant JavaScript
$this->contact = implode(PHP_EOL,$description->getContact()) . PHP_EOL;
Les seules exceptions sont deux propriétés nommées la version et bugs.
Cet objet est ensuite codé dans un objet JSON et transmis au javascript suivant, qui compare l'objet JSON avec la valeur d'un formulaire.
function compareEntry(data){
var dataProperties = ["version", "bugs", "scenario", "exception", "instruction", "sources", "risks", "test", "contact"];
var hasChanged = false;
for(var i = 0; i < dataProperties.length; i++){
var dataProperty = dataProperties[i];
alert("Original: '" + data[dataProperty] + "'\nModified: '" + document.myform[dataProperty].value + "'\nTest Value: " + (!data[dataProperty].localeCompare(document.myform[dataProperty].value)));
if(!data[dataProperty].localeCompare(document.myform[dataProperty].value)){
hasChanged = true;
}
}
[...]
Dans l'exception de la version et bogues, toutes les autres propriétés sont comparées à la valeur dans la zone de texte.
Les champs de formulaire sont initialisés avec la valeur de l'objet PHP. Lorsque je soumets le formulaire, la fonction est appelée. Si je soumets le formulaire sans changer aucune valeur, il me donne quand même un false
en comparant une propriété avec la valeur d'une zone de texte. Pourquoi et comment pourrais-je les comparer correctement?
Remarques: L'objet PHP est le reflet d'une entrée MySQL créée avec le même formulaire. Entre les deux, l'information a été chiffrée et déchiffrée. Mais il ne devrait pas jouer de rôle, car l'objet PHP/JSon et la valeur initiale du formulaire proviennent de la même source.
EDIT
Après l'explication de Frode, j'ai changé ma déclaration de test à:
data[dataProperty].localeCompare(document.myform[dataProperty].value)!=0
Mais après, je note deux discordances.
- Propriétés Version et bogues qui jusque-là sont retournés
true
lorsque le retour testé maintenantfalse
. Mais contrairement aux autres propriétés, je ne manipule pas les valeurs lorsque je les récupère de la base de données. La valeur de la version de la propriété est stockée dans une baliseselect
dans le formulaire. - Et plus étrange, quand je change l'une des valeurs dans la zone de texte, au lieu de me donner
false
, il me donnetrue
.
Il m'est apparu que cela peut être dû à l'implémentation de javascript du navigateur que j'utilise. Mais le résultat que j'ai obtenu n'est pas tout à fait comme je l'espérais. Considérant que, j'ai le comportement décrit dans Firefox et Chrome, IE et Opera jeter toujours false
(à l'exception notable de la comparaison version, qui m'a donné vrai dans IE, bien qu'il ne pouvait pas récupérer la valeur de la select
tag). Dois-je utiliser une autre méthode pour comparer mes chaînes de caractères?
EDIT 2
Après avoir pris la suggestion de Wolph, j'ai changé la condition de test:
données [dataProperty] .trim() document.myform [dataProperty] .trim()
Où trim() est la fonction décrite dans this other question. Et le résultat est l'inverse de ce que j'avais dans le premier EDIT. Sauf pour Chrome qui semble attribuer son booléen au hasard. Il semble y avoir quelque chose qui ne va vraiment pas dans mes données.
Voici un exemple d'un objet JSON tel que je peux le voir dans Firefox (variable data dans l'extrait de code).
{"version":"REL-773","bugs":"20831","scenario":"THIS IS A TEST\r\n\r\nThis is the what happens: stuffs.\r\n","exception":"N\/A\r\n","instruction":"1. First Step.\r\n2. Second Step.\r\n2. Third Step\r\nIt is longer.\r\n4. Fourth Step.\r\n5. Fifth Step.\r\n6. Sixth Step.\r\n","sources":"me\r\n","risks":"High risks as it is just for testing of the web application.\r\n","test":"1. Select an entry\r\n2. Change some data such as <HOME>\/path\/\r\n3. See if the application run as expected!\r\n","contact":"[email protected]\r\n"}
EDIT 3
Utilisation de la fonction escape()
pour échapper à tous les caractères spéciaux des deux chaînes, je remarquai que dans le caractère %OA
est écrit comme %OD%OA
dans l'objet JSON. Il m'a fait soupçonner que ma fonction de coupe ne remplace pas correctement le \r\n
par \n
. (. Fonction de coupe que j'ai ajouté après la suggestion des affiches ici)
Voici la fonction que j'utilise:
if(typeof(String.prototype.trim) === "undefined")
{
String.prototype.trim = function()
{
return String(this).replace(/^\s+|\s+$/g, '').replace(/\r\n/g,"\n");
};
}
Avez-vous essayé d'effacer tous les espaces avant de comparer? – Wolph
@WoLpH, il semble que l'effacement des espaces blancs n'aide pas un peu. – Eldros
Ok ... deuxième estimation (toujours liée aux espaces), dans votre testdata je vois '\ r \ n' qui est le format de nouvelle ligne de Windows. Il se peut que ce soit simplement au format '\ n'. Essayez donc de supprimer tous les caractères '\ r' avant de comparer. – Wolph