Я нашел решение, но оно удовлетворяет меня только наполовину: я позволю себе судить самому: /
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>