Flutter:如何基于API返回的掩码实现可正常输入的输入框掩码功能
动态根据API返回掩码实现输入框格式化(解决输入异常问题)
场景说明
我的应用通过API获取字段配置,配置里包含用户选择的掩码规则(比如CEP的99999-999、CPF/CNPJ等),需要给对应输入框自动套上格式。但当前实现有问题:点击输入框按键时根本输不了内容,反而直接把完整的掩码字符串99999-999插进去了,得改成正常的掩码输入——用户输数字时自动补充分隔符,而不是直接替换整个输入值。
API返回的配置示例:
{ "id": 26934, "label": "Campo de Texto - Com Máscara", "required": true, "type": "T", "mascara": "99999-999", "formatacao": "S", "format": "S", "originalFormat": "S", "html5Input": false, "codcampodinamico": 26934, "fieldSize": "M", "value": null, "values": [] }
问题根源
之前的实现应该是直接把掩码字符串赋值给输入框,或者监听输入事件时错误地用掩码覆盖了用户输入,没有区分掩码里的固定分隔符和数字占位符,导致每次按键都被完整掩码替换,根本没法输入实际内容。
解决方案
核心逻辑是:只保留用户输入的数字,然后按照掩码模板的规则,把数字填充到9的位置,其他固定分隔符直接保留,同时处理光标位置避免跳转。
实现代码
HTML
<input type="text" id="maskedField" placeholder="Digite o valor">
JavaScript
// 模拟从API获取的字段配置 const fieldConfig = { "id": 26934, "label": "Campo de Texto - Com Máscara", "required": true, "type": "T", "mascara": "99999-999", "formatacao": "S", "format": "S", "originalFormat": "S", "html5Input": false, "codcampodinamico": 26934, "fieldSize": "M", "value": null, "values": [] }; const input = document.getElementById('maskedField'); const maskPattern = fieldConfig.mascara; // 通用掩码处理函数 function setupInputMask(inputElem, mask) { inputElem.addEventListener('input', function(e) { // 过滤出用户输入的纯数字 const rawNumbers = this.value.replace(/\D/g, ''); let formattedValue = ''; let numIndex = 0; // 遍历掩码模板,拼接格式化后的内容 for (const char of mask) { if (numIndex >= rawNumbers.length) break; if (char === '9') { // 占位符,填充用户输入的数字 formattedValue += rawNumbers[numIndex]; numIndex++; } else { // 固定分隔符,直接添加 formattedValue += char; } } // 保存光标位置,避免格式化后光标跳走 const cursorPos = this.selectionStart; this.value = formattedValue; // 保持光标位置一致(如果光标在分隔符前,自动跳到后面) this.setSelectionRange(cursorPos, cursorPos); }); // 设置占位符提示(可选,让用户直观看到格式) inputElem.placeholder = mask.replace(/9/g, '_'); } // 给输入框应用掩码 setupInputMask(input, maskPattern);
关键说明
- 过滤有效字符:用
replace(/\D/g, '')把用户输入的非数字全部去掉,只保留需要填充的数字。 - 掩码拼接逻辑:遍历掩码模板,遇到
9就取用户输入的下一个数字,其他字符直接保留,确保格式和掩码一致。 - 光标位置处理:格式化后重置光标位置,避免用户输入时光标突然跳到末尾,提升体验。
- 通用性:不管是CEP、CPF还是CNPJ的掩码,只要用
9表示数字占位符,其他字符为分隔符,这个函数都能直接适配。
内容的提问来源于stack exchange,提问作者Natan
相关产品推荐
相关产品推荐

