@@ -475,6 +475,15 @@ const getMultipleCheckboxValue = (element, currentValues) => {
475
475
return finalValues ;
476
476
} ;
477
477
const 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
+ }
478
487
479
488
class HookManager {
480
489
constructor ( ) {
@@ -2343,6 +2352,10 @@ function getModelBinding (modelDirective) {
2343
2352
let shouldRender = true ;
2344
2353
let targetEventName = null ;
2345
2354
let debounce = false ;
2355
+ let minLength = null ;
2356
+ let maxLength = null ;
2357
+ let minValue = null ;
2358
+ let maxValue = null ;
2346
2359
modelDirective . modifiers . forEach ( ( modifier ) => {
2347
2360
switch ( modifier . name ) {
2348
2361
case 'on' :
@@ -2360,6 +2373,18 @@ function getModelBinding (modelDirective) {
2360
2373
case 'debounce' :
2361
2374
debounce = modifier . value ? Number . parseInt ( modifier . value ) : true ;
2362
2375
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 ;
2363
2388
default :
2364
2389
throw new Error ( `Unknown modifier "${ modifier . name } " in data-model="${ modelDirective . getString ( ) } ".` ) ;
2365
2390
}
@@ -2371,6 +2396,10 @@ function getModelBinding (modelDirective) {
2371
2396
shouldRender,
2372
2397
debounce,
2373
2398
targetEventName,
2399
+ minLength,
2400
+ maxLength,
2401
+ minValue,
2402
+ maxValue,
2374
2403
} ;
2375
2404
}
2376
2405
@@ -3153,6 +3182,27 @@ class LiveControllerDefault extends Controller {
3153
3182
}
3154
3183
}
3155
3184
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
+ }
3156
3206
this . component . set ( modelBinding . modelName , finalValue , modelBinding . shouldRender , modelBinding . debounce ) ;
3157
3207
}
3158
3208
dispatchEvent ( name , detail = { } , canBubble = true , cancelable = false ) {
0 commit comments