ทริกเกอร์การตรวจสอบฟอร์มด้วยตนเองโดยใช้ jQuery


106

ฉันมีแบบฟอร์มที่มีชุดฟิลด์ต่างๆ ฉันมี jQuery บางตัวที่แสดงชุดฟิลด์ให้กับผู้ใช้ทีละคน สำหรับเบราว์เซอร์ที่รองรับการตรวจสอบ HTML5 ฉันชอบที่จะใช้ประโยชน์จากมัน อย่างไรก็ตามฉันต้องทำตามเงื่อนไขของฉัน ฉันใช้ JQuery

เมื่อผู้ใช้คลิกลิงก์ JS เพื่อย้ายไปยังชุดฟิลด์ถัดไปฉันต้องการการตรวจสอบความถูกต้องเพื่อให้เกิดขึ้นในชุดฟิลด์ปัจจุบันและบล็อกผู้ใช้ไม่ให้ก้าวไปข้างหน้าหากมีปัญหา

ตามหลักการแล้วเมื่อผู้ใช้สูญเสียโฟกัสไปที่องค์ประกอบการตรวจสอบความถูกต้องจะเกิดขึ้น

ขณะนี้มี novalidate ไปและใช้ jQuery ต้องการใช้วิธีดั้งเดิม :)

คำตอบ:


62

คุณไม่สามารถทริกเกอร์ UI การตรวจสอบความถูกต้องดั้งเดิม (ดูแก้ไขด้านล่าง) แต่คุณสามารถใช้ประโยชน์จาก API การตรวจสอบความถูกต้องกับองค์ประกอบอินพุตที่กำหนดเองได้อย่างง่ายดาย:

$('input').blur(function(event) {
    event.target.checkValidity();
}).bind('invalid', function(event) {
    setTimeout(function() { $(event.target).focus();}, 50);
});

เหตุการณ์แรกเริ่มทำงานcheckValidityในทุกองค์ประกอบอินพุตทันทีที่สูญเสียโฟกัสหากองค์ประกอบinvalidนั้นเป็นเช่นนั้นเหตุการณ์ที่เกี่ยวข้องจะถูกยิงและถูกดักจับโดยตัวจัดการเหตุการณ์ที่สอง สิ่งนี้ตั้งค่าโฟกัสกลับไปที่องค์ประกอบ แต่อาจเป็นเรื่องที่น่ารำคาญฉันคิดว่าคุณมีทางออกที่ดีกว่าสำหรับการแจ้งข้อผิดพลาด นี่เป็นตัวอย่างการทำงานของรหัสของฉันข้างต้น

แก้ไข:เบราว์เซอร์ที่ทันสมัยทั้งหมดสนับสนุนreportValidity()วิธีการสำหรับการตรวจสอบ HTML5 พื้นเมืองต่อคำตอบนี้


20
โกลเด้นประโยค"คุณไม่สามารถเรียกตรวจสอบ UI พื้นเมือง" ในกรณีของฉัน (เทคนิค JS ที่กำหนดเอง + การตรวจสอบความถูกต้องของเบราว์เซอร์ html5 + เคล็ดลับเครื่องมือ UI) ฉันไม่มีทางเลือกอื่นนอกจากไปที่ปุ่มส่งที่ซ่อนอยู่ในตอนท้ายเพื่อรับทั้งสองอย่าง
lukmdo

23
หากแบบฟอร์มของคุณไม่มีปุ่มส่งคุณสามารถปลอมได้:$('<input type="submit">').hide().appendTo($myForm).click().remove();
philfreo

1
@philfreo จะform.submit()ทำงานได้ดีไม่ใช่เหรอ? หรือ HTML5 ต้องการปุ่มส่งสำหรับการตรวจสอบความถูกต้องในตอนนี้?
Mattisdada

@Mattisdada การโทร.submit()ไม่ทำงานสำหรับฉัน โซลูชันของ @ philfreo ใช้ได้ผล อืม.
Zero3

8
เพียงแค่เตือนว่าcheckValidityการตรวจสอบเพียง แต่ไม่ป๊อปอัพคำใบ้มาตรฐานเบราว์เซอร์ หากคุณต้องการป๊อปอัปด้วย - ใช้element.reportValidity()
Alex

152

TL; DR:ไม่สนใจเบราว์เซอร์เก่าใช่ไหม ใช้form.reportValidity().

ต้องการการสนับสนุนเบราว์เซอร์เดิมหรือไม่ อ่านต่อ.


มันจริงเป็นไปได้ที่จะตรวจสอบด้วยตนเองทริกเกอร์

ฉันจะใช้ JavaScript ธรรมดาในคำตอบของฉันเพื่อปรับปรุงการนำกลับมาใช้ใหม่ไม่จำเป็นต้องใช้ jQuery


สมมติรูปแบบ HTML ต่อไปนี้:

<form>
  <input required>
  <button type="button">Trigger validation</button>
</form>

และมาคว้าองค์ประกอบ UI ของเราใน JavaScript:

var form = document.querySelector('form')
var triggerButton = document.querySelector('button')

ไม่ต้องการการสนับสนุนสำหรับเบราว์เซอร์เดิมเช่น Internet Explorer ใช่หรือไม่ นี่ของคุณ.

เบราว์เซอร์ที่ทันสมัยทั้งหมดสนับสนุนreportValidity()วิธีการเกี่ยวกับformองค์ประกอบ

triggerButton.onclick = function () {
    form.reportValidity()
}

เท่านี้เราก็เสร็จแล้ว นอกจากนี้นี่คือ CodePen ง่ายๆโดยใช้แนวทางนี้


แนวทางสำหรับเบราว์เซอร์รุ่นเก่า

ด้านล่างนี้คือคำอธิบายโดยละเอียดว่าreportValidity()จะจำลองได้อย่างไรในเบราว์เซอร์รุ่นเก่า

อย่างไรก็ตามคุณไม่จำเป็นต้องคัดลอกและวางบล็อคโค้ดเหล่านั้นลงในโปรเจ็กต์ของคุณด้วยตัวคุณเองเพราะมีponyfill / polyfillพร้อมให้คุณใช้งาน

reportValidity()ไม่รองรับตรงไหนเราต้องหลอกเบราว์เซอร์เล็กน้อย แล้วเราจะทำอย่างไร?

  1. ตรวจสอบความถูกต้องของแบบฟอร์มโดยโทรform.checkValidity(). สิ่งนี้จะบอกเราว่าแบบฟอร์มถูกต้องหรือไม่ แต่ไม่แสดง UI การตรวจสอบความถูกต้อง
  2. หากแบบฟอร์มไม่ถูกต้องเราจะสร้างปุ่มส่งชั่วคราวและเริ่มการคลิก เนื่องจากแบบฟอร์มไม่ถูกต้องเราจึงทราบว่าจะไม่ส่งจริงอย่างไรก็ตามจะแสดงคำแนะนำการตรวจสอบความถูกต้องให้กับผู้ใช้ เราจะลบปุ่มส่งชั่วคราวทันทีดังนั้นผู้ใช้จะไม่เห็นปุ่มนี้
  3. หากแบบฟอร์มถูกต้องเราไม่จำเป็นต้องเข้าไปยุ่งใด ๆ และปล่อยให้ผู้ใช้ดำเนินการต่อไป

ในรหัส:

triggerButton.onclick = function () {
  // Form is invalid!
  if (!form.checkValidity()) {
    // Create the temporary button, click and remove it
    var tmpSubmit = document.createElement('button')
    form.appendChild(tmpSubmit)
    tmpSubmit.click()
    form.removeChild(tmpSubmit)

  } else {
    // Form is valid, let the user proceed or do whatever we need to
  }
}

รหัสนี้จะใช้งานได้กับเบราว์เซอร์ทั่วไป (ฉันได้ทดสอบสำเร็จแล้วจนถึง IE11)

นี่คือตัวอย่าง CodePen ที่ใช้งานได้


23

ในบางกรณีคุณสามารถtriggerตรวจสอบความถูกต้องของแบบฟอร์ม HTML5 และแสดงคำแนะนำแก่ผู้ใช้โดยไม่ต้องส่งแบบฟอร์ม

สองปุ่มหนึ่งปุ่มสำหรับตรวจสอบความถูกต้องหนึ่งปุ่มสำหรับส่ง

ตั้งonclickผู้ฟังบนปุ่มตรวจสอบความถูกต้องเพื่อตั้งค่าสถานะส่วนกลาง (พูดjustValidate) เพื่อระบุว่าการคลิกนี้มีจุดมุ่งหมายเพื่อตรวจสอบความถูกต้องของแบบฟอร์ม

และตั้งค่าonclickผู้ฟังบนปุ่มส่งเพื่อตั้งค่าjustValidateสถานะเป็นเท็จ

จากนั้นในonsubmitตัวจัดการของแบบฟอร์มให้คุณตรวจสอบแฟล็กjustValidateเพื่อตัดสินใจค่าที่ส่งคืนและเรียกใช้preventDefault()เพื่อหยุดฟอร์มเพื่อส่ง ที่คุณรู้ว่าการตรวจสอบรูปแบบ HTML5 (และคำแนะนำแก่ผู้ใช้ GUI) จะ preformed ก่อนที่เหตุการณ์และแม้ว่ารูปแบบที่ถูกต้องคุณสามารถหยุดการส่งฟอร์มโดยกลับเท็จหรือวิงวอนonsubmitpreventDefault()

และใน HTML5 คุณมีวิธีตรวจสอบการตรวจสอบความถูกต้องของแบบฟอร์ม: form.checkValidity()จากนั้นคุณสามารถทราบได้ว่าแบบฟอร์มนั้นตรวจสอบความถูกต้องหรือไม่ในโค้ดของคุณ

ตกลงนี่คือการสาธิต: http://jsbin.com/buvuku/2/edit


3

ฉันไม่แน่ใจว่ามันคุ้มค่าสำหรับฉันที่จะพิมพ์ทั้งหมดนี้ตั้งแต่เริ่มต้นเนื่องจากบทความนี้ที่เผยแพร่ใน A List Apartนั้นอธิบายได้ดีทีเดียว นอกจากนี้ MDN ยังมีคู่มือที่มีประโยชน์สำหรับรูปแบบ HTML5 และการตรวจสอบความถูกต้อง (ครอบคลุม API และ CSS ที่เกี่ยวข้อง)


2

ค่อนข้างง่ายในการเพิ่มหรือลบการตรวจสอบ HTML5 ไปยัง fieldsets

 $('form').each(function(){

    // CLEAR OUT ALL THE HTML5 REQUIRED ATTRS
    $(this).find('.required').attr('required', false);

    // ADD THEM BACK TO THE CURRENT FIELDSET
    // I'M JUST USING A CLASS TO IDENTIFY REQUIRED FIELDS
    $(this).find('fieldset.current .required').attr('required', true);

    $(this).submit(function(){

        var current     = $(this).find('fieldset.current')
        var next        = $(current).next()

        // MOVE THE CURRENT MARKER
        $(current).removeClass('current');
        $(next).addClass('current');

        // ADD THE REQUIRED TAGS TO THE NEXT PART
        // NO NEED TO REMOVE THE OLD ONES
        // SINCE THEY SHOULD BE FILLED OUT CORRECTLY
        $(next).find('.required').attr('required', true);

    });

});

2

var field = $("#field")
field.keyup(function(ev){
    if(field[0].value.length < 10) {
        field[0].setCustomValidity("characters less than 10")
        
    }else if (field[0].value.length === 10) {
        field[0].setCustomValidity("characters equal to 10")
        
    }else if (field[0].value.length > 10 && field[0].value.length < 20) {
        field[0].setCustomValidity("characters greater than 10 and less than 20")
        
    }else if(field[0].validity.typeMismatch) {
    	field[0].setCustomValidity("wrong email message")
        
    }else {
    	field[0].setCustomValidity("") // no more errors
        
    }
    field[0].reportValidity()
    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="email" id="field">


1
ช่วยเพิ่มคำอธิบายได้ไหม
zmag

2

ฉันดูเหมือนจะพบเคล็ดลับ: เพียงแค่ลบtargetแอตทริบิวต์form จากนั้นใช้ปุ่มส่งเพื่อตรวจสอบความถูกต้องของแบบฟอร์มและแสดงคำใบ้ตรวจสอบว่าแบบฟอร์มถูกต้องผ่าน JavaScript หรือไม่จากนั้นโพสต์อะไรก็ได้ รหัสต่อไปนี้ใช้ได้กับฉัน:

<form>
  <input name="foo" required>
  <button id="submit">Submit</button>
</form>

<script>
$('#submit').click( function(e){
  var isValid = true;
  $('form input').map(function() {
    isValid &= this.validity['valid'] ;
  }) ;
  if (isValid) {
    console.log('valid!');
    // post something..
  } else
    console.log('not valid!');
});
</script>

ขอบคุณ! เป็นทางออกที่แท้จริงสำหรับ jQuery
Vuong

1

รหัส Html:

<form class="validateDontSubmit">
....
<button style="dislay:none">submit</button>
</form>
<button class="outside"></button>

javascript (โดยใช้ Jquery):

<script type="text/javascript">

$(document).on('submit','.validateDontSubmit',function (e) {
    //prevent the form from doing a submit
    e.preventDefault();
    return false;
})

$(document).ready(function(){
// using button outside trigger click
    $('.outside').click(function() {
        $('.validateDontSubmit button').trigger('click');
    });
});
</script>

หวังว่านี่จะช่วยคุณได้


ทำไมจึงตอบคำถาม?
ปฏิบัติการ

โดยใช้ HTML5 ตรวจสอบความถูกต้องโดยไม่ต้องส่ง และใช้ข้อมูลแบบฟอร์มเพื่อวัตถุประสงค์ของคุณ: form_data = $ ('. validateDontSubmit'). serializeArray ();
HưngTrịnh

0

สำหรับช่องป้อนข้อมูล

<input id="PrimaryPhNumber" type="text" name="mobile"  required
                                       pattern="^[789]\d{9}$" minlenght="10" maxLength="10" placeholder="Eg: 9444400000"
                                       class="inputBoxCss"/>
$('#PrimaryPhNumber').keyup(function (e) {
        console.log(e)
        let field=$(this)
        if(Number(field.val()).toString()=="NaN"){
            field.val('');
            field.focus();
            field[0].setCustomValidity('Please enter a valid phone number');
            field[0].reportValidity()
            $(":focus").css("border", "2px solid red");
        }
    })

-1

เมื่อมีกระบวนการตรวจสอบความถูกต้องที่ซับซ้อนมาก (โดยเฉพาะอะซิงโครนัส) มีวิธีแก้ปัญหาง่ายๆดังนี้

<form id="form1">
<input type="button" onclick="javascript:submitIfVeryComplexValidationIsOk()" />
<input type="submit" id="form1_submit_hidden" style="display:none" />
</form>
...
<script>
function submitIfVeryComplexValidationIsOk() {
    var form1 = document.forms['form1']
    if (!form1.checkValidity()) {
        $("#form1_submit_hidden").click()
        return
    }

    if (checkForVeryComplexValidation() === 'Ok') {
         form1.submit()
    } else {
         alert('form is invalid')
    }
}
</script>

-2

อีกวิธีในการแก้ไขปัญหานี้:

$('input').oninvalid(function (event, errorMessage) {
    event.target.focus();
});

ไม่ได้ผลสำหรับฉันฉันได้รับ: Uncaught TypeError: $(...).oninvalid is not a functionและฉันไม่เห็นมันในเอกสาร jQuery
MECU

ฉันคิดว่ามันควรจะบอกว่า "ไม่ถูกต้อง" ไม่ใช่ "oninvalid" ในขณะที่คุณใช้ jQuery ที่นี่
Aenadon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.