延迟(2秒)后如何清除CustomValidity消息

时间:2020-04-07 15:33:23

标签: javascript forms validation

我尝试在其中使用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 :(得分:0)

我找到了一个解决方案,但只能让我满意一半:我让你自己判断:/

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>