diff --git a/docs/esempi/form/index.html b/docs/esempi/form/index.html index c8a1368e93..a21cc90cd2 100644 --- a/docs/esempi/form/index.html +++ b/docs/esempi/form/index.html @@ -46,7 +46,7 @@

Campi input

- @@ -59,7 +59,7 @@

Campi input

- +
@@ -70,13 +70,30 @@

Campi input

+
+
+ + + + + + + + + +
+
- +
@@ -89,121 +106,123 @@

Autocomplete

-
- - +
+
+ + +
@@ -275,7 +294,7 @@

File

- +
@@ -344,6 +363,23 @@

File

rule: 'required', errorMessage: 'Questo campo è richiesto', }, + { + validator: (value) => { + return ['Alessandria', 'Bergamo', 'Piacenza'].includes(value); + }, + errorMessage: 'Puoi scegliere solo tra Alessandria, Piacenza o Bergamo', + }, + ]) + .addField('#importo_input_group', [ + { + rule: 'required', + errorMessage: 'Questo campo è richiesto', + }, + { + rule: 'minNumber', + value: 3.50, + errorMessage: 'Deve essere maggiore di 3.50', + } ]) .addField('#age', [ { diff --git a/docs/form/input-numerico.md b/docs/form/input-numerico.md index 88125dcc98..6e90215eb5 100644 --- a/docs/form/input-numerico.md +++ b/docs/form/input-numerico.md @@ -20,29 +20,37 @@ La larghezza del campo predefinita è quella del suo contenitore, per limitare l {% comment %}Example name: Base {% endcomment %} {% capture example %}
- - - - - - +
+ +
+ + + + + +
+
- - - - - - +
+ +
+ + + + + +
+
{% endcapture %}{% include example.html content=example %} @@ -53,16 +61,20 @@ Aggiungendo gli attributi HTML `min=""`, `max=""` e `step=""` all'input è possi {% comment %}Example name: Con limiti e incremento {% endcomment %} {% capture example %}
- - - - - - +
+ +
+ + + + + +
+
{% endcapture %}{% include example.html content=example %} @@ -72,17 +84,23 @@ Per anteporre il simbolo della valuta in Euro, aggiungere la classe `.input-numb {% comment %}Example name: Con valuta {% endcomment %} {% capture example %} +
- - - - - - +
+ +
+ + + + + + +
+
{% endcapture %}{% include example.html content=example %} @@ -95,16 +113,21 @@ Si consiglia di impostare gli attributi `min=0` e `max="100"`. {% comment %}Example name: Con percentuale {% endcomment %} {% capture example %}
- - - - - - +
+ +
+ % + + + + + +
+
{% endcapture %}{% include example.html content=example %} @@ -116,16 +139,20 @@ Aggiungere anche l'attributo `disabled` al campo e ai pulsanti. {% comment %}Example name: Disabilitato {% endcomment %} {% capture example %}
- - - - - - +
+ +
+ + + + + +
+
{% endcapture %}{% include example.html content=example %} @@ -138,16 +165,20 @@ sufficiente aggiungere la classe `input-number-adaptive`. {% comment %}Example name: Con ridimensionamento {% endcomment %} {% capture example %}
- - - - - - +
+ +
+ + + + + +
+
{% endcapture %}{% include example.html content=example %} diff --git a/docs/form/input.md b/docs/form/input.md index 296a4dacd5..04c6ba3212 100644 --- a/docs/form/input.md +++ b/docs/form/input.md @@ -517,7 +517,7 @@ Includendo l'elemento all'interno di un `.form-group`, la label assumerà lo ste {% capture example %}
- +
{% endcapture %}{% include example.html content=example %} diff --git a/src/js/plugins/input-number.js b/src/js/plugins/input-number.js index f3917e1493..6dac08880a 100644 --- a/src/js/plugins/input-number.js +++ b/src/js/plugins/input-number.js @@ -12,13 +12,12 @@ const DATA_API_KEY = '.data-api' const EVENT_CLICK = `click${EVENT_KEY}` const EVENT_CHANGE = `change${EVENT_KEY}` +const EVENT_INPUT = `input` //const EVENT_FOCUS_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY}` const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` const CLASS_NAME_ADAPTIVE = 'input-number-adaptive' -const CLASS_NAME_PERCENTAGE = 'input-number-percentage' -const CLASS_NAME_CURRENCY = 'input-number-currency' //const CLASS_NAME_INCREMENT = 'input-number-add' const CLASS_NAME_DECREMENT = 'input-number-sub' @@ -59,6 +58,7 @@ class InputNumber extends BaseComponent { EventHandler.on(btn, EVENT_CLICK, (evt) => { evt.preventDefault() this._incrDecr(btn.classList.contains(CLASS_NAME_DECREMENT)) + this._label._labelOut() }) }) @@ -70,14 +70,9 @@ class InputNumber extends BaseComponent { if (this._wrapperElement.classList.contains(CLASS_NAME_ADAPTIVE)) { let newWidth = null //let newWidthIE = null - if (!this._wrapperElement.classList.contains(CLASS_NAME_PERCENTAGE)) { - newWidth = 'calc(44px + ' + this._element.value.length + 'ch)' - //newWidthIE = 'calc(44px + (1.5 * ' + this._element.value.length + 'ch))' - } - if (this._wrapperElement.classList.contains(CLASS_NAME_CURRENCY)) { - newWidth = 'calc(40px + 44px + ' + this._element.value.length + 'ch)' - //newWidthIE = 'calc(40px + 44px + (1.5 * ' + this._element.value.length + 'ch))' - } + //74px - buttons (30px) and possible validation icon (40px) + newWidth = 'calc(70px + ' + this._element.value.length + 'ch)' + //newWidthIE = 'calc(44px + (1.5 * ' + this._element.value.length + 'ch))' if (newWidth) { this._element.style.width = newWidth @@ -87,7 +82,8 @@ class InputNumber extends BaseComponent { } _incrDecr(isDecr) { - const inputVal = parseFloat(this._element.value) + var inputVal = 0 + if (this._element.value !== '') inputVal = parseFloat(this._element.value) if (!isNaN(inputVal)) { //get step @@ -98,6 +94,7 @@ class InputNumber extends BaseComponent { this._element.value = inputVal + step * (isDecr ? -1 : 1) EventHandler.trigger(this._element, EVENT_CHANGE) + EventHandler.trigger(this._element, EVENT_INPUT) } } diff --git a/src/js/plugins/select-autocomplete.js b/src/js/plugins/select-autocomplete.js index 35e9017122..937ce70b39 100644 --- a/src/js/plugins/select-autocomplete.js +++ b/src/js/plugins/select-autocomplete.js @@ -3,14 +3,24 @@ import accessibleAutocomplete from 'accessible-autocomplete' import BaseComponent from 'bootstrap/js/src/base-component.js' const NAME = 'selectautocomplete' -//const DATA_KEY = 'bs.selectautocomplete' -//const EVENT_KEY = `.${DATA_KEY}` -//const DATA_API_KEY = '.data-api' + +function onClassChange(element, callback) { + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.type === 'attributes' && mutation.attributeName === 'class') { + callback(mutation.target) + } + }) + }) + observer.observe(element, { attributes: true }) + return observer.disconnect +} class SelectAutocomplete extends BaseComponent { constructor(element, config) { super(element) - + this._hasFormControl = element.classList.contains('form-control') + this.element_original_id = this._element.id this._config = config this._enhance() } @@ -21,11 +31,20 @@ class SelectAutocomplete extends BaseComponent { return NAME } - // Public - // Private _enhance() { accessibleAutocomplete.enhanceSelectElement(Object.assign({}, { selectElement: this._element }, this._config)) + setTimeout(() => { + if (this._hasFormControl) { + const inputField = document.getElementById(this.element_original_id) + inputField.classList.add('form-control') + onClassChange(inputField, (node) => { + if (!node.classList.contains('form-control')) { + node.classList.add('form-control') + } + }) + } + }, 100) } } diff --git a/src/scss/custom/_form-input-number.scss b/src/scss/custom/_form-input-number.scss index 1fcaad277c..5a8589fc12 100644 --- a/src/scss/custom/_form-input-number.scss +++ b/src/scss/custom/_form-input-number.scss @@ -1,10 +1,8 @@ .input-number { position: relative; - width: 100%; &.input-number-adaptive { - width: auto; - display: inline; + width: fit-content; input[type='number'] { width: auto; transition: all 0.3s; @@ -23,80 +21,49 @@ } // color: $color-text-muted; - padding-right: 32px; - padding-left: 12px; - min-width: 86px !important; - width: 100%; &:focus { color: $color-text-base; } } - //currency + percentage version - &.input-number-currency, - &.input-number-percentage { - &:before { - position: absolute; - left: 14px; - top: 0; - // color: $color-text-muted; - font-weight: bold; - font-size: 1rem; - } - input[type='number'] { - padding-left: 40px; - } - } - &.input-number-currency { - &:before { - content: '€'; - } - } - &.input-number-percentage { - &:before { - content: '%'; - } - } - //disabled version &.disabled { input[type='number'] { - background-color: transparent; - color: $gray-label-disabled; - border-bottom-color: $gray-border-disabled; + background-color: $gray-disabled; + color: $gray-800; &:hover { cursor: not-allowed; color: $gray-label-disabled; } } - button { - pointer-events: none; - &:hover { - cursor: not-allowed; - } - &.input-number-add { - &:after { - border-color: transparent transparent $gray-border-disabled transparent; - } - } - &.input-number-sub { - &:after { - border-color: $gray-border-disabled transparent transparent transparent; + .input-group-text { + background-color: $gray-disabled; + color: $gray-800; + button { + pointer-events: none; + &:hover { + cursor: not-allowed; } } } } //add + sub buttons - button { + .input-group-text.align-buttons { position: absolute; - right: 2px; + top: 0; + bottom: 0; + right: 0; + z-index: 10; + } + .input-group-text button { + position: relative; transition: opacity 0.1s; padding: 0; border: none; - height: 20px; - width: 24px; + height: 50%; + width: 16px; background: transparent; &:after { position: absolute; @@ -126,14 +93,12 @@ } &.input-number-add { - top: -6px; &:after { border-width: 0 5px 6px 5px; border-color: transparent transparent $neutral-1-a7 transparent; // TODO Check if still necessary } } &.input-number-sub { - bottom: -6px; &:after { border-width: 6px 5px 0 5px; border-color: $neutral-1-a7 transparent transparent transparent; // TODO Check if still necessary diff --git a/src/scss/custom/_forms.scss b/src/scss/custom/_forms.scss index 0b3e02427c..0f9ea51fe7 100644 --- a/src/scss/custom/_forms.scss +++ b/src/scss/custom/_forms.scss @@ -59,6 +59,13 @@ fieldset { font-size: $small-font-size; color: $input-label-color; } + &:not(.active) { + & + .input-number-currency { + .input-group-text { + display: none; + } + } + } } input:is([type='radio']), @@ -100,7 +107,6 @@ textarea { border-radius: 0; padding: $input-spacing-y $input-spacing-x; outline: 0; - height: $input-height; width: 100%; box-shadow: none; transition: none; @@ -188,7 +194,7 @@ textarea { .input-group-text { padding: $input-spacing-y $input-spacing-x; border-bottom: 1px solid $input-border; - height: 100%; + border-radius: 0; } .input-group-prepend { diff --git a/src/scss/custom/_just-validate.scss b/src/scss/custom/_just-validate.scss index f12e4f0044..c7f734cefb 100644 --- a/src/scss/custom/_just-validate.scss +++ b/src/scss/custom/_just-validate.scss @@ -7,6 +7,24 @@ color: #d9364f; } } + +.input-group-text:has(+ .focus--mouse:not(.btn)), +.focus--mouse:not(.btn) + .input-group-text, +button:has(~ .focus--mouse:not(.btn)), +.focus--mouse:not(.btn) + button { + border-color: inherit !important; + box-shadow: none !important; + outline: none !important; +} + +//same border color for element in input-group +.input-group-text:has(+ .is-invalid), +.is-invalid + .input-group-text, +button:has(~ .is-invalid), +.is-invalid + button { + border-color: #d9364f; +} + .sr-only-justvalidate-bi { display: none; } @@ -15,20 +33,41 @@ padding-right: calc(1.5em + 0.75rem) !important; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2300cc85' viewBox='0 0 192 512'%3E%3Cpath d='M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z'/%3E%3C/svg%3E"); } -textarea { - &.just-validate-success-field { - background-position: right 0.2rem !important; - background-repeat: no-repeat !important; - background-size: 28px 16px !important; +.input-group-text:has(+ .just-validate-success-field), +.just-validate-success-field + .input-group-text, +button:has(~ .just-validate-success-field), +.just-validate-success-field + button { + border-color: #008758; +} + +//move buttons to make validation icon visible +.just-validate-success-field + .input-group-text.align-buttons, +.is-invalid + .input-group-text.align-buttons { + right: 30px; +} + +.is-invalid + .input-group-text.align-buttons { + bottom: 22px; //height of the form-feedback element +} + +.autocomplete__wrapper { + .form-feedback.just-validate-error-label { + position: absolute; } } -input[type='date'], -input[type='file'], -input[type='text'] { + +textarea { + &.form-control { + background-position: top 0.3em right 0.3em !important; + background-size: 37px 30% !important; + } + &.is-invalid { + border-bottom-style: solid; + border-bottom-width: 1px; + } &.just-validate-success-field { - background-repeat: no-repeat; - background-size: 37px 21px; - background-position: right center; + border-bottom-style: solid; + border-bottom-width: 1px; } } input[type='date'] { @@ -36,9 +75,6 @@ input[type='date'] { border-bottom: 1px solid #d9364f; padding-right: calc(1.5em + 0.75rem) !important; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23f73e5a' viewBox='0 0 384 512'%3E%3Cpath d='M231.6 256l130.1-130.1c4.7-4.7 4.7-12.3 0-17l-22.6-22.6c-4.7-4.7-12.3-4.7-17 0L192 216.4 61.9 86.3c-4.7-4.7-12.3-4.7-17 0l-22.6 22.6c-4.7 4.7-4.7 12.3 0 17L152.4 256 22.3 386.1c-4.7 4.7-4.7 12.3 0 17l22.6 22.6c4.7 4.7 12.3 4.7 17 0L192 295.6l130.1 130.1c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17L231.6 256z'/%3E%3C/svg%3E"); - background-repeat: no-repeat; - background-size: 37px 21px; - background-position: right center; } } input[type='checkbox'], @@ -54,9 +90,6 @@ select { border-bottom: 1px solid #d9364f; } &.just-validate-success-field { - background-repeat: no-repeat; - background-size: 77px 21px; - background-position: right center; border-bottom: 1px solid #008758; } }