Form Validate
regexp | javascript
Прізвище
Може складатися з двох частин (Карпенко-Карий), які пишуться через дефіс
maxlength="30"
placeholder="Іваненко"
pattern="[А-яІіЇїЄєҐґ\-'’]{2,30}"
required
Ім’я
Може складатися з двох слів (Анна Марія), тому тут є пробіл
maxlength="30"
placeholder="Василь"
pattern="[А-яІіЇїЄєҐґ\s'’]{2,30}"
required
По батькові
maxlength="30"
placeholder="Федорович"
pattern="[А-яІіЇїЄєҐґ'’]{2,30}"
email
maxlength="50"
placeholder="name@example.com"
pattern="[0-9A-Z_a-z\.\-]+@[0-9A-Z_a-z\.\-]+?\.[a-z]{2,}"
required
Перевірити поля по шаблонам і піти на іншу сторінку або скрипт:
В form є action і onsubmit.
onsubmit - запускає bootstrap-перевірку полів, і якщо вона проходить - виконується action.
Поля з pattert - перевіряються по цьому шаблону, якщо у поля є тільки required - поле перевіряєтся на не порожність. Якщо нема ні того, ні іншого - поле не перевіряється.
HTML
<form id="mainform" action="user_login.py" method="POST" class="row g-3 needs-validation" novalidate onsubmit="is_valid();">
<div class="col-md-4">
<label for="login" class="form-label">{{ TX_LOGIN }}</label>
<input type="text" class="form-control" id="login" name="login" aria-describedby="loginHelpBlock" pattern="^[\.@\d\-\A-Za-z]+$" required>
<div id="loginHelpBlock" class="form-text">{{ TX_HELP_LOGIN }}</div>
<div class="invalid-feedback">{{ TX_INVALID_INPUT }}</div>
</div>
<div class="col-md-8">
</div>
<div class="col-md-4">
<label for="password" class="form-label">{{ TX_PASSWORD }}</label>
<input type="password" class="form-control" id="password" name="password" aria-describedby="passwordHelpBlock" required>
<div id="passwordHelpBlock" class="form-text">{{ TX_HELP_PASSWORD }}</div>
<div class="invalid-feedback">{{ TX_INVALID_INPUT }}</div>
</div>
<div class="col-md-8">
</div>
<div class="col-12 py-2" id="alertPlace"></div>
<div class="col-12 text-center">
<button type="submit" id="bSave" class="btn btn-primary w-50" >{{ TX_ENTER }}</button>
</div>
</form>
JS
function is_valid()
{
if (!mainform.checkValidity())
{
// "custom Bootstrap form validation" (перевірка за шаблонами)
event.preventDefault();
event.stopPropagation();
// для того, щоб показати які поля не пройшли провірку:
mainform.classList.add('was-validated');
}
else
{
// якщо пройшло, щоб не залишалися "зелені" поля з галочками
mainform.classList.remove('was-validated');
}
}
Перевірити поля по шаблонам (потім виконати AJAX-запит) і залишитися на цій сторінці:
В цьому прикладі, крім bootstrap-перевірки полів за шаблонами mainform.checkValidity(), ще відбувається перевірка за значеннями: check_param(), потім вже виконується AJAX-запит save_param().
<form id="mainform" class="row g-3 needs-validation" novalidate onsubmit="return false;">
<div class="col-md-4">
<label for="tTemp" class="form-label">{{ TX_TEMPERATURE }}, °С</label>
<input type="text" class="form-control" id="tTemp" name="t_temp" value="{{ TEMPERATURE }}" aria-describedby="tempHelpBlock" autocomplete="off" pattern="^-*\d{1,2}(?:[\.,]\d{0,2})?$">
<div id="tempHelpBlock" class="form-text">{{ TX_AVERAGE_VALUE }}: <b id="avTemp">{% if AV_TEMP %}{{ AV_TEMP }}{% endif %}</b> °С</div>
<div class="invalid-feedback">{{ TX_INCORRECT_VALUE }} (-25°С ... 45°С)</div>
</div>
<div class="col-md-4">
<label for="nHumd" class="form-label text-end">{{ TX_HUMIDITY }}, %</label>
<input type="number" class="form-control" id="nHumd" name="n_humd" value="{{ HUMIDITY }}" aria-describedby="humdHelpBlock" min="10" max="90" step="1">
<div id="humdHelpBlock" class="form-text">{{ TX_AVERAGE_VALUE }}: <b id="avHumd">{% if AV_HUMD %}{{ AV_HUMD }}{% endif %}</b> %</div>
<div class="invalid-feedback">{{ TX_INCORRECT_VALUE }} (10% ... 90%)</div>
</div>
<div class="col-md-4">
<label for="tPres" class="form-label text-end">{{ TX_PRESSURE }}, гПа</label>
<input type="text" class="form-control" id="tPres" value="{{ PRESSURE }}" name="t_pres" aria-describedby="presHelpBlock" autocomplete="off" pattern="^\d{3,4}(?:[\.,]\d{0,2})?$">
<div id="presHelpBlock" class="form-text">{{ TX_AVERAGE_VALUE }}: <b id="avPres">{% if AV_PRES %}{{ AV_PRES }}{% endif %}</b> гПа</div>
<div class="invalid-feedback">{{ TX_INCORRECT_VALUE }} (950 - 1050 гПа)</div>
</div>
<button type="submit" id="bSave" class="btn btn-primary w-50">{{ TX_SAVE }}</button>
</form>
// --------------------------------------------------------------
mainform.addEventListener('submit', event =>
{
if (!mainform.checkValidity())
{
// спочатку "custom Bootstrap form validation" (перевірка за шаблонами)
event.preventDefault();
event.stopPropagation();
// для того, щоб показати які поля не пройшли провірку
mainform.classList.add('was-validated');
}
else
{
// потім - перевірка за значеннями, вимикаємо дію псевдо-класів :invalid та :valid
mainform.classList.remove('was-validated');
// і будемо використовувати класи .is-valid та .is-invalid для
// позначення полів, що не пройшли перевірку
// https://getbootstrap.com/docs/5.2/forms/validation/
if (check_param())
{
bSave.disabled = true;
save_param();
}
else
{
return false;
}
}
}, false)
/* --------------------------------------------------------------------- */
function check_param()
{
if ((tTemp.value + nHumd.value + tPres.value).trim() == '')
{
if (!confirm(TX_EMPTY_CONFIRM))
{
get_param();
bSave.disabled = false;
return false;
}
}
else
{
let err = 0;
if (tTemp.value.trim() != '' && (tTemp.value * 1 < -25 || tTemp.value * 1 > 45))
{
valid(tTemp, false);
err = 1;
} else {
valid(tTemp, true);
}
if (nHumd.value.trim() != '' && (nHumd.value * 1 < 10 || nHumd.value * 1 > 90))
{
valid(nHumd, false);
err = 1;
} else {
valid(nHumd, true);
}
if (tPres.value.trim() != '' && (tPres.value * 1 < 950 || tPres.value * 1 > 1050))
{
valid(tPres, false);
err = 1;
} else {
valid(tPres, true);
}
if (err == 1) return false;
}
return true;
}
/* --------------------------------------------------------------------- */
function valid(elem, bl)
{
if (bl == true) // set valid
{
elem.classList.remove('is-invalid');
elem.classList.add('is-valid');
}
else if (bl == false) // set invalid
{
elem.classList.remove('is-valid');
elem.classList.add('is-invalid');
}
else // clear all
{
elem.classList.remove('is-valid');
elem.classList.remove('is-invalid');
}
}
/* --------------------------------------------------------------------- */
function input_disabled(bool)
{
tTemp.disabled = bool;
nHumd.disabled = bool;
tPres.disabled = bool;
bSave.disabled = bool;
}
/* --------------------------------------------------------------------- */
function save_param_success(resp) {
const json_obj = resp;
if (resp && 'res' in resp)
{
if (resp.res === 'err') // error
{
errmess = ERROR;
num_errors = resp.err.length;
for (let i = 1; i <= num_errors; i++)
{
errmess += '<br>' + i +'. '+ resp.err[i-1]
}
valid(tTemp);
valid(nHumd);
valid(tPres);
alert('danger', errmess);
}
else if (resp.res === 'sux')
{
alert('hide');
// message('sux', resp.sux); // not winXP!
alert('success', resp.sux);
}
}
else
alert('danger', SRV_UNKNOWN_RESPONSE);
}
/* --------------------------------------------------------------------- */
function save_param_error(err) {
console.dir(err);
alert('danger', SRV_ERR);
}
/* --------------------------------------------------------------------- */
function save_param() {
let fdata = new FormData(document.forms.mainform);
fetch("/atmo/save/", { method: "POST", body: fdata })
.then(resp => {
if (resp.status != 200) {
alert('danger', SRV_REFUSED_REQUEST +` Status: ${resp.status}`);
}
return resp.json(); // return server response as json
})
.then(resp => save_param_success(resp))
.catch(err => save_param_error(err));
// return false; // prevent form submit
}
Last updated