J'ai besoin d'un champ de saisie pour régler la durée.

L'utilisateur aura la possibilité de régler cette durée en minutes, hours ou days

Par exemple, je voudrais donner la possibilité d'avoir des entrées comme:

1m
8.5 h
3d

Etc

Je convertirai la valeur en minutes avant d'envoyer la valeur au backend.

Connaissez-vous des plugins d'entrées pour cela?

2
Safari 7 avril 2020 à 11:53

4 réponses

Meilleure réponse

En utilisant moment.js, vous pouvez autoriser les entrées comme suit:

const threeMinuts = '3m';       // 3 minutes
const eightHours  = '8.5 h';    // 8.5 hours
const threeDays   = '3 days';      // 3 days

Vous devez ensuite séparer la valeur numérique de l'unité de mesure:

const numberValue = Number(input.match(/(\d|\.|,)+/)[0]);
const unit = input.match(/[a-z]+/)[0];

Après quoi vous pouvez passer la durée au moment comme suit:

const duration = moment.duration(numberValue, unit);

Par exemple.:

const duration = moment.duration(8.5, 'h');
1
Titulum 7 avril 2020 à 09:22

Tout d'abord, vous créez une entrée

<input id="time" type="time">

Enfin, vous ajoutez de la valeur à l'entrée à l'aide de javascript

document.getElementById("time").value = new Date().toTimeString().slice(0,8);
-1
D z 7 avril 2020 à 10:00

Comme je préfère le JS pur et pas de libs (avec une surcharge importante) ici un JS simple pour cette tâche s'adapte (en particulier le regex par exemple pour les heures (/ ([0-9] 0-9?) []? H /) pour les chiffres ) comme vous voulez:

function toSeconds(dd,hh,mm) {
 var d = parseInt(dd);
  var h = parseInt(hh);
  var m = parseInt(mm);
  if (isNaN(d)) d = 0;
  if (isNaN(h)) h = 0;
  if (isNaN(m)) m = 0;

 var t = d * 24 * 60 * 60 +
      h * 60 * 60 +
      m * 60;
  return t;
}

/* Expects 1d 11h 11m, or 1d 11h, or 11h 11m, 
or 11h, or 11m, or 1d returns number of seconds */
function parseInput(sInput) {
  if (sInput== null || sInput=== '') return 0;
  var mrx = new RegExp(/([0-9][0-9]?)[ ]?m/);
  var hrx = new RegExp(/([0-9][0-9]?)[ ]?h/);
  var drx = new RegExp(/([0-9])[ ]?d/);
  var days = 0;
  var hours = 0;
  var minutes = 0;
  if (mrx.test(sInput)) {
    minutes = mrx.exec(sInput)[1];
  }
  if (hrx.test(sInput)) {
    hours = hrx.exec(sInput)[1];
  }
  if (drx.test(sInput)) {
    days = drx.exec(sInput)[1];
  }

  return toSeconds(days, hours, minutes);
}
0
Codebreaker007 7 avril 2020 à 10:13
  1. Attribuez chacun <input> type="number" et min="0".

  2. Puis max="23" pendant des heures et max="59" pendant des minutes.

  3. Ajoutez une entrée masquée avec un attribut name.

  4. Si vous ne l'avez pas déjà fait, enveloppez tout dans un <form> et enregistrez-le à l'événement "input".

  5. Créez un gestionnaire d'événements pour extraire et calculer les valeurs de toutes les entrées, puis attribuez le total à l'entrée masquée.

  6. Lorsque le <form> est soumis, la valeur d'entrée masquée sera envoyée car elle possède un attribut name.

BTW ce n'est pas vraiment bon UX d'avoir un type d'utilisateur dans autant de valeurs dans une entrée. Vous devez fournir à l'utilisateur des champs clairement définis qui obligent l'utilisateur à saisir des données sans complications supplémentaires.


Démo

document.forms.duration.oninput = toMinutes;

function toMinutes(e) {
  const dur = this.elements;
  let time;
  if (e.target.tagName === 'INPUT') {
    let d = Number(dur.days.value) * 1440;
    let h = Number(dur.hours.value) * 60;
    let m = Number(dur.minutes.value);
    time = d + h + m;
    dur.time.value = time;
  }
  console.log(dur.time.value);
}
:root,
body {
  font: 400 3vw/1.45 Consolas
}

fieldset {
  width: max-content;
}

label,
input {
  width: 6.5ch;
  display: inline-block;
  margin: 4px;
}

input {
  height: 3vw;
  line-height: 1;
  font: inherit;
  text-align: right
}

.as-console-wrapper {
  width: 40%;
  min-height: 100%;
  margin-left: 60%;
}
  
<form id='duration'>
  <fieldset>
    <legend>Duration</legend>
    <label for='days'>Days: </label>
    <input id='days' type='number' min='0' value='0'><br>
    <label for='hours'>Hours: </label>
    <input id='hours' type='number' min='0' max='23' value='0'><br>
    <label for='minutes'>Minutes: </label>
    <input id='minutes' type='number' min='0' max='59' value='0'><br>
  </fieldset>
  <input id='time' name='time' type='hidden'>
</form>
0
zer00ne 7 avril 2020 à 10:03