【问题标题】:How to validate pattern matching in textarea?如何验证文本区域中的模式匹配?
【发布时间】:2023-03-28 13:40:01
【问题描述】:

当我在 javascript 中使用 textarea.checkValidity() 或 textarea.validity.valid 且值无效时,两者总是返回 true,我做错了什么?

<textarea name="test" pattern="[a-z]{1,30}(,[a-z]{1,30})*" id="test"></textarea>​

jQuery('#test').on('keyup', function() {
    jQuery(this).parent().append('<p>' + this.checkValidity() + ' ' +
    this.validity.patternMismatch + '</p>');
});

http://jsfiddle.net/Riesling/jbtRU/9/

【问题讨论】:

标签: html textarea


【解决方案1】:

HTML5 &lt;textarea&gt; 元素不支持 pattern 属性。

查看MDN doc 以了解允许的&lt;textarea&gt; 属性。

您可能需要自己定义此功能。

或者按照定义 JavaScript/jQuery 函数的传统 HTML 4 做法来执行此操作。

【讨论】:

    【解决方案2】:

    您可以使用setCustomValidity() 自己实现此功能。 这样,this.checkValidity() 将回复您想要应用于您的元素的任何规则。 我不认为this.validity.patternMismatch 可以手动设置,但如果需要,您可以使用自己的属性。

    http://jsfiddle.net/yanndinendal/jbtRU/22/

    $('#test').keyup(validateTextarea);
    
    function validateTextarea() {
        var errorMsg = "Please match the format requested.";
        var textarea = this;
        var pattern = new RegExp('^' + $(textarea).attr('pattern') + '$');
        // check each line of text
        $.each($(this).val().split("\n"), function () {
            // check if the line matches the pattern
            var hasError = !this.match(pattern);
            if (typeof textarea.setCustomValidity === 'function') {
                textarea.setCustomValidity(hasError ? errorMsg : '');
            } else {
                // Not supported by the browser, fallback to manual error display...
                $(textarea).toggleClass('error', !!hasError);
                $(textarea).toggleClass('ok', !hasError);
                if (hasError) {
                    $(textarea).attr('title', errorMsg);
                } else {
                    $(textarea).removeAttr('title');
                }
            }
            return !hasError;
        });
    }
    

    【讨论】:

    • 很好的答案,感谢您的提琴。它帮助了我!
    • 谢谢,很高兴能帮上忙。 :)
    【解决方案3】:

    这将启用 DOM 中所有文本区域的 pattern 属性并触发 Html5 验证。它还考虑了具有^$ 运算符的模式,并使用g 正则表达式标志进行全局匹配:

    $( document ).ready( function() {
        var errorMessage = "Please match the requested format.";
    
        $( this ).find( "textarea" ).on( "input change propertychange", function() {
    
            var pattern = $( this ).attr( "pattern" );
    
            if(typeof pattern !== typeof undefined && pattern !== false)
            {
                var patternRegex = new RegExp( "^" + pattern.replace(/^\^|\$$/g, '') + "$", "g" );
    
                hasError = !$( this ).val().match( patternRegex );
    
                if ( typeof this.setCustomValidity === "function") 
                {
                    this.setCustomValidity( hasError ? errorMessage : "" );
                } 
                else 
                {
                    $( this ).toggleClass( "error", !!hasError );
                    $( this ).toggleClass( "ok", !hasError );
    
                    if ( hasError ) 
                    {
                        $( this ).attr( "title", errorMessage );
                    } 
                    else
                    {
                        $( this ).removeAttr( "title" );
                    }
                }
            }
    
        });
    });
    

    【讨论】:

    • 是的,这样更干净。 :) 实际上,输入中的模式属性允许在正则表达式中使用 ^$,即使它们是隐式的。
    • ^ 和 $ 替换不起作用。它应该是全局(带 /g)正则表达式(带斜杠),而不是字符串中的正则表达式:var patternRegex = new RegExp('^' + pattern.replace(/^\^|\$$/g, '') + '$', 'g');
    • 我试图让它在每行寻找电子邮件地址的小提琴上工作。我能做的最好的事情是添加一个 m 修饰符,然后如果 ANY 行上有一个电子邮件地址,它就会匹配。仍然不是我想要的。 Yann 上面的第一个示例运行正常。您将如何使用这种方法来解决问题?这是我创建的小提琴:jsfiddle.net/da1hg19e
    • @YannDìnendal 完全同意,我相应地修改了代码。 @BrianLayman 您绝对可以使用m 多行自定义标志,但这也可以通过利用 \n\r 符号来编写正则表达式来实现
    • 似乎使用 HTML 实体是解决方法。代替[^'"],使用[^&amp;apos;&amp;quot;]
    【解决方案4】:

    如果有其他人使用 React-Bootstrap HTML 表单验证而不是 jQuery。

    这并没有明确使用pattern,但它的工作方式相同。

    我只是对documentation 进行了一些更改。

    function FormExample() {
      const [validated, setValidated] = useState(false);
      const [textArea, setTextArea] = useState('');
      const textAreaRef = useRef(null);
    
      const handleSubmit = (event) => {
        const form = event.currentTarget;
        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
    
        setValidated(true);
      };
    
      const isValid = () => {
        // Put whichever logic or regex check to determine if it's valid
        return true;
      };
    
      useEffect(() => {
        textAreaRef.current.setCustomValidity(isValid() ? '' : 'Invalid');
        // Shows the error message if it's invalid, remove this if you don't want to show
        textAreaRef.current.reportValidity();
      }, [textArea];
    
      return (
        <Form noValidate validated={validated} onSubmit={handleSubmit}>
          <Form.Row>
            <Form.Group md="4" controlId="validationCustom01">
              <Form.Label>Text area</Form.Label>
              <Form.Control
                required
                as="textarea"
                ref={textAreaRef}
                placeholder="Text area"
                value={textArea}
                onChange={(e) => setTextArea(e.target.value)}
              />
              <Form.Control.Feedback>Looks good!</Form.Control.Feedback>
            </Form.Group>
          </Form.Row>
          <Button type="submit">Submit form</Button>
        </Form>
      );
    }
    
    render(<FormExample />);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 2011-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多