Ajouter une action quand on quitte une zone de saisie

Bonjour,

Pour un prêt, nous avons une date de début et une date de fin ainsi qu’une durée.
Nous souhaitons faire en sorte que lorsqu’un utilisateur saisie la date de début et la durée, qu’on lui affiche directement la date de fin (zone calculée et non saisissable).
Pour le confort de l’utilisateur, nous aimerions que cette date de fin s’affiche quand on quitte la zone « Durée » et avant de cliquer sur « Enregistrer ».
Pourriez-vous nous dire si c’est faisable ? et si oui, comment ?

Nous ajouterons un contrôle pour s’assurer que tout est Ok.

Merci d’avance pour votre aide
Abed.

Pour tout comportement dynamique coté client sur le formulaire il faut utiliser les hooks client qui permettent de tout manipuler de manière événementielle, cf. https://www.simplicite.io/resources/documentation/04-ui/responsive.md

Merci pour le lien.
Malheureusement, je n’ai pas tout compris dans la doc.
Je pense que le code à utiliser est :
// Bind change on a field to change one other field
var field = ui.getUIField(ctn, obj, “myField”);
field.ui.on(“change”, function() {
var v = field.ui.val(),
f = ui.getUIField(ctn, obj, “myOtherField”);
// Change properties
f.ui.visible(v ? Simplicite.VIS_HIDDEN: Simplicite.VIS_BOTH);
f.ui.updatable(f.required && v==“123”);
Est-ce que c’est dans Editor code qu’il faut le mettre ? Si oui, dans quelle fonction (preLoad, postValidate,….)
Dans l’exemple on donne les cas : f.ui.visible et f.ui.updatable, quelle fonction utiliser pour affecter une valeur (Date de début + durée) à un champ (Date de fin)? Il y a-t-il une doc là-dessus ?
Que devrais-je mettre dans les variables ctn, obj ?
Merci d’avance.
Abed.

Les hooks clients sont du code Javascript client donc ça s’écrit dans une resource JS d’objet, par défaut dans celle nommée SCRIPT, pas dans le script Rhino serveur de l’objet (pour mémoire Rhino est une script engine Java qui utilise la syntaxe du Javascript mais ça n’a rien à voir avec le Javascript client qui s’execute dans le navigateur)

Cf l’objet DemoClient de la démo qui a à la fois du code serveur et du code client dans sa resource SCRIPT

NB: dans votre cas, contrairement à la démo, pas la peine de gérer du code à la fois pour la UI responsive et l’ancienne UI legacy, votre code peut se limiter au cas de la UI responsive, genre:

MyObject = (function(ui) {
    if (!ui) return; // Do nothing on legacy UI
    var app = ui.getAjax();
    Simplicite.UI.hooks.MyObject = function(o, cbk) {
        try {
             o.locals.ui.form.onload = function(ctn, obj) {
                 // Your UI hooks, e.g.
                 var myField1 = ui.getUIField(ctn, obj, "myField1");
                 myField1.ui.on("change", function() {
                     console.log(myField1.ui.val());
                 });
                 // Etc.
             };
        } catch (e) {
            app.error("Error in Simplicite.UI.hooks.MyObject: " + e.message);
        } finally {
            cbk && cbk();
        }
    };
})(window.$ui);

Sur le fond je laisse @Francois vous donner un exemple adapté à votre cas particulier

On peut effectivement ajouter du script client et sur le chargement du formulaire, récupérer le champ date, et lui ajouter un handler sur change pour faire un calcul et valoriser un autre champ.

Pour prolonger l’exemple de David, dans le onload, on aurait qq chose comme :

...
o.locals.ui.form.onload = function(ctn, obj) {
  var myDuration = ui.getUIField(ctn, obj, "myDuration");
  myDuration.ui.change(function() {
    var d = myDuration.ui.val(); // getter
    d = parseInt(d || "0"); // integer days
    var date1 = ui.getUIField(ctn, obj, "myDate1").ui.val(); // from date YYYY-MM-DD
    if (date1 && date1.length==10) { // not empty
      var y = parseInt(date1.substring(0,4)),
          m = parseInt(date1.substring(5,7)),
          d = parseInt(v.substring(8,10)),
          dt = new Date(y,m-1,d);
      var d2 = new Date(dt.getTime() + d*3600*24*1000); // date + duration in millisec
      y = d2.getFullYear();
      m = d2.getMonth()+1;
      d = d2.getDate();
      var ymd = "" + y + "-" + (m<10?"0":"")+m + "-" + (d<10?"0":"")+d;
      ui.getUIField(ctn, obj, "myDate2").ui.val(ymd); // to date YYYY-MM-DD
    }
  });
};

@Francois en UI legacy, dans le vieux common.js il y a avait plein de fonctions JS “bas niveau” pour manipuler les dates natives JS vs le format technique "YYYY-MM-DD" et il y avait aussi des enrichissements de la date native JS pour ajouter des secondes/minutes/heures/jours/mois:

Date.prototype.addMilliseconds = function(m) { this.setTime(this.getTime() + m); return this; }
Date.prototype.addSeconds = function(s) { return this.addMilliseconds(s*1000); }
Date.prototype.addMinutes = function(m) { return this.addMilliseconds(m*60000); }
Date.prototype.addHours = function(h) { return this.addMilliseconds(h*3600000); }
Date.prototype.addDays = function(d) { return this.addMilliseconds(d*24*3600000); }
Date.prototype.addWeeks = function(w) { return this.addMilliseconds(w*7*24*3600000); }

Peut être faudrait il reprendre qques unes de ces fonctions dans les tools de la UI responsive…