Salá koleka na makambo ya ntina Salta na navigation ya docs
in English

Bondimisi ya mosala

Pesa makanisi ya motuya, oyo ekoki kosala na basaleli na yo na bondimi ya formulaire HTML5, na nzela ya bizaleli ya navigateur na ndenge ya liboso to ba styles personnalisés mpe JavaScript.

Toyebi ete na ntango oyo ba styles ya validation personnalisée ya côté client mpe ba toli ya bisaleli ezali accessible te, puisque ezali exposés te na ba technologies ya lisungi. Ntango tozali kosala na solution, tokopesa toli ya kosalela option ya côté serveur to méthode ya validation ya navigateur par défaut.

Ndenge oyo esalaka

Tala ndenge validation ya formulaire esalaka na Bootstrap:

  • Validation ya formulaire HTML esalemi na nzela ya ba pseudo-classes mibale ya CSS, :invalidmpe :valid. Etaleli <input>, <select>, mpe <textarea>biloko.
  • Bootstrap esali ba styles ya :invalidmpe :validna classe ya moboti .was-validated, mingi mingi esalelamaka na <form>. Soki te, esika nyonso oyo esengeli kozanga motuya ekolakisama lokola oyo ezali na ntina te na bokɔti ya lokasa. Na ndenge yango, okoki kopona ntango nini okofungola yango (mingimingi nsima ya komeka kotinda formulaire).
  • Mpo na kozongisa lolenge ya komonana ya formulaire (ndakisa, na likambo ya botindiki ya formulaire dynamique na kosalelaka AJAX), longola .was-validatedkelasi na <form>lisusu nsima ya kotinda.
  • Lokola fallback, .is-invalidmpe .is-validba classes ekoki kosalelama na esika ya ba pseudo-classes mpo na validation ya côté serveur . Bazali kosɛnga te .was-validatedkelasi ya baboti.
  • Na tina ya ba contraintes na ndenge CSS esalaka, tokoki te (na tango oyo) kosalela ba styles na a <label>oyo eyaka liboso ya contrôle ya formulaire na DOM sans aide ya JavaScript personnalisé.
  • Ba navigateurs nionso ya mikolo oyo esungaka API ya validation ya contrainte , série ya ba méthodes ya JavaScript pona ko valider ba contrôles ya formulaire.
  • Ba messages ya ba réactions ekoki kosalela ba défauts ya navigateur (ekeseni mpo na navigateur moko na moko, mpe ekoki kozala na style te na nzela ya CSS) to ba styles na biso ya ba réactions personnalisés na HTML mpe CSS ya kobakisa.
  • Okoki kopesa ba messages ya validité personnalisé na setCustomValidityna JavaScript.

Na makanisi wana, talelá ba démonstrations oyo elandi mpo na ba styles na biso ya validation ya formulaire personnalisé, ba classes ya côté serveur oyo okoki kopona, mpe ba défauts ya navigateur.

Ba styles oyo esalemi na kolanda bamposa ya bato

Mpo na ba messages ya validation ya formulaire ya Bootstrap personnalisé, ekosenga obakisa novalidateattribut boolean na <form>. Yango e désactiver ba conseils ya retour par défaut ya navigateur, kasi epesaka kaka accès na ba API ya validation ya formulaire na JavaScript. Meká kotinda formulaire oyo ezali awa na nse; JavaScript na biso ekokanga bouton ya kotinda mpe ekopesa yo makanisi. Ntango ozali komeka kotinda, okomona :invalidmpe :validmitindo oyo esalelami na ba contrôles ya formulaire na yo.

Ba styles ya ba retours personnalisés esalelaka ba couleurs personnalisées, ba frontières, ba styles ya focus, na ba icônes ya fond pona ko communiquer malamu ba réactions. Ba icônes ya fond ya <select>s ezali kaka na .form-select, mpe te .form-control.

Emonani malamu!
Emonani malamu!
@
Svp pona kombo ya mosaleli.
Svp bopesa engumba oyo ezali na ntina.
Please select a valid state.
Please provide a valid zip.
You must agree before submitting.
<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
(function () {
  'use strict'

  // Fetch all the forms we want to apply custom Bootstrap validation styles to
  var forms = document.querySelectorAll('.needs-validation')

  // Loop over them and prevent submission
  Array.prototype.slice.call(forms)
    .forEach(function (form) {
      form.addEventListener('submit', function (event) {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }

        form.classList.add('was-validated')
      }, false)
    })
})()

Navigateur ezo défaut

Ozali na mposa te ya ba messages ya rétroaction ya validation personnalisée to kokoma JavaScript mpo na kobongola bizaleli ya formulaire? Nionso bien, okoki kosalela ba défauts ya navigateur. Meká kotinda formulaire oyo ezali awa na nse. Na kotalela navigateur mpe OS na yo, okomona lolenge ya kopesa makanisi oyo ekeseni mwa moke.

Atako ba styles oyo ya ba réactions ekoki kozala style na CSS te, okoki kaka ko personnaliser texte ya ba réactions na nzela ya 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>

Côté ya serveur

Tosengi kosalela validation côté client, kasi na cas osengi validation côté serveur, okoki kolakisa ba champs ya formulaire oyo ezali na valeur te mpe oyo ezali valide na .is-invalidmpe .is-valid. Boyeba ete .invalid-feedbackezali mpe kosungama na bakelasi oyo.

Mpo na bisika oyo ezali na ntina te, sala ete nsango ya bozongisi makanisi/erreur oyo ezali malamu te ezala na boyokani na esika ya formulaire oyo etali yango na kosalelaka aria-describedby(koyeba ete attribut oyo epesaka nzela ya kosala référence koleka moko id, soki esika yango ezali déjà kolakisa makomi ya formulaire ya kobakisa).

Mpo na kobongisa makambo na ba rayons ya ndelo.has-validation , bituluku ya bokɔti esɛngaka kelasi ya kobakisa .

Emonani malamu!
Emonani malamu!
@
Svp pona kombo ya mosaleli.
Svp bopesa engumba oyo ezali na ntina.
Svp pona état oyo ezali valide.
Svp bopesa zip oyo ezali valide.
Esengeli ondima liboso ya kotinda.
<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>

Ba éléments oyo esungami

Ba styles ya validation ezali pona ba contrôles ya formulaire na ba composants oyo elandi:

  • <input>s mpe <textarea>s na .form-control(kosangisa kino moko .form-controlna bituluku ya bokɔti) .
  • <select>s na.form-select
  • .form-checks
Svp kotia message na esika ya texte.
Ndakisa ya makomi ya bozongisi makanisi oyo ezali na ntina te
Ndakisa mingi texte ya rétroaction ya mabe
Ndakisa ya makanisi ya kopona oyo ezali malamu te
Ndakisa ya bozongisi makanisi ya fisyé ya formulaire oyo ezali na ntina te
<form class="was-validated">
  <div class="mb-3">
    <label for="validationTextarea" class="form-label">Textarea</label>
    <textarea class="form-control is-invalid" 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>

Batoli ya bisaleli

Soki bobongisi ya formulaire na yo epesi yango nzela, okoki kobongola .{valid|invalid}-feedbackbakelasi mpo na .{valid|invalid}-tooltipbakelasi mpo na kolakisa makanisi ya bondimi na lisalisi ya bisaleli oyo ezali na lolenge. Kobosana te kozala na moboti na position: relativelikolo na yango mpo na positionnement ya tooltip. Na ndakisa oyo ezali awa na nse, ba classes na biso ya colonne ezali déjà na oyo, kasi projet na yo ekoki kosenga configuration alternative.

Looks good!
Looks good!
@
Please choose a unique and valid username.
Please provide a valid city.
Please select a valid state.
Please provide a valid zip.
<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 oyo azali

Ba variables oyo ezali

$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.73L.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>");

Ba mixins

Mixins mibale esangani esika moko, na nzela ya boucle na biso , mpo na kobimisa ba styles na biso ya retour ya validation ya formulaire.

@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-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,
  .input-group .form-select {
    @include form-validation-state-selector($state) {
      @if $state == "valid" {
        z-index: 1;
      } @else if $state == "invalid" {
        z-index: 2;
      }
      &:focus {
        z-index: 3;
      }
    }
  }
}

Karte

Oyo ezali carte Sass ya validation oyo euti na _variables.scss. Bolongola to bopanzi oyo mpo na kobimisa ba états ekeseni to ya kobakisa.

$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
  )
);

Ba cartes ya $form-validation-statesekoki kozala na ba paramètres misato ya option pona ko superposer ba toli ya bisaleli pe ba styles ya focus.

Boucle

Esalemi pona ko iterer likolo $form-validation-statesya ba valeurs ya carte pona ko générer ba styles na biso ya validation. Ba modifications nionso na carte Sass oyo ezali likolo ekozala na CSS na yo compilé na nzela ya boucle oyo.

@each $state, $data in $form-validation-states {
  @include form-validation-state($state, $data...);
}

Kosala na ndenge ya moto ye moko

Ba états ya validation ekoki kozala personnalisé via Sass na $form-validation-statescarte. Ezwami na _variables.scssfichier na biso, carte oyo ya Sass ezali ndenge tozali ko générer ba états par défaut valid/ invalidvalidation. Ezali na kati ya karte oyo ekangami mpo na kobongisa langi ya etúká mokomoko, elembo, langi ya tooltip, mpe elili ya focus. Atako ba états mosusu te esungami na ba navigateurs, ba oyo basalelaka ba styles personnalisés bakoki kobakisa na pete ba retours ya formulaire ya complexe mingi.

Svp bo yeba que to recommandé te ko personnaliser ba $form-validation-statesvaleurs sans aussi ko modifier form-validation-statemixin .