как очистить сообщение CustomValidity после задержки (2 с) - PullRequest
1 голос
/ 07 апреля 2020

Я пытался использовать setTimeout в
function errMsg()
, но это ничего не дает.

Я просто хочу, чтобы красная граница сохранялась при неправильной записи, но без сообщения .. .

const formFrEu = document.getElementById('converter-form')
  ,   v_Euro   = 6.55957
  ,   regNum   = /^\d+\.\d+?$/
  ;
formFrEu.onsubmit = e => e.preventDefault();
formFrEu.oninput = e =>
  {
  // formFrEu.Franc.setCustomValidity('')  //  try changed by 2s delay
  // formFrEu.Euro.setCustomValidity('')

  switch (e.target.name)
    {
    case 'Franc':
      if (formFrEu.Franc.reportValidity())
        formFrEu.Euro.value = (parseFloat(formFrEu.Franc.value) / v_Euro).toFixed(2)
      break;
    case 'Euro':
      if (formFrEu.Euro.reportValidity())
        formFrEu.Franc.value = (parseFloat(formFrEu.Euro.value) * v_Euro).toFixed(2)
      break;
    }
  }
formFrEu.Euro.oninvalid  = errMsg;
formFrEu.Franc.oninvalid = errMsg;

function errMsg(e)
  {
  if (regNum.test(e.target.value))
    {
    e.target.setCustomValidity('sonly 2 digits after the decimal point !')
    } 
  else
    {
    e.target.setCustomValidity('Please enter a numeric value !')
    }
  setTimeout(() => {  e.target.setCustomValidity('');  }, 2000);  // not working!!
  }
<form id="converter-form">
  <h2>Converter Euros  &lt;-&gt; Francs </h2>

  <label>
    <h4>Euros</h4>
    <input type="text" name="Euro" placeholder="Enter the amount in Euros"   pattern="[0-9]+([\.][0-9]{0,2})?" autocomplete=off>
  </label>

  <label>
    <h4>Francs</h4>
    <input type="text" name="Franc" placeholder="Enter the amount in Francs"  pattern="[0-9]+([\.][0-9]{0,2})?" autocomplete=off>
  </label>

</form>

1 Ответ

0 голосов
/ 08 апреля 2020

Я нашел решение, но оно удовлетворяет меня только наполовину: я позволю себе судить самому: /

function errMsg(e)
  {
  let otherTarget = (e.target.name==='Franc') ? formFrEu.Euro : formFrEu.Franc

  if ( regNum.test(e.target.value) )
    { e.target.setCustomValidity('Only 2 digits after the decimal point !')     }
  else
    { e.target.setCustomValidity('Please enter a numeric value !') }

  setTimeout(()=>
    {
    if (document.activeElement===e.target) // if still on the same place
      {
      otherTarget.focus(); // double flip focus
      e.target.focus();   // will remove message bubble
      }
    }, 2000);
  }

PS: Поскольку я работаю в основном с Firefox, я не осознавал, что под Chromium сообщение исчезает само по себе через несколько секунд, но из-за того, что оно не накладывает какого-либо цветового эффекта на границу ...

завершить страницу для тестирования (я внес небольшие изменения по сравнению с исходным сообщением)

const formFrEu = document.getElementById('converter-form')
  ,   v_Euro   = 6.55957
  ,   inPatt   = '[0-9]+([\.][0-9]{0,2})?'
  ,   regNum   = /^\d+\.\d+?$/
  ;
formFrEu.querySelectorAll('input').forEach(inp=>
  {
  inp.pattern = inPatt
  inp.autocomplete = 'off'
  })
formFrEu.onsubmit=e=>e.preventDefault() 
  ;
formFrEu.oninput=e=>
  {
  formFrEu.Francs.setCustomValidity('')
  formFrEu.Euros.setCustomValidity('')

  let noStrVal = (e.target.value.trim()==='')

  switch (e.target.name)
    {
    case 'Francs':
      if ( formFrEu.Francs.reportValidity() )
        {
        formFrEu.Euros.value = noStrVal? '' : (parseFloat(formFrEu.Francs.value) / v_Euro).toFixed(2)  
        }
      break;
    case 'Euros':
      if ( formFrEu.Euros.reportValidity() )
        {
        formFrEu.Francs.value = noStrVal? '' : (parseFloat(formFrEu.Euros.value) * v_Euro).toFixed(2)
        }
      break;
    }
  }

formFrEu.Euros.oninvalid = errMsg
formFrEu.Francs.oninvalid= errMsg

function errMsg(e)
  {
  let otherTarget = (e.target.name==='Francs') ? formFrEu.Euros : formFrEu.Francs

  if ( regNum.test(e.target.value) )
    { e.target.setCustomValidity('Only 2 digits after the decimal point !')     }
  else
    { e.target.setCustomValidity('Please enter a numeric value !') }

  setTimeout(()=>
    {
    if (document.activeElement===e.target) // if still on the same place
      {
      otherTarget.focus(); // double flip focus
      e.target.focus();   // will remove message bubble
      }
    }, 2000);
  }
input:invalid { border-color: crimson; }
<form id="converter-form" >
  <h3>Converters Euros <=> Francs </h3>

  <label>
    <h4>Euros</h4>
    <input type="text" name="Euros" placeholder="Enter the amount in Euros"  autocomplete="off" >
  </label> 
  <label>
    <h4>Francs</h4>
    <input type="text" name="Francs" placeholder="Enter the amount in Francs"  autocomplete="off" >
  </label>
</form>
...