@@ -475,6 +475,15 @@ const getMultipleCheckboxValue = (element, currentValues) => {
475475 return finalValues ;
476476} ;
477477const inputValue = ( element ) => element . dataset . value ? element . dataset . value : element . value ;
478+ function isTextualInputElement ( el ) {
479+ return el instanceof HTMLInputElement && [ 'text' , 'email' , 'password' , 'search' , 'tel' , 'url' ] . includes ( el . type ) ;
480+ }
481+ function isTextareaElement ( el ) {
482+ return el instanceof HTMLTextAreaElement ;
483+ }
484+ function isNumericalInputElement ( element ) {
485+ return element instanceof HTMLInputElement && [ 'number' , 'range' ] . includes ( element . type ) ;
486+ }
478487
479488class HookManager {
480489 constructor ( ) {
@@ -2343,6 +2352,10 @@ function getModelBinding (modelDirective) {
23432352 let shouldRender = true ;
23442353 let targetEventName = null ;
23452354 let debounce = false ;
2355+ let minLength = null ;
2356+ let maxLength = null ;
2357+ let minValue = null ;
2358+ let maxValue = null ;
23462359 modelDirective . modifiers . forEach ( ( modifier ) => {
23472360 switch ( modifier . name ) {
23482361 case 'on' :
@@ -2360,6 +2373,18 @@ function getModelBinding (modelDirective) {
23602373 case 'debounce' :
23612374 debounce = modifier . value ? Number . parseInt ( modifier . value ) : true ;
23622375 break ;
2376+ case 'min_length' :
2377+ minLength = modifier . value ? Number . parseInt ( modifier . value ) : null ;
2378+ break ;
2379+ case 'max_length' :
2380+ maxLength = modifier . value ? Number . parseInt ( modifier . value ) : null ;
2381+ break ;
2382+ case 'min_value' :
2383+ minValue = modifier . value ? Number . parseFloat ( modifier . value ) : null ;
2384+ break ;
2385+ case 'max_value' :
2386+ maxValue = modifier . value ? Number . parseFloat ( modifier . value ) : null ;
2387+ break ;
23632388 default :
23642389 throw new Error ( `Unknown modifier "${ modifier . name } " in data-model="${ modelDirective . getString ( ) } ".` ) ;
23652390 }
@@ -2371,6 +2396,10 @@ function getModelBinding (modelDirective) {
23712396 shouldRender,
23722397 debounce,
23732398 targetEventName,
2399+ minLength,
2400+ maxLength,
2401+ minValue,
2402+ maxValue,
23742403 } ;
23752404}
23762405
@@ -3153,6 +3182,27 @@ class LiveControllerDefault extends Controller {
31533182 }
31543183 }
31553184 const finalValue = getValueFromElement ( element , this . component . valueStore ) ;
3185+ if ( isTextualInputElement ( element ) || isTextareaElement ( element ) ) {
3186+ if ( modelBinding . minLength !== null &&
3187+ typeof finalValue === 'string' &&
3188+ finalValue . length < modelBinding . minLength ) {
3189+ return ;
3190+ }
3191+ if ( modelBinding . maxLength !== null &&
3192+ typeof finalValue === 'string' &&
3193+ finalValue . length > modelBinding . maxLength ) {
3194+ return ;
3195+ }
3196+ }
3197+ if ( isNumericalInputElement ( element ) ) {
3198+ const numericValue = Number ( finalValue ) ;
3199+ if ( modelBinding . minValue !== null && numericValue < modelBinding . minValue ) {
3200+ return ;
3201+ }
3202+ if ( modelBinding . maxValue !== null && numericValue > modelBinding . maxValue ) {
3203+ return ;
3204+ }
3205+ }
31563206 this . component . set ( modelBinding . modelName , finalValue , modelBinding . shouldRender , modelBinding . debounce ) ;
31573207 }
31583208 dispatchEvent ( name , detail = { } , canBubble = true , cancelable = false ) {
0 commit comments