Bonjour,
Je me heurte à un problème très certainement tout bête, mais je n'arrive pas à trouver de solution…
J'utilise un logiciel déjà existant. Je n'ai pas la main sur son code à proprement parler.
En revanche, je peux paramétrer, dans certains endroits, des bouts de code JavaScript à exécuter lors de certaines actions.
J'ai donc ici un élément de type menu déroulant (mais un truc custom, pas un simple <select>).
Dessus, je peux indiquer un "hook function", à savoir une fonction exécutée lorsqu'on change la valeur sélectionnée.
Voici l'appel :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part u8.Custom.Affaire.FieldRunValidator($, "StadeAvancementAffaire");
Ensuite, voici mon code :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 (function () { u8.Custom.Affaire = { CheckMustFields: function (e, save) { // Tout un tas de bordel }, FieldRunValidator: function (object, otherCheck) { this.CheckMustFields(object.widget, false); if (otherCheck === "StadeAvancementAffaire") { u8.Custom.Affaire.StadeAvancementAffaire(object); } }, StadeAvancementAffaire: function (e) { // Recherche de la valeur dans la base, ainsi que la présence de dossiers var uid = e.widget.model.getUid(); var nouveau_code = e.getValue("F7021"); u8.services.queries.execute({ statement: "select (F7021, OJ1.SeqNo, OJ1.F7180) from (OJ) where (ProjType='#1' and StatNo = '" + u8.Custom.Affaire.GetUidPart(uid, 0) + "'and SeqNo = '" + u8.Custom.Affaire.GetUidPart(uid, 1) + "') plus (OJ using link 2 as OJ1) where (ProjType='#2')", options: {}}, function (sender, args) { var ancien_code = args.resultSet.rows[0].values[0]; if (args.resultSet.rows[0].values[1] === "") { // Pas de dossier : aucun contrôle } else { // Il y a au moins un dossier var catalogField = u8.services.schema.getField("OJ", "F7021"); var nouveau_externalKey = u8.services.catalogs.codeToExternalKey(catalogField, nouveau_code); var ancien_externalKey = u8.services.catalogs.codeToExternalKey(catalogField, ancien_code); var nb_adju = 0; for (var i = 0; i < args.resultSet.rows.length; ++i) { nb_adju += args.resultSet.rows[i].values[2]; } switch (ancien_externalKey) { case "INTENTION": case "AVANTPROJET": case "APPELOFFRE": if (nouveau_externalKey === "ADJUDICATION" || nouveau_externalKey === "COMMANDE") { // cas 1 if (nb_adju !== 1) { alert("Changement non autorisé : un dossier doit être déclaré \"Adjudicataire\""); save = false; } } break; case "ADJUDICATION": case "COMMANDE": if (nouveau_externalKey === "INTENTION" || nouveau_externalKey === "AVANTPROJET" || nouveau_externalKey === "APPELOFFRE") { // cas 2 if (nb_adju !== 0) { alert("Changement non autorisé : un dossier est déclaré \"Adjudicataire\""); save = false; } } break; default: // Pas de valeur avant : aucun contrôle break; } } }); } } })();
Ce code, en l'état, fonctionne.
Selon le cas 1 ou cas 2, j'ai bien une popup affichant le message d'erreur.
Seulement, je souhaite aussi annuler la saisie.
Pour se faire, je dois faire un e.setValue("F7021", ancien_code)Et là je me tape le message d'erreur :
J'ai cherché un peu et j'ai compris qu'il fallait que j'utilise un deferred.Error: $.setValue() must not be called from an asynchronous callback.
Seulement je ne comprends absolument pas la syntaxe.
Voici ce que j'ai tenté :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 StadeAvancementAffaire: function (e) { var ancien_code = ""; // Recherche de la valeur dans la base, ainsi que la présence de dossiers var uid = e.widget.model.getUid(); var nouveau_code = e.getValue("F7021"); var deferred = jQuery.Deferred(); deferred.then(function(value) { alert("Save : " + value); if (value === false) { e.setValue("F7021", ancien_code); } }); u8.services.queries.execute({ statement: "select (F7021, OJ1.SeqNo, OJ1.F7180) from (OJ) where (ProjType='#1' and StatNo = '" + u8.Custom.Affaire.GetUidPart(uid, 0) + "'and SeqNo = '" + u8.Custom.Affaire.GetUidPart(uid, 1) + "') plus (OJ using link 2 as OJ1) where (ProjType='#2')", options: {}}, function (sender, args) { var save = true; ancien_code = args.resultSet.rows[0].values[0]; if (args.resultSet.rows[0].values[1] === "") { // Pas de dossier : aucun contrôle } else { // Il y a au moins un dossier var catalogField = u8.services.schema.getField("OJ", "F7021"); var nouveau_externalKey = u8.services.catalogs.codeToExternalKey(catalogField, nouveau_code); var ancien_externalKey = u8.services.catalogs.codeToExternalKey(catalogField, ancien_code); var nb_adju = 0; for (var i = 0; i < args.resultSet.rows.length; ++i) { nb_adju += args.resultSet.rows[i].values[2]; } switch (ancien_externalKey) { case "INTENTION": case "AVANTPROJET": case "APPELOFFRE": if (nouveau_externalKey === "ADJUDICATION" || nouveau_externalKey === "COMMANDE") { // cas 1 if (nb_adju !== 1) { alert("Changement non autorisé : un dossier doit être déclaré \"Adjudicataire\""); save = false; } } break; case "ADJUDICATION": case "COMMANDE": if (nouveau_externalKey === "INTENTION" || nouveau_externalKey === "AVANTPROJET" || nouveau_externalKey === "APPELOFFRE") { // cas 2 if (nb_adju !== 0) { alert("Changement non autorisé : un dossier est déclaré \"Adjudicataire\""); save = false; } } break; default: // Pas de valeur avant : aucun contrôle break; } } deferred.resolve(save); }); return deferred.promise(); }
Malheureusement, si le code entre bien dans le "then()" j'ai toujours le message d'erreur.
Pourtant, la fonction StadeAvancementAffaire() n'est pas elle-même une méthode callback asynchrone, car je peux faire ça :
Seul hic, mon "1", il je ne peux le récupérer que depuis la méthode asynchrone u8.services.queries.execute().
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 StadeAvancementAffaire: function (e) { e.setValue("F7021", 1); }
Mon besoin, ce serait donc :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 StadeAvancementAffaire: function (e) { var res = null; MaFonctionAynchroneQuiVaBien(); JAttendsLaFinDeMaFonctionAsynchroneQuiVaBien(); e.setValue("F7021", res); }
Un peu comme le Join() de C# pour attendre la fin d'un thread.
Partager