// CrbPcaDossier front side hook
(function(ui) {
if (!ui) return;
var app = ui.getAjax();
// Hook called by each object instance
Simplicite.UI.hooks.CrbPcaDossier = function(o, cbk) {
try {
console.log("CrbPcaDossier hooks loading...");
var p = o.locals.ui;
if (p && o.isMainInstance()) {
p.form.onload = function(ctn, obj, params) {
var qpe = ui.getUIField(ctn, obj, "pcaDossierInstPartExt");
var qpr = ui.getUIField(ctn, obj, "pcaDossierInstPartRegion");
qpe.ui.on("change", function() {
console.log("Valeur part ext : " +qpe.ui.val());
var valQpe=parseFloat(qpe.ui.val());
if (!isNaN(valQpe))
qpr.ui.val(100-valQpe);
});
};
}
} catch (e) {
app.error("Error in Simplicite.UI.hooks.CrbPcaDossier: " + e.message);
} finally {
console.log("CrbPcaDossier hooks loaded.");
cbk && cbk(); // final callback
}
};
})(window.$ui);
J’ai peut-être raté quelque chose mais ça ne fonctionne pas, j’obtiens la valeur précédente de mon champ qpe au lieu de celle qui vient d’être changée.
J’ai affiché qpe.ui.val() dans la console pour confirmer qu’il y avait bien décalage et pas juste un problème d’affichage, ici après avoir changé 50 en 30 :
J’ai testé avec $(this) au lieu de la référence qpe définie hors de la fonction on change, et ça marche, j’ai bien la valeur actuelle. Maintenant que j’y pense c’est peut-être une mauvaise idée d’utiliser une référence qui vient d’en dehors de la fonction, même si dans l’exemple de l’autre sujet ça avait l’air de marcher avec “field”.
J’ai fait un affichage console des deux valeurs pour vérifier :
p.form.onload = function(ctn, obj, params) {
var qpe = ui.getUIField(ctn, obj, "pcaDossierInstPartExt");
qpe.ui.on("change", function() {
var qpr = ui.getUIField(ctn, obj, "pcaDossierInstPartRegion");
console.log("Valeur obtenue par ref : " + qpe.ui.val());
console.log("Valeur obtenue par this : " +$(this).val());
let valQpe=parseFloat($(this).val());
if (!isNaN(valQpe))
qpr.ui.val(100-valQpe);
});
};
Etrange, le formulaire a peut être redessiné la champ entre temps, car la référence de l’input a changé.
Il convient d’utiliser le getter getUIField au moment de lire/ecrire la valeur, il contient les selectors qui vont chercher l’input (ou autre) associé au champ dans le container de l’objet. Si on le fait trop top : le champ n’est pas forcement encore présent, mais je n’ai jamais vu de cas où il pointe sur un “vieil” input non affiché.
Avez vous plusieurs fois ce champs dans l’objet ou le formulaire ?
Je vais regarder avec votre exemple cette histoire de scope.
Votre code dans la démo donne bien la bonne valeur en testant un changement de code fournisseur :
Il y a quelque chose qui recharge votre input entre le moment où le formulaire est dessiné une première fois, et le change : doublon, contraintes, responsive… ?
Dans votre cas pour avoir la bonne référence, il faut la recharger, car utiliser “this” c’est parfois ambigu ou incompatible avec des fonctions lambda, ex :
p.form.onload = function(ctn, obj, params) {
let f = "pcaDossierInstPartExt";
ui.getUIField(ctn, obj, f).ui.on("change", () => {
let v = ui.getUIField(ctn, obj, f).val();
...
});
};
Pas de doublon à ma connaissance dans le formulaire, des contraintes sur l’objet mais aucune censée impacter ce champ.
La seule chose que je vois l’impactant directement c’est un traitement dans le hook initUpdate de l’objet métier, qui détermine si le champ est visible et modifiable.
Il n’y a rien d’autre dans le script front de l’objet non plus, juste ce que j’ai mis dans la première capture.
Je viens de tester en chargeant le champ depuis la fonction elle-même et j’ai le même problème avec la nouvelle référence qu’avec la première, la valeur retournée est l’ancienne :
if (p && o.isMainInstance()) {
p.form.onload = function(ctn, obj, params) {
let qpe = ui.getUIField(ctn, obj, "pcaDossierInstPartExt");
qpe.ui.on("change", function() {
let pe = ui.getUIField(ctn, obj, "pcaDossierInstPartExt");
let pr = ui.getUIField(ctn, obj, "pcaDossierInstPartRegion");
let testVal = pe.ui.val();
debugger
let valQpe=parseFloat(pe.ui.val());
if (!isNaN(valQpe))
pr.ui.val(100-valQpe);
});
};
}
au debuggez regarder sur quoi pointe pe.ui.input, et recherchez tous les pcaDossierInstPartExt dans la page et dans la définition de l’objet. Vous devez avoir un champ caché qui contient l’ancienne valeur dans le formulaire.
$(this) est bien l’élément du change, donc ça reste une bonne solution, mais ce serait bien de trouver pourquoi vous avez 2 inputs au lieu d’un.
Quel est le code de l’initUpdate au niveau de ce champ ?
setZoneUpdateFields change la propriété modifiable du champ au besoin :
public static void setZoneUpdatableFields(FieldArea zone,boolean droit) {
//AppLog.simpleDebug("Updatable :"+zone.getName()+" "+droit);
for (int i=0; i<zone.getFields().size(); i++){
ObjectField car = zone.getFields().get(i);
// si champs commentaire et en lecture seule ne sont jamais required
if (car.getUpdatableDefault()!=ObjectField.UPD_READ_ONLY&&Tool.isEmpty(car.getRefFieldName())) car.setUpdatable(droit);
}
}
Je pensais qu’il y en avait une autre pour la visibilité, mais pas directement parce que c’est la zone complète qui est rendue visible ou pas dans le initUpdate.
Il y a aussi un changement de propriété obligatoire ou non dans le preValidate, un peu sur le même principe.
Pas d’autre référence au champ dans le code a priori.
Alors aucune idée si c’est bien un même et unique champ. De mon point de vue, tous ces codes sont équivalents pour un input simple :
pe.ui.val()
// qui devient pour un texte simple
pe.ui.input.val()
// sinon du natif
pe.ui.input[0].value
this.value
$(this).val()
Regardez ce qu’ils vous donnent.
Le 1er verbe de Simplicité ui.val() est préférable dans un cas général car ne dépend pas du type/rendering du champ (input, radio, check, select, file, image, éditeur html… qui n’ont pas forcement un input).
qpe.ui.on("change", function() {
let pe = ui.getUIField(ctn, obj, "pcaDossierInstPartExt");
let t1 = pe.ui.val();
let t2 = $(pe.ui.input).val();
let t3 = pe.ui.input.value;
let t4 = this.value;
let t5 = $(this).val();
debugger
Donc $(pe.ui.input).val() , this.value et $(this).val() renvoient la valeur attendue.
Mais pe.ui.val() renvoie la valeur précédente, et pe.ui.input.value est indéfini…
D’après ton debugger le champ est un big decimal, et la valeur utilisée est bigdec = “15.00” qui permet de stocker la valeur sans perte de précision sous forme de String (sinon en javascript on ne peut pas stocker plus que des float = double precision).
Dans le cas d’un change cette variable n’est pas bien actualisée et du coup ça explique l’effet retard de cette variable en front. On va voir pour améliorer ça pour que la valeur bigdec s’actualise correctement à chaque “keyup” ou “input”.
Par contre pourquoi utiliser un bigdecimal pour un champ %, un simple décimal 6,2 devrait convenir à votre besoin.
Et sinon pe.ui.input est déjà un objet jQuery donc un tableau, donc en fait c’est pe.ui.input[0].value pour accéder à la valeur native de l’input.
OK, effectivement on n’a pas d’intérêt à utiliser ce type, je l’ai modifié.
En fait après vérification dans notre cas on n’a probablement même pas besoin de décimale du tout, donc même entier suffira. Et je confirme, ui.val() est bien actualisé maintenant.