Skip to main content

Introduzione

Elementi e stili per la creazione di form accessibili e responsivi.

Nella visualizzazione predefinita di un form gli elementi sono distribuiti verticalmente, ma è possibile utilizzare classi aggiuntive per variare questo tipo di layout.

Bootstrap Italia applica automaticamente a tutti i form display: block e width: 100%.

Organizzazione dei campi

Per raggruppare correttamente gli elementi di un modulo form è bene utilizzare la classe .form-group per ogni singolo blocco, in questo modo l’elemento input, l’etichetta, il testo di aiuto opzionale e la messaggistica di validazione otterranno lo stile grafico e le funzionalità per loro predisposte. Si può usare con <fieldset>, <div> o qualsiasi altro elemento.

Dimensionamento delle colonne

Strutture più complesse possono essere costruite usando il sistema a griglia, da utilizzare per layout che richiedono più colonne, larghezze diverse e opzioni di allineamento aggiuntive. La classe .row ne assicura una corretta spaziatura.

Si può scegliere di dare una dimensione ad una colonna, ad esempio dandogli una classe .col-md-6 per ottenere una certo design dal breakpoint md in su, mentre le restanti .col-md si divideranno il resto dello spazio.

<div>
  <div class="row">
    <div class="form-group col-md-6">
      <label for="formNome">Nome</label>
      <input type="text" class="form-control" id="formNome">
    </div>
    <div class="form-group col-md-6">
      <label for="formCognome">Cognome</label>
      <input type="text" class="form-control" id="formCognome">
    </div>
  </div>
  <div class="row">
    <div class="form-group col-md-6">
      <label for="Comune">Comune</label>
      <input type="text" class="form-control" id="Comune">
    </div>
    <div class="form-group col-md">
      <label for="Provincia">Provincia</label>
      <input type="text" class="form-control" id="Provincia">
    </div>
    <div class="form-group col-md">
      <label for="CAP">CAP</label>
      <input type="text" class="form-control" id="CAP">
    </div>
  </div>
</div>

Ecco l’esempio di una struttura più complessa creata con il sistema a griglie.

<div>
  <div class="row">
    <div class="form-group col-md-6">
      <label class="active" for="inputEmail4">Email</label>
      <input type="email" class="form-control" id="inputEmail4" placeholder="inserisci il tuo indirizzo email">
    </div>
    <div class="form-group col-md-6">
      <label class="active" for="exampleInputPassword">Password</label>
      <input type="password" data-bs-input class="form-control input-password" id="exampleInputPassword" placeholder="inserisci la tua password">
      <span class="password-icon" aria-hidden="true">
        <svg class="password-icon-visible icon icon-sm"><use href="/dist/svg/sprites.svg#it-password-visible"></use></svg>
        <svg class="password-icon-invisible icon icon-sm d-none"><use href="/dist/svg/sprites.svg#it-password-invisible"></use></svg>
      </span>
    </div>
  </div>
  <div class="row">
    <div class="form-group col">
      <label class="active" for="inputAddress">Indirizzo</label>
      <input type="text" class="form-control" id="inputAddress" placeholder="Via Roma, 1">
    </div>
  </div>
  <div class="row">
    <div class="form-group col-md-6">
      <label for="inputCity">Comune</label>
      <input type="text" class="form-control" id="inputCity">
    </div>
    <div class="form-group col-md-2">
      <label for="inputCAP">CAP</label>
      <input type="text" class="form-control" id="inputCAP">
    </div>
    <div class="form-group col-md-4">
      <div class="select-wrapper">
        <label for="selectID">Provincia</label>
        <select id="selectID">
          <option value="Value 1">Opzione 1</option>
          <option value="Value 2">Opzione 2</option>
          <option value="Value 3">Opzione 3</option>
          <option value="Value 4">Opzione 4</option>
          <option value="Value 5">Opzione 5</option>
        </select>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="form-group col-md-6">
      <div class="toggles">
        <label for="toggleEsempio1a">
          Label dell'interruttore 1
          <input type="checkbox" id="toggleEsempio1a">
          <span class="lever"></span>
        </label>
      </div>
    </div>
  </div>
  <div class="row mt-4">
    <div class="form-group col text-center">
      <button type="button" class="btn btn-outline-primary">Annulla</button>
      <button type="submit" class="btn btn-primary">Conferma</button>
    </div>
  </div>
</div>

Auto-dimensionamento

L’esempio seguente usa una delle utilità di flexbox per centrare verticalmente dal breakpoint lg in su il contenuto e cambiando .col con .col-auto in modo che le colonne occupino solo lo spazio necessario. In altre parole, la colonna si dimensiona in base al contenuto. È possibile usarlo anche quando sono presenti altre colonne con dimensioni specifiche (es.: col-sm-3).

@
<div class="row align-items-center">
  <div class="col-12 col-md-6 col-lg-auto mb-3">
    <label class="visually-hidden" for="inlineFormInput">Nome</label>
    <input type="text" class="form-control" id="inlineFormInput" placeholder="Mario Rossi">
  </div>
  <div class="col-12 col-md-6 col-lg-auto mb-3">
    <label class="visually-hidden" for="inlineFormInputGroup">Username</label>
    <div class="input-group">
      <div class="input-group-prepend">
        <div class="input-group-text">@</div>
      </div>
      <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
    </div>
  </div>
  <div class="col-6 col-md-3 offset-md-6 offset-lg-0 col-lg-auto">
    <div class="form-check m-0">
      <input class="form-check-input" type="checkbox" id="autoSizingCheck">
      <label class="form-check-label" for="autoSizingCheck">
        Ricordami
      </label>
    </div>
  </div>
  <div class="col-6 col-md-3 col-lg-auto d-flex justify-content-end">
    <button type="submit" class="btn btn-primary">Invia</button>
  </div>
</div>

Alternative alle etichette nascoste

Le tecnologie assistive come gli screenreader avranno problemi con i tuoi moduli se non includi un’etichetta per ogni input. Per questi moduli in linea, si può nascondere le etichette usando la classe .visually-hidden. Esistono altri metodi alternativi per fornire un’etichetta per le tecnologie assistive, come l’attributo aria-label, aria-labelledby o title. Se nessuno di questi è presente, le tecnologie assistive possono ricorrere all’uso dell’attributo placeholder, se presente, ma è sconsigliato.

Disabilitazione di campi

Aggiungi l’attributo booleano disabled su un input per impedire le interazioni dell’utente e renderlo più chiaro.

<input class="form-control" id="disabledInput" type="text" value="Esempio di input disabilitato" aria-label="Label" disabled>

Disabilitazione di un intero form

Aggiungi l’attributo disabled al <fieldset> per disabilitare tutti gli elementi del form contenuti.

Esempio di form disabilitato
<div>
  <fieldset disabled aria-label="Form disabilitato">
    <legend class="mb-4">Esempio di form disabilitato</legend>
      <div class="row mt-4">
        <div class="col-12 col-md-6">
          <div class="form-group">
            <label for="disabledFieldsetInput">Input </label>
            <input type="text" id="disabledFieldsetInput" class="form-control" value="Input disabilitato">
          </div>
        </div>
        <div class="col-12 col-md-6">
          <div class="form-group">
            <div class="select-wrapper">
              <label for="disabledFieldsetSelect">Select</label>
              <select id="disabledFieldsetSelect">
                <option value="Value 1">Select disabilitata</option>
                <option value="Value 2">Opzione 2</option>
                <option value="Value 3">Opzione 3</option>
                <option value="Value 4">Opzione 4</option>
                <option value="Value 5">Opzione 5</option>
              </select>
            </div>
          </div>
        </div>
      </div>
      <div class="row mb-4">
        <div class="col-12 col-md-6">
          <div class="form-check mb-3">
            <input class="form-check-input" type="checkbox" id="disabledFieldsetCheck1">
            <label class="form-check-label" for="disabledFieldsetCheck1">
              Check disabilitato 1
            </label>
          </div>
          <div class="form-check">
            <input class="form-check-input" type="checkbox" id="disabledFieldsetCheck2">
            <label class="form-check-label" for="disabledFieldsetCheck2">
              Check disabilitato 2
            </label>
          </div>
        </div>
        <div class="col-12 col-md-6">
          <div class="form-check">
            <input name="gruppo1" type="radio" id="disabledFieldsetRadio1" checked>
            <label for="disabledFieldsetRadio1">
              Radio disabilitato 1
            </label>
          </div>
          <div class="form-check">
            <input name="gruppo1" type="radio" id="disabledFieldsetRadio2">
            <label for="disabledFieldsetRadio2">
              Radio disabilitato 2
            </label>
          </div>
        </div>
      </div>
    <button class="btn btn-primary mt-3">Pulsante disabilitato</button>
  </fieldset>
</div>

Compatibilità Cross-browser

Mentre Bootstrap applicherà questi stili in tutti i browser, Internet Explorer 11 e successivi non supportano completamente l’attributo disabled nel <fieldset>. Utilizza codice JavaScript custom per disabilitare il fieldset in questi browser.

Validazione

Per la validazione dei forms è stato utilizzato il plugin Just Validate.

Come funziona

Per il funzionamento e le opzioni disponibili, si consiglia di consultare la documentazione.

Stili personalizzati

I campi che necessitano di validazione acquisiranno all’invio del form le classi CSS definite nello script che attiva il plugin. Nel nostro caso le classi saranno is-invalid e just-validate-success-field. I messaggi di errore avranno classe just-validate-error-label.

Di seguito un esempio di form validato con Just Validate.

<form class="needs-validation" id="justValidateForm">
  <div class="row mt-4">
    <div class="form-group col-md-3">
      <label class="active" for="validationCustom01">Nome</label>
      <input type="text" class="form-control" id="validationCustom01" value="Mario" required>
    </div>
    <div class="form-group col-md-3">
      <label class="active" for="validationCustom02">Cognome</label>
      <input type="text" class="form-control" id="validationCustom02" value="Rossi" required>
    </div>
    <div class="form-group col-md-3">
      <label for="validationCustomUsername">Username</label>
      <input type="text" class="form-control" id="validationCustomUsername" required>
    </div>
    <div class="form-group col-md-3">
      <label class="input-number-label active " for="validationAge">Età (minimo 18 anni)</label>
      <input type="number" data-bs-input class="form-control" id="validationAge" value="18" min="18" step="1" required>
    </div>
  </div>
  <div class="row">
    <div class="form-group col-md-6">
      <label for="validationCustom03">Città</label>
      <input type="text" class="form-control" id="validationCustom03" required>
    </div>
    <div class="form-group col-md-3">
      <label for="validationCustom04">Provincia</label>
      <input type="text" class="form-control" id="validationCustom04" required>
    </div>
    <div class="form-group col-md-3">
      <label for="validationCustom05">CAP (5 cifre)</label>
      <input type="text" class="form-control" id="validationCustom05" required>
    </div>
  </div>
  <div class="row align-items-center">
    <div class="col-md-9 col-lg-6">
      <div class="form-check mt-0">
        <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
        <label class="form-check-label" for="invalidCheck">Accetto i termini e le condizioni.</label>
      </div>
    </div>
    <div class="col-md-3 col-lg-6 mt-3 mt-md-0 d-flex justify-content-center justify-content-md-end justify-content-lg-start">
        <button class="btn btn-primary" type="submit">Invia</button>
    </div>
  </div>
</form>
<div class="row mt-4">
  <div class="col-12">
    <div aria-live="polite" id="errorMsgContainer"></div>
  </div>
</div>
<script>
  document.addEventListener("DOMContentLoaded", function() {
    const errorMessage = '<div class="alert alert-danger alert-dismissible fade show" role="alert"><strong>Attenzione</strong> Alcuni campi inseriti sono da controllare.<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Chiudi avviso">';
    const errorWrapper = document.querySelector('#errorMsgContainer');
    const validate = new bootstrap.FormValidate('#justValidateForm', {
      errorFieldCssClass: 'is-invalid',
      errorLabelCssClass: 'form-feedback',
      errorLabelStyle: '',
      focusInvalidField: false,
    })
    validate
      .addField('#validationCustom01', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
      ])
      .addField('#validationCustom02', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
      ])
      .addField('#validationCustom03', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
      ])
      .addField('#validationCustom04', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
      ])
      .addField('#validationCustomUsername', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
      ])
      .addField('#validationAge', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
        {
          rule: 'minNumber',
          value: 18,
          errorMessage: 'Deve essere maggiore di 17'
        },
      ])
      .addField('#validationCustom05', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
        {
          rule: 'minLength',
          value: 5,
          errorMessage: 'Inserire 5 cifre'
        },
        {
          rule: 'maxLength',
          value: 5,
          errorMessage: 'Inserire 5 cifre'
        },
        {
          rule: 'number',
          errorMessage: 'Inserire un numero'
        },
      ])
      .addField('#invalidCheck', [
        {
          rule: 'required',
          errorMessage: 'Questo campo è richiesto'
        },
      ])
      .onFail((fields) => {
        errorWrapper.innerHTML = '';
        errorWrapper.innerHTML = errorMessage
      })
  })
</script>
Continua la lettura

I singoli campi di tipo input, checkbox, radio, toggle, ecc. sono trattati in pagine separate della documentazione, continua a leggere alla pagina dedicata ai campi di input.