You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

关键说明

  1. 过滤有效字符:用replace(/\D/g, '')把用户输入的非数字全部去掉,只保留需要填充的数字。
  2. 掩码拼接逻辑:遍历掩码模板,遇到9就取用户输入的下一个数字,其他字符直接保留,确保格式和掩码一致。
  3. 光标位置处理:格式化后重置光标位置,避免用户输入时光标突然跳到末尾,提升体验。
  4. 通用性:不管是CEP、CPF还是CNPJ的掩码,只要用9表示数字占位符,其他字符为分隔符,这个函数都能直接适配。

内容的提问来源于stack exchange,提问作者Natan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 21:00:38