]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Restore feedback icons on validated form fields
authorMark Otto <markdotto@gmail.com>
Sun, 8 Jul 2018 22:31:18 +0000 (15:31 -0700)
committerMark Otto <markdotto@gmail.com>
Sun, 8 Jul 2018 22:31:18 +0000 (15:31 -0700)
- Only applies to textual inputs and textareas with `.form-control` and selects with `.custom-select`
- Wrap the feedback icons in a Sass variable option, $enable-validation-icons, so folks who theme can disable
- Update docs to summarize styles, mention the icons, include a textarea demo, and add mention of the Sass variable option to the Theming section

docs/4.1/components/forms.md
docs/4.1/getting-started/theming.md
scss/_custom-forms.scss
scss/_variables.scss
scss/mixins/_forms.scss

index e55f58f4de864e94b7357ce2cfd74b6bccb1fea4..3ca83b20961e490ecd850511f65458cb3d1cfb86 100644 (file)
@@ -767,9 +767,9 @@ With that in mind, consider the following demos for our custom form validation s
 
 ### Custom styles
 
-For custom Bootstrap form validation messages, you'll need to add the `novalidate` boolean attribute to your `<form>`. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; our JavaScript will intercept the submit button and relay feedback to you.
+For custom Bootstrap form validation messages, you'll need to add the `novalidate` boolean attribute to your `<form>`. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; our JavaScript will intercept the submit button and relay feedback to you. When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls.
 
-When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls.
+Custom feedback styles apply custom colors, borders, focus styles, and background icons to better communicate feedback. Background icons for `<select>`s are only available with `.custom-select`, and not `.form-control`.
 
 {% capture example %}
 <form class="needs-validation" novalidate>
@@ -990,10 +990,18 @@ We recommend using client side validation, but in case you require server side,
 
 ### Supported elements
 
-Our example forms show native textual `<input>`s above, but form validation styles are available for our custom form controls, too.
+Our example forms show native textual `<input>`s above, but form validation styles are also available for `<textarea>`s and custom form controls.
 
 {% capture example %}
 <form class="was-validated">
+  <div class="mb-3">
+    <label for="validationTextarea">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="custom-control custom-checkbox mb-3">
     <input type="checkbox" class="custom-control-input" id="customControlValidation1" required>
     <label class="custom-control-label" for="customControlValidation1">Check this custom checkbox</label>
index 192e819bcff57b8ebe282abbdc2fb467c62b88e0..1c7106dee79b4abdc0fa6b11723e53d2cef3a50c 100644 (file)
@@ -241,6 +241,7 @@ You can find and customize these variables for key global options in Bootstrap's
 | `$enable-grid-classes`      | `true` (default) or `false`        | Enables the generation of CSS classes for the grid system (e.g., `.container`, `.row`, `.col-md-1`, etc.). |
 | `$enable-caret`             | `true` (default) or `false`        | Enables pseudo element caret on `.dropdown-toggle`. |
 | `$enable-print-styles`      | `true` (default) or `false`        | Enables styles for optimizing printing. |
+| `$enable-validation-icons`  | `true` (default) or `false`        | Enables `background-image` icons within textual inputs and some custom forms for validation states. |
 
 ## Color
 
index 1311ba482c6dc94fea71215c81cec1da098ef7b9..b021b908c0c2669bbca9f23af988adc33360c07d 100644 (file)
   line-height: $custom-select-line-height;
   color: $custom-select-color;
   vertical-align: middle;
-  background: $custom-select-bg $custom-select-indicator no-repeat right $custom-select-padding-x center;
-  background-size: $custom-select-bg-size;
+  background: $custom-select-background;
+  background-color: $custom-select-bg;
   border: $custom-select-border-width solid $custom-select-border-color;
   @if $enable-rounded {
     border-radius: $custom-select-border-radius;
index 6531a934f78cee13d53c85138d19ff83d57289d5..9d6565d992e4b33e1c358df1a43e11a3a58f8c0e 100644 (file)
@@ -117,7 +117,7 @@ $enable-transitions:        true !default;
 $enable-hover-media-query:  false !default; // Deprecated, no longer affects any compiled CSS
 $enable-grid-classes:       true !default;
 $enable-print-styles:       true !default;
-
+$enable-validation-icons:   true !default;
 
 // Spacing
 //
@@ -515,6 +515,8 @@ $custom-select-disabled-bg:         $gray-200 !default;
 $custom-select-bg-size:             8px 10px !default; // In pixels because image dimensions
 $custom-select-indicator-color:     $gray-800 !default;
 $custom-select-indicator:           str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E"), "#", "%23") !default;
+$custom-select-background:          $custom-select-indicator no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
+
 $custom-select-border-width:        $input-btn-border-width !default;
 $custom-select-border-color:        $input-border-color !default;
 $custom-select-border-radius:       $border-radius !default;
@@ -574,6 +576,11 @@ $form-feedback-font-size:           $small-font-size !default;
 $form-feedback-valid-color:         theme-color("success") !default;
 $form-feedback-invalid-color:       theme-color("danger") !default;
 
+$form-feedback-icon-valid-color:    $form-feedback-valid-color !default;
+$form-feedback-icon-valid:          str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath 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'/%3E%3C/svg%3E"), "#", "%23") !default;
+$form-feedback-icon-invalid-color:  $form-feedback-invalid-color !default;
+$form-feedback-icon-invalid:        str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-feedback-icon-invalid-color}' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E"), "#", "%23") !default;
+
 
 // Dropdowns
 //
@@ -670,6 +677,7 @@ $navbar-light-disabled-color:       rgba($black, .3) !default;
 $navbar-light-toggler-icon-bg:      str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default;
 $navbar-light-toggler-border-color: rgba($black, .1) !default;
 
+
 // Pagination
 
 $pagination-padding-y:              .5rem !default;
index 3db995e014a7483e784234f4497f9f4e692947c5..49e6303d55f515f8eec787a306bafa65a039da23 100644 (file)
     border-radius: .2rem;
   }
 
-  .form-control,
+  .form-control {
+    .was-validated &:#{$state},
+    &.is-#{$state} {
+      border-color: $color;
+
+      @if $enable-validation-icons {
+        padding-right: $input-height-inner;
+        background-repeat: no-repeat;
+        background-position: center right calc(#{$input-height-inner} / 4);
+        background-size: calc(#{$input-height-inner} / 2) calc(#{$input-height-inner} / 2);
+
+        @if $state == "valid" {
+          background-image: $form-feedback-icon-valid;
+        } @else {
+          background-image: $form-feedback-icon-invalid;
+        }
+      }
+
+      &:focus {
+        border-color: $color;
+        box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
+      }
+
+      ~ .#{$state}-feedback,
+      ~ .#{$state}-tooltip {
+        display: block;
+      }
+    }
+  }
+
+  textarea.form-control {
+    .was-validated &:#{$state},
+    &.is-#{$state} {
+      @if $enable-validation-icons {
+        padding-right: $input-height-inner;
+        background-position: top calc(#{$input-height-inner} / 4) right calc(#{$input-height-inner} / 4);
+      }
+    }
+  }
+
   .custom-select {
     .was-validated &:#{$state},
     &.is-#{$state} {
       border-color: $color;
 
+      @if $enable-validation-icons {
+        padding-right: $input-height-inner;
+
+        @if $state == "valid" {
+          background: $custom-select-background, $form-feedback-icon-valid no-repeat center right ($input-height-inner * .9) / calc(#{$input-height-inner} / 2) calc(#{$input-height-inner} / 2);
+        } @else {
+          background: $custom-select-background, $form-feedback-icon-invalid no-repeat center right ($input-height-inner * .9) / calc(#{$input-height-inner} / 2) calc(#{$input-height-inner} / 2);
+        }
+      }
+
       &:focus {
         border-color: $color;
         box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
     }
   }
 
+
   .form-control-file {
     .was-validated &:#{$state},
     &.is-#{$state} {