Время ввода Html, выберите время в пределах min и max — Jquery

#javascript #html #jquery

#javascript #HTML #jquery

Вопрос:

Как вы видите в коде, я хочу, чтобы пользователи могли выбирать время между открытием и закрытием (мин.макс), но оно не работает, это займет все введенное время, а иногда оно будет работать только в течение максимального времени. Я видел похожие вопросы, я не мог найти никаких решений.

часть кода —

    temple_name| temple_opentime | temple_closetime
   -----------------------------------------------
    temple1   |      9:30       |    18:30       |
    temple2   |      7:30       |    21:00       |
    temple3   |     10:00       |    18:00       |
    temple4   |      8:30       |    20:00       |



<select id="temple" class="form-control">
           <?php 
             require "config/database.php";
             
             $sql = "select * from entity_temple";
             $result = mysqli_query($link, $sql);
             while($row = mysqli_fetch_array($result))
            {
             echo '<option name="'.$row["temple_opentime"].'" data-value="'. $row["temple_closetime"].'" value="'. $row["temple_name"].'">'. $row["temple_name"].'</option>';
            }
            ?>
      </select>

<div class="form-group col-md-4">
          <label for="time" class="form-label">Time:</label>
          <input type="time" id="time" name="time" min="" max="" step="600" class="form-control">
        </div>

<div class="form-group d-grid col-4 mx-auto">
  <button type="submit" name="save" class="btn btn-block btn-outline-dark" id="butsave">Add Request</button>
    </div>

$("#temple").on("change", function () {
    
  var value = $('#temple').val();
  
  var nm = $('#temple option[value="'   value   '"]').attr('name');
    
  var dv = $('#temple [value="'   value   '"]').data('value');
     
   $("#time").attr({
   "max" : dv,
   "min" : nm
});
 

Комментарии:

1. Добро пожаловать в Stack Overflow. Из моего примера неясно, что вы пробовали. Я вижу, что он собирает Min и Max, тогда что вы хотели, чтобы он делал?

2. да, он даже правильно устанавливает min и max, но он не будет работать по назначению, также потребуется время, введенное за пределами min и max

3. Вы проверили поддержку браузером ввода type=»time» ?

4. да, теперь это работает, кто-то только что ответил на него (и удалил ответ), просто нужно было добавить 0 перед 9:30 , 7:30 , 8:30 как 09:30, 07:30, 08:30,

Ответ №1:

Я бы использовал атрибуты данных для времени открытия и закрытия… И с осмысленными именами. 😉

Ваш SQL должен быть:

 while($row = mysqli_fetch_array($result)){
  echo '<option value="'.$row["temple_name"].'" data-opentime="'. $row["temple_opentime"].'" data-closetime="'. $row["temple_closetime"].'">'. $row["temple_name"].'</option>';
}
 

Я заметил, что время НЕ отображается во входных данных, если значение не имеет начального нуля… Так 7:30 что не работает, но 07:30 работает.


Теперь об атрибутах min и max для ввода времени …
Пока нет проверки, сделанной из коробки браузером

Вы можете заметить, что даже пример MDN ведет себя не так, как должен.

Итак, я добавил что-то вроде базового средства проверки. Это, по крайней мере, предотвращает отправку формы и добавляет класс к элементу time, если выбранное значение неверно.

 $("#temple").on("change", function() {

  var value = $('#temple').val();

  var min = $('#temple option[value="'   value   '"]').data('opentime');

  var max = $('#temple [value="'   value   '"]').data('closetime');

  console.log(value, min, max)

  $("#time").attr({
    value: min,
    max,
    min
  });
});

$("#timeForm").on("submit", function(e){
  e.preventDefault();
  
  let time = $("#time");
  if( time.val() < time.attr("min") || time.val() > time.attr("max") ){
    time.addClass("error");
    return;
  }
  
  // if the time is correct, submit
  $(this).submit();
});

$("#timeForm").on("change",function(){
  $("#time").removeClass("error");
}); 
 .error{
  background: red;
} 
 <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>

<form id="timeForm">
  <select id="temple" class="form-control">
    <option disabled selected>Select a temple</option>
    <option value="temple1" data-opentime="09:30" data-closetime="18H30">temple1</option>
    <option value="temple2" data-opentime="07:30" data-closetime="21:00">temple2</option>
    <option value="temple3" data-opentime="10:00" data-closetime="18:00">temple3</option>
    <option value="temple4" data-opentime="08:30" data-closetime="20:00">temple4</option>
  </select>

  <div class="form-group col-md-4">
    <label for="time" class="form-label">Time:</label>
    <input type="time" id="time" name="time" min="" max="" step="600" class="form-control" required>
  </div>

  <div class="form-group d-grid col-4 mx-auto">
    <button type="submit" name="save" class="btn btn-block btn-outline-dark" id="butsave">Add Request</button>
  </div>
</form> 

Ответ №2:

Рассмотрим следующее.

 $(function() {
  $("#temple").on("change", function() {
    var item = $(":selected", this),
      op = item.data("open-time"),
      cl = item.data("close-time");
    $("#time").attr({
      min: op,
      max: cl,
      value: op
    }).trigger("input");
  });
  $("#time").on("change", function(e) {
    if ($(this).val() < $(this).attr("min")) {
      $(this).val($(this).attr("min"));
    } else if ($(this).val() > $(this).attr("max")) {
      $(this).val($(this).attr("min"));
    }
  });
}); 
 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3 Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--
   temple_name| temple_opentime | temple_closetime
   -----------------------------------------------
    temple1   |      9:30       |    18:30       |
    temple2   |      7:30       |    21:00       |
    temple3   |     10:00       |    18:00       |
    temple4   |      8:30       |    20:00       |
-->
<select id="temple" class="form-control">
  <option>---</option>
  <option data-open-time="09:30" data-close-time="18:30" value="Temple1">Temple1</option>
  <option data-open-time="07:30" data-close-time="21:00" value="Temple2">Temple2</option>
  <option data-open-time="10:00" ddata-close-time="18:00" value="Temple3">Temple3</option>
  <option data-open-time="08:30" data-close-time="20:00" value="Temple1">Temple4</option>
</select>

<div class="form-group col-md-4">
  <label for="time" class="form-label">Time:</label>
  <input type="time" id="time" name="time" min="" max="" step="600" class="form-control" required>
</div>

<div class="form-group d-grid col-4 mx-auto">
  <button type="submit" name="save" class="btn btn-block btn-outline-dark" id="butsave">Add Request</button>
</div> 

Здесь, когда выбран параметр, обновляются Минимальные, Максимальные и значения введенного времени. после обновления мы запускаем событие ввода, это приведет к тому, что Значение появится у пользователя. Во входных данных могут быть значения, которые находятся за пределами значений Min и Max, это приведет к тому, что входные данные будут недопустимыми. Если пользователь затем отрегулирует время, оно будет вынуждено соответствовать Минимальному максимуму с помощью jQuery.

Смотрите больше: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time#Time_value_format

Примечание: Когда данные, введенные пользователем, не соответствуют пошаговой конфигурации, агент пользователя может округлить до ближайшего допустимого значения, предпочитая числа в положительном направлении, когда есть два одинаково близких варианта.

Это свойство имеет некоторые странные эффекты в разных браузерах, поэтому не является полностью надежным.

Ответ №3:

Как указывалось выше, проблема с операционным кодом была просто опечаткой:

Входные min данные и max значения атрибутов должны быть строками в форме «hh: mm» («h: mm» недопустимо).:

 <input type="time" min="08:30" max="16:00">
 

Однако это исправление опечатки само по себе не устраняет несовместимость с браузером. Как утверждает MDN:

… в Safari и любых других браузерах, которые не поддерживают <time> , он [ <input type="time"> ] изящно деградирует до <input type="text"> .

и degraded input не будет проверяться на наличие ошибок min / max.

Чтобы устранить эту несовместимость с браузером, приведенный ниже код обнаруживает входные данные, которые были преобразованы в форму <input type="text" min="hh:mm" max="hh:mm"> , и добавляет в форму скрипт проверки.

Если обнаружена ошибка проверки, сообщение об ошибке будет показано в виде наложения над входными данными (соответствует собственному поведению в Chrome и Firefox).

 // the "real" form submits
  const timeForm = document.getElementById('formtime');
  timeForm.onsubmit = function () {
    alert('time form was submitted');
  };
  const textForm = document.getElementById('formtext');
  textForm.onsubmit = function () {
    alert('text form was submitted');
  };

// time validator for degraded time inputs
// Note: This must be loaded AFTER all user form submitters have
// been added
(function () {

  // error overlay custom element
  class ErrorOverlay extends HTMLElement {
    constructor () {
      super();

      // create a shadow root
      let shadowRoot = this.attachShadow({mode: 'open'});

      // create shadow DOM element
      const overlay = document.createElement('div');
      this.overlay = overlay;
      overlay.className = 'error-overlay';

      // create css for the shadow DOM
      const style = document.createElement('style');
      style.textContent = `
          .error-overlay {
            font-family: Helvetica, sans-serif;
            position: absolute;
            z-index: 1000;
            border: 1px solid #808080;
            border-radius: 4px;
            color: #f8f8f8;
            background-color: #808080;
            padding: 0.2rem 0.4rem;
            display: none;
          }
          .error-overlay::after {
            content: " ";
            position: absolute;
            top: 100%;
            left: 24px;
            margin-left: -5px;
            border-width: 5px;
            border-style: solid;
            border-color: #808080 transparent transparent transparent;
          }
        `;

      // attach shadow DOM to shadow root
      shadowRoot.appendChild(style);
      shadowRoot.appendChild(overlay);
    }

    // show error overlay above the input
    show (input, message) {
      const {top, right, bottom, left} = input.getBoundingClientRect();
      const overlay = this.overlay;
      overlay.style.top = Math.round(top - 34   window.scrollY)   'px';
      overlay.style.left = Math.round(left)   'px';
      overlay.innerText = message;
      overlay.style.display = 'block';

      // hide overlay
      function overlayHide () {
        overlay.style.display = 'none';
        // remove listeners
        input.removeEventListener('keyup', overlayHide);
        input.removeEventListener('blur', overlayHide);
      }

      // add input listeners and focus the input
      input.addEventListener('keyup', overlayHide);
      input.addEventListener('blur', overlayHide);
      input.focus();
    }
  }

  // create overlay instance amp; add to body
  customElements.define('error-overlay', ErrorOverlay);
  const errorOverlay = document.createElement('error-overlay');
  document.body.appendChild(errorOverlay);

  // convert time string to decimal hours
  // time string patterns: "hh:mm AM", "hh:mm PM", "hh:mm"
  function timeStringToDecimalHours (timeStr) {
    let [hhmm, ampm] = timeStr.split(' ');
    ampm = (ampm || '').toLowerCase();
    let [hour, minute] = hhmm.split(':').map(el => Number(el));
    if (ampm === 'pm' amp;amp; hour < 12) {
      hour  = 12;
    } else if (ampm === 'am' amp;amp; hour === 12) {
      hour = 0;
    }
    return hour   (minute / 60);
  }

  // get array of inputs that have this pattern:
  // <input type="text" min="hh:mm" max="hh:mm">
  function getDegradedTimeInputs (form) {
    return Array.from(form.querySelectorAll('input'))
      .filter(input => {
        if (input.type !== 'text') { return false; }
        return input.hasAttribute('min') ||
          input.hasAttribute('max');
      });
  }

  // validate inputs when form is submitted
  function validateTimeOnFormSubmit (evt) {

    // get form's inputs that have type="text", `min` and/or `max`
    const form = evt.target;
    const tInputs = getDegradedTimeInputs(form);

    // validate that each input value is between min and max
    for (const input of tInputs) {
      const {value, max, min} = input;

      // convert time strings into decimal hours
      const valTime = timeStringToDecimalHours(value),
        minTime = timeStringToDecimalHours(min),
        maxTime = timeStringToDecimalHours(max);

      if (valTime < minTime || maxTime < valTime) {
        // show the error overlay and prevent the submit
        errorOverlay.show(input, `Time must be between ${min} and ${max}`);
        return false;
      }
    }
    // complete the submit
    return form.realOnSubmit(evt);
  }

  // add time validator to all forms that contain degraded time inputs
  const forms = document.querySelectorAll('form');

  function submitHandlerStub () { return true; }

  for (const form of forms) {
    if (getDegradedTimeInputs(form).length > 0) {
      // store the real submit handler as `form.realOnSubmit`
      const realOnSubmit = form.onsubmit || submitHandlerStub;
      Object.defineProperty(form, 'realOnSubmit', {
        value: realOnSubmit,
        enumerable: false
      });
      form.onsubmit = validateTimeOnFormSubmit;
    }
  }

})(); 
 form {
  border: 1px solid black;
  max-width: 30rem;
  margin: 1rem 0;
  padding: 0.5rem;
} 
 <h1>Validate a form's degraded time inputs</h1>

<p>Some browsers do not support <code>amp;<input type="time"></code>, degrading it to <code>amp;<input type="text"></code>.</p>

<p>This script detects these degraded inputs and validates them accordingly.</p>

<form id="formtime">
  <label for="timeinput">TIME input (min 09:30, max: 14:00):</label>
  <input id="timeinput" type="time" min="09:30" max="14:00" placeholder="hh:mm AM/PM" />
  <button type="submit">Submit</button>
</form>
<form id="formtext">
  <label for="degraded">TEXT input (min 09:30, max: 14:00):</label>
  <input id="degraded" type="text" min="09:30" max="14:00" style="width: 5rem" placeholder="hh:mm AM/PM" />
  <button type="submit">Submit</button>
</form>