Kev lees paub
Muab cov lus qhia tseem ceeb, ua tau zoo rau koj cov neeg siv nrog HTML5 daim ntawv validation, ntawm browser default cwj pwm los yog kev cai style thiab JavaScript.
Nws ua haujlwm li cas
Nov yog li cas daim ntawv validation ua haujlwm nrog Bootstrap:
- HTML daim ntawv validation yog siv ntawm CSS's ob pseudo-chav kawm,
:invalid
thiab:valid
. Nws siv rau<input>
,<select>
, thiab<textarea>
cov khoom. - Bootstrap scopes
:invalid
thiab:valid
styles rau niam txiv.was-validated
chav kawm, feem ntau siv rau<form>
. Txwv tsis pub, txhua qhov chaw uas yuav tsum tau muaj yam tsis muaj nqi qhia tau tias tsis raug ntawm nplooj ntawv thauj khoom. Txoj kev no, koj tuaj yeem xaiv thaum twg los qhib lawv (feem ntau tom qab xa daim ntawv thov). - Txhawm rau rov pib dua qhov zoo li ntawm daim ntawv (piv txwv li, nyob rau hauv cov ntaub ntawv ntawm dynamic daim ntawv xa mus siv AJAX), tshem tawm cov
.was-validated
chav kawm ntawv los ntawm<form>
dua tom qab xa. - Raws li kev poob qis,
.is-invalid
thiab.is-valid
cov chav kawm yuav raug siv los hloov cov pseudo-chav kawm rau server-sab validation . Lawv tsis tas yuav muaj.was-validated
chav kawm niam txiv. - Vim muaj kev txwv hauv CSS ua haujlwm li cas, peb tsis tuaj yeem (tam sim no) siv cov qauv rau ib qho
<label>
uas los ua ntej daim ntawv tswj hauv DOM yam tsis muaj kev pab los ntawm kev cai JavaScript. - Tag nrho cov browsers niaj hnub no txhawb nqa qhov txwv tsis pub siv API , cov txheej txheem JavaScript rau kev tswj xyuas daim ntawv.
- Cov lus tawm tswv yim tuaj yeem siv qhov browser defaults (sib txawv rau txhua qhov browser, thiab tsis zoo ntawm CSS) los yog peb cov kev cai tawm tswv yim nrog ntxiv HTML thiab CSS.
- Koj tuaj yeem muab cov lus muaj cai siv tau nrog
setCustomValidity
hauv JavaScript.
Nrog rau qhov ntawd nyob rau hauv lub siab, xav txog cov nram qab no demos rau peb cov kev cai validation styles, xaiv server-sab chav kawm, thiab browser defaults.
Kev cai style
Rau kev cai Bootstrap daim ntawv validation lus, koj yuav tsum tau ntxiv tus novalidate
cwj pwm boolean rau koj <form>
. Qhov no cuam tshuam qhov browser default tawm tswv yim cov lus qhia, tab sis tseem muab kev nkag mus rau daim ntawv validation APIs hauv JavaScript. Sim xa daim foos hauv qab no; peb JavaScript yuav cuam tshuam lub pob xa tawm thiab xa cov lus tawm tswv yim rau koj. Thaum sim xa, koj yuav pom cov qauv :invalid
thiab :valid
cov qauv siv rau koj daim ntawv tswj hwm.
Cov kev tawm tswv yim kev cai siv cov xim kev cai, ciam teb, tsom cov qauv, thiab cov cim keeb kwm yav dhau los kom sib txuas lus zoo dua. Cov cim keeb kwm yav dhau rau <select>
s tsuas yog muaj nrog .form-select
, thiab tsis yog .form-control
.
<form class="row g-3 needs-validation" novalidate>
<div class="col-md-4">
<label for="validationCustom01" class="form-label">First name</label>
<input type="text" class="form-control" id="validationCustom01" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationCustom02" class="form-label">Last name</label>
<input type="text" class="form-control" id="validationCustom02" value="Otto" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationCustomUsername" class="form-label">Username</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend">@</span>
<input type="text" class="form-control" id="validationCustomUsername" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
<div class="col-md-6">
<label for="validationCustom03" class="form-label">City</label>
<input type="text" class="form-control" id="validationCustom03" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
</div>
<div class="col-md-3">
<label for="validationCustom04" class="form-label">State</label>
<select class="form-select" id="validationCustom04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="invalid-feedback">
Please select a valid state.
</div>
</div>
<div class="col-md-3">
<label for="validationCustom05" class="form-label">Zip</label>
<input type="text" class="form-control" id="validationCustom05" required>
<div class="invalid-feedback">
Please provide a valid zip.
</div>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
<label class="form-check-label" for="invalidCheck">
Agree to terms and conditions
</label>
<div class="invalid-feedback">
You must agree before submitting.
</div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(() => {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
const forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.from(forms).forEach(form => {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
Browser defaults
Tsis txaus siab rau cov lus qhia txog kev lees paub kev cai lossis sau JavaScript los hloov tus cwj pwm? Txhua yam zoo, koj tuaj yeem siv qhov browser defaults. Sim xa daim foos hauv qab no. Nyob ntawm koj tus browser thiab OS, koj yuav pom qhov txawv me ntsis ntawm cov lus tawm tswv yim.
Txawm hais tias cov kev tawm tswv yim no tsis tuaj yeem tsim nrog CSS, koj tseem tuaj yeem hloov kho cov lus tawm tswv yim los ntawm JavaScript.
<form class="row g-3">
<div class="col-md-4">
<label for="validationDefault01" class="form-label">First name</label>
<input type="text" class="form-control" id="validationDefault01" value="Mark" required>
</div>
<div class="col-md-4">
<label for="validationDefault02" class="form-label">Last name</label>
<input type="text" class="form-control" id="validationDefault02" value="Otto" required>
</div>
<div class="col-md-4">
<label for="validationDefaultUsername" class="form-label">Username</label>
<div class="input-group">
<span class="input-group-text" id="inputGroupPrepend2">@</span>
<input type="text" class="form-control" id="validationDefaultUsername" aria-describedby="inputGroupPrepend2" required>
</div>
</div>
<div class="col-md-6">
<label for="validationDefault03" class="form-label">City</label>
<input type="text" class="form-control" id="validationDefault03" required>
</div>
<div class="col-md-3">
<label for="validationDefault04" class="form-label">State</label>
<select class="form-select" id="validationDefault04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
</div>
<div class="col-md-3">
<label for="validationDefault05" class="form-label">Zip</label>
<input type="text" class="form-control" id="validationDefault05" required>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck2" required>
<label class="form-check-label" for="invalidCheck2">
Agree to terms and conditions
</label>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
Server sab
Peb pom zoo kom siv cov neeg siv khoom validation, tab sis nyob rau hauv rooj plaub koj xav tau server-sab validation, koj tuaj yeem qhia cov ntawv tsis raug thiab siv tau nrog .is-invalid
thiab .is-valid
. Nco ntsoov tias .invalid-feedback
tseem muaj kev txhawb nqa nrog cov chav kawm no.
Rau cov teb tsis raug, xyuas kom meej tias cov lus tawm tswv yim tsis raug / cov lus yuam kev cuam tshuam nrog cov ntaub ntawv cuam tshuam nrog kev siv aria-describedby
(nco ntsoov tias tus cwj pwm no tso cai rau ntau tshaj ib qho id
los hais txog, yog tias daim teb twb tau taw qhia rau daim ntawv ntxiv).
Txhawm rau txhim kho cov teeb meem nrog lub vojvoog ciam teb , cov tswv yim pab pawg yuav tsum muaj .has-validation
chav kawm ntxiv.
<form class="row g-3">
<div class="col-md-4">
<label for="validationServer01" class="form-label">First name</label>
<input type="text" class="form-control is-valid" id="validationServer01" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationServer02" class="form-label">Last name</label>
<input type="text" class="form-control is-valid" id="validationServer02" value="Otto" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationServerUsername" class="form-label">Username</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend3">@</span>
<input type="text" class="form-control is-invalid" id="validationServerUsername" aria-describedby="inputGroupPrepend3 validationServerUsernameFeedback" required>
<div id="validationServerUsernameFeedback" class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
<div class="col-md-6">
<label for="validationServer03" class="form-label">City</label>
<input type="text" class="form-control is-invalid" id="validationServer03" aria-describedby="validationServer03Feedback" required>
<div id="validationServer03Feedback" class="invalid-feedback">
Please provide a valid city.
</div>
</div>
<div class="col-md-3">
<label for="validationServer04" class="form-label">State</label>
<select class="form-select is-invalid" id="validationServer04" aria-describedby="validationServer04Feedback" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div id="validationServer04Feedback" class="invalid-feedback">
Please select a valid state.
</div>
</div>
<div class="col-md-3">
<label for="validationServer05" class="form-label">Zip</label>
<input type="text" class="form-control is-invalid" id="validationServer05" aria-describedby="validationServer05Feedback" required>
<div id="validationServer05Feedback" class="invalid-feedback">
Please provide a valid zip.
</div>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input is-invalid" type="checkbox" value="" id="invalidCheck3" aria-describedby="invalidCheck3Feedback" required>
<label class="form-check-label" for="invalidCheck3">
Agree to terms and conditions
</label>
<div id="invalidCheck3Feedback" class="invalid-feedback">
You must agree before submitting.
</div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
Txhawb cov ntsiab lus
Cov qauv kev lees paub muaj nyob rau hauv daim ntawv tswj thiab cov khoom hauv qab no:
<input>
s thiab<textarea>
s nrog.form-control
(xws li mus txog ib qho.form-control
hauv pawg tswv yim)<select>
s nrog.form-select
.form-check
s
<form class="was-validated">
<div class="mb-3">
<label for="validationTextarea" class="form-label">Textarea</label>
<textarea class="form-control" id="validationTextarea" placeholder="Required example textarea" required></textarea>
<div class="invalid-feedback">
Please enter a message in the textarea.
</div>
</div>
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="validationFormCheck1" required>
<label class="form-check-label" for="validationFormCheck1">Check this checkbox</label>
<div class="invalid-feedback">Example invalid feedback text</div>
</div>
<div class="form-check">
<input type="radio" class="form-check-input" id="validationFormCheck2" name="radio-stacked" required>
<label class="form-check-label" for="validationFormCheck2">Toggle this radio</label>
</div>
<div class="form-check mb-3">
<input type="radio" class="form-check-input" id="validationFormCheck3" name="radio-stacked" required>
<label class="form-check-label" for="validationFormCheck3">Or toggle this other radio</label>
<div class="invalid-feedback">More example invalid feedback text</div>
</div>
<div class="mb-3">
<select class="form-select" required aria-label="select example">
<option value="">Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<div class="invalid-feedback">Example invalid select feedback</div>
</div>
<div class="mb-3">
<input type="file" class="form-control" aria-label="file example" required>
<div class="invalid-feedback">Example invalid form file feedback</div>
</div>
<div class="mb-3">
<button class="btn btn-primary" type="submit" disabled>Submit form</button>
</div>
</form>
Cov lus qhia
Yog tias koj daim ntawv layout tso cai rau nws, koj tuaj yeem sib pauv cov .{valid|invalid}-feedback
chav kawm rau .{valid|invalid}-tooltip
cov chav kawm los tso tawm cov lus pom zoo rau hauv cov lus qhia styled. Nco ntsoov muaj ib tug niam txiv nrog position: relative
rau nws rau qhov kev taw qhia qhov chaw. Hauv qhov piv txwv hauv qab no, peb cov chav kawm kem muaj qhov no lawm, tab sis koj qhov project yuav xav tau lwm txoj kev teeb tsa.
<form class="row g-3 needs-validation" novalidate>
<div class="col-md-4 position-relative">
<label for="validationTooltip01" class="form-label">First name</label>
<input type="text" class="form-control" id="validationTooltip01" value="Mark" required>
<div class="valid-tooltip">
Looks good!
</div>
</div>
<div class="col-md-4 position-relative">
<label for="validationTooltip02" class="form-label">Last name</label>
<input type="text" class="form-control" id="validationTooltip02" value="Otto" required>
<div class="valid-tooltip">
Looks good!
</div>
</div>
<div class="col-md-4 position-relative">
<label for="validationTooltipUsername" class="form-label">Username</label>
<div class="input-group has-validation">
<span class="input-group-text" id="validationTooltipUsernamePrepend">@</span>
<input type="text" class="form-control" id="validationTooltipUsername" aria-describedby="validationTooltipUsernamePrepend" required>
<div class="invalid-tooltip">
Please choose a unique and valid username.
</div>
</div>
</div>
<div class="col-md-6 position-relative">
<label for="validationTooltip03" class="form-label">City</label>
<input type="text" class="form-control" id="validationTooltip03" required>
<div class="invalid-tooltip">
Please provide a valid city.
</div>
</div>
<div class="col-md-3 position-relative">
<label for="validationTooltip04" class="form-label">State</label>
<select class="form-select" id="validationTooltip04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="invalid-tooltip">
Please select a valid state.
</div>
</div>
<div class="col-md-3 position-relative">
<label for="validationTooltip05" class="form-label">Zip</label>
<input type="text" class="form-control" id="validationTooltip05" required>
<div class="invalid-tooltip">
Please provide a valid zip.
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
Sass
Hloov pauv
$form-feedback-margin-top: $form-text-margin-top;
$form-feedback-font-size: $form-text-font-size;
$form-feedback-font-style: $form-text-font-style;
$form-feedback-valid-color: $success;
$form-feedback-invalid-color: $danger;
$form-feedback-icon-valid-color: $form-feedback-valid-color;
$form-feedback-icon-valid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>");
$form-feedback-icon-invalid-color: $form-feedback-invalid-color;
$form-feedback-icon-invalid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>");
Mixins
Ob lub mixins ua ke ua ke, los ntawm peb lub voj , los tsim peb daim ntawv validation tawm tswv yim.
@mixin form-validation-state-selector($state) {
@if ($state == "valid" or $state == "invalid") {
.was-validated #{if(&, "&", "")}:#{$state},
#{if(&, "&", "")}.is-#{$state} {
@content;
}
} @else {
#{if(&, "&", "")}.is-#{$state} {
@content;
}
}
}
@mixin form-validation-state(
$state,
$color,
$icon,
$tooltip-color: color-contrast($color),
$tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),
$focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity)
) {
.#{$state}-feedback {
display: none;
width: 100%;
margin-top: $form-feedback-margin-top;
@include font-size($form-feedback-font-size);
font-style: $form-feedback-font-style;
color: $color;
}
.#{$state}-tooltip {
position: absolute;
top: 100%;
z-index: 5;
display: none;
max-width: 100%; // Contain to parent when possible
padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
margin-top: .1rem;
@include font-size($form-feedback-tooltip-font-size);
line-height: $form-feedback-tooltip-line-height;
color: $tooltip-color;
background-color: $tooltip-bg-color;
@include border-radius($form-feedback-tooltip-border-radius);
}
@include form-validation-state-selector($state) {
~ .#{$state}-feedback,
~ .#{$state}-tooltip {
display: block;
}
}
.form-control {
@include form-validation-state-selector($state) {
border-color: $color;
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-image: escape-svg($icon);
background-repeat: no-repeat;
background-position: right $input-height-inner-quarter center;
background-size: $input-height-inner-half $input-height-inner-half;
}
&:focus {
border-color: $color;
box-shadow: $focus-box-shadow;
}
}
}
// stylelint-disable-next-line selector-no-qualifying-type
textarea.form-control {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
}
}
}
.form-select {
@include form-validation-state-selector($state) {
border-color: $color;
@if $enable-validation-icons {
&:not([multiple]):not([size]),
&:not([multiple])[size="1"] {
padding-right: $form-select-feedback-icon-padding-end;
background-image: escape-svg($form-select-indicator), escape-svg($icon);
background-position: $form-select-bg-position, $form-select-feedback-icon-position;
background-size: $form-select-bg-size, $form-select-feedback-icon-size;
}
}
&:focus {
border-color: $color;
box-shadow: $focus-box-shadow;
}
}
}
.form-control-color {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
width: add($form-color-width, $input-height-inner);
}
}
}
.form-check-input {
@include form-validation-state-selector($state) {
border-color: $color;
&:checked {
background-color: $color;
}
&:focus {
box-shadow: $focus-box-shadow;
}
~ .form-check-label {
color: $color;
}
}
}
.form-check-inline .form-check-input {
~ .#{$state}-feedback {
margin-left: .5em;
}
}
.input-group {
> .form-control:not(:focus),
> .form-select:not(:focus),
> .form-floating:not(:focus-within) {
@include form-validation-state-selector($state) {
@if $state == "valid" {
z-index: 3;
} @else if $state == "invalid" {
z-index: 4;
}
}
}
}
}
Daim ntawv qhia
Nov yog daim ntawv qhia validation Sass los ntawm _variables.scss
. Override lossis txuas ntxiv qhov no los tsim cov xeev sib txawv lossis ntxiv.
$form-validation-states: (
"valid": (
"color": $form-feedback-valid-color,
"icon": $form-feedback-icon-valid
),
"invalid": (
"color": $form-feedback-invalid-color,
"icon": $form-feedback-icon-invalid
)
);
Maps ntawm $form-validation-states
tuaj yeem muaj peb qhov kev xaiv tsis tau los hla cov lus qhia thiab cov qauv tsom.
Loop
Siv los iterate dua $form-validation-states
daim ntawv qhia qhov tseem ceeb los tsim peb cov qauv siv tau. Txhua qhov kev hloov kho rau Sass daim ntawv qhia saum toj no yuav tshwm sim hauv koj cov CSS suav nrog ntawm lub voj no.
@each $state, $data in $form-validation-states {
@include form-validation-state($state, $data...);
}
Customizing
Kev lees paub lub xeev tuaj yeem hloov kho ntawm Sass nrog $form-validation-states
daim ntawv qhia. Nyob rau hauv peb cov _variables.scss
ntaub ntawv, Sass daim ntawv qhia no yog li cas peb tsim lub default valid
/ invalid
validation xeev. Xws li yog ib daim ntawv qhia nested rau customizing txhua lub xeev cov xim, icon, tooltip xim, thiab tsom teeb duab ntxoov ntxoo. Txawm hais tias tsis muaj lwm lub xeev tau txais kev txhawb nqa los ntawm browsers, cov neeg siv cov qauv kev cai tuaj yeem yooj yim ntxiv cov lus tawm tswv yim ntau dua.