Kích hoạt xác thực biểu mẫu HTML5


97

Tôi có một biểu mẫu với một số bộ trường khác nhau. Tôi có một số Javascript hiển thị các nhóm trường cho từng người dùng một. Đối với các trình duyệt hỗ trợ xác thực HTML5, tôi rất muốn sử dụng nó. Tuy nhiên, tôi cần phải làm điều đó với điều kiện của mình. Tôi đang sử dụng JQuery.

Khi người dùng nhấp vào Liên kết JS để chuyển sang tập trường tiếp theo, tôi cần xác thực xảy ra trên tập trường hiện tại và chặn người dùng tiếp tục nếu có vấn đề.

Lý tưởng nhất là khi người dùng mất tập trung vào một phần tử, việc xác thực sẽ xảy ra.

Hiện tại không có hợp lệ đi và sử dụng Javascript. Muốn sử dụng phương pháp gốc. :)

Câu trả lời:


60

Bạn không thể kích hoạt giao diện người dùng xác thực gốc, nhưng bạn có thể dễ dàng tận dụng API xác thực trên các phần tử đầu vào tùy ý:

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

Sự kiện đầu tiên kích hoạt checkValiditytrên mọi phần tử đầu vào ngay khi nó mất tiêu điểm, nếu phần tử invalidđó là thì sự kiện tương ứng sẽ được kích hoạt và bị mắc kẹt bởi trình xử lý sự kiện thứ hai. Điều này đặt tiêu điểm trở lại phần tử, nhưng điều đó có thể khá khó chịu, tôi cho rằng bạn có một giải pháp tốt hơn để thông báo về các lỗi. Đây là một ví dụ làm việc về mã của tôi ở trên .


20
Câu vàng "Bạn không thể kích hoạt giao diện người dùng xác thực gốc" . Trong trường hợp của tôi (tùy chỉnh JS thủ thuật + Trình duyệt html5 xác nhận + UI tooltips) Tôi không có sự lựa chọn hơn cho đi ẩn nút gửi ở cuối để có được cả hai
lukmdo

22
Nếu biểu mẫu của bạn không có nút gửi, bạn có thể giả mạo một nút:$('<input type="submit">').hide().appendTo($myForm).click().remove();
philfreo

1
@philfreo Sẽ không form.submit()tốt sao? Hay HTML5 yêu cầu nút gửi để xác thực ngay bây giờ?
Mattisdada

@Mattisdada Gọi điện .submit()không hoạt động với tôi. Giải pháp của @ philfreo hoạt động. Hừ!
Zero3

128

TL; DR: Không quan tâm đến các trình duyệt cũ? Sử dụngform.reportValidity() .

Cần hỗ trợ trình duyệt cũ? Đọc tiếp.


Nó thực sự có thể để xác nhận kích hoạt bằng tay.

Tôi sẽ sử dụng JavaScript đơn giản trong câu trả lời của mình để cải thiện khả năng tái sử dụng, không cần jQuery.


Giả sử dạng HTML sau:

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

Và hãy lấy các phần tử giao diện người dùng của chúng tôi trong JavaScript:

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

Bạn không cần hỗ trợ cho các trình duyệt cũ như Internet Explorer? Cái này dành cho bạn.

Tất cả các trình duyệt hiện đại hỗ trợ các reportValidity()phương pháp trên formcác yếu tố.

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

Vậy là xong. Ngoài ra, đây là một CodePen đơn giản sử dụng phương pháp này.


Phương pháp tiếp cận cho các trình duyệt cũ hơn

Dưới đây là giải thích chi tiết cách reportValidity()có thể được mô phỏng trong các trình duyệt cũ hơn.

Tuy nhiên, bạn không cần phải tự mình sao chép và dán các khối mã đó vào dự án của mình - có một ponyfill / polyfill luôn sẵn sàng cho bạn.

Chỗ nào reportValidity()không được hỗ trợ thì chúng ta cần đánh lừa trình duyệt một chút. Vậy chúng ta sẽ làm gì?

  1. Kiểm tra tính hợp lệ của biểu mẫu bằng cách gọi form.checkValidity(). Điều này sẽ cho chúng tôi biết nếu biểu mẫu hợp lệ, nhưng không hiển thị giao diện người dùng xác thực.
  2. Nếu biểu mẫu không hợp lệ, chúng tôi tạo một nút gửi tạm thời và kích hoạt một cú nhấp chuột vào nó. Vì biểu mẫu không hợp lệ nên chúng tôi biết rằng biểu mẫu này sẽ không thực sự gửi, tuy nhiên, nó sẽ hiển thị gợi ý xác thực cho người dùng. Chúng tôi sẽ xóa nút gửi tạm thời ngay lập tức, vì vậy nó sẽ không bao giờ hiển thị cho người dùng.
  3. Nếu biểu mẫu hợp lệ, chúng tôi không cần can thiệp gì cả và để người dùng tiếp tục.

Trong mã:

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
  }
}

Mã này sẽ hoạt động trên hầu hết mọi trình duyệt phổ biến (Tôi đã thử nghiệm thành công nó xuống IE11).

Đây là một ví dụ CodePen đang hoạt động.


22

Ở một mức độ nào đó, bạn CÓ THỂ trigger xác thực biểu mẫu HTML5 và hiển thị gợi ý cho người dùng mà không cần gửi biểu mẫu!

Hai nút, một để xác thực, một để gửi

Đặt một trình onclicknghe trên nút xác thực để đặt cờ toàn cầu (nói justValidate) để cho biết nhấp chuột này nhằm mục đích kiểm tra xác thực của biểu mẫu.

Và đặt một onclickngười nghe trên nút gửi để đặt justValidatecờ thành sai.

Sau đó, trong onsubmittrình xử lý của biểu mẫu, bạn kiểm tra cờ justValidateđể quyết định giá trị trả về và gọi lệnh preventDefault()dừng biểu mẫu để gửi. Như bạn đã biết, xác thực biểu mẫu HTML5 (và gợi ý GUI cho người dùng) được định dạng trước trước onsubmitsự kiện và ngay cả khi biểu mẫu HỢP LỆ, bạn có thể dừng gửi biểu mẫu bằng cách trả về false hoặc gọi preventDefault().

Và, trong HTML5, bạn có một phương pháp để kiểm tra xác thực của biểu mẫu: form.checkValidity() sau đó bạn có thể biết liệu biểu mẫu có được xác thực hay không trong mã của mình.

OK, đây là bản demo: http://jsbin.com/buvuku/2/edit



2

Hơi dễ dàng để thực hiện thêm hoặc xóa xác thực HTML5 vào các tập trường.

 $('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

Dường như tôi đã tìm ra mẹo: Chỉ cần xóa targetthuộc tính biểu mẫu , sau đó sử dụng nút gửi để xác thực biểu mẫu và hiển thị gợi ý, kiểm tra xem biểu mẫu có hợp lệ hay không qua JavaScript và sau đó đăng bất kỳ thứ gì. Đoạn mã sau phù hợp với tôi:

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

Cảm ơn! Đó là giải pháp thực sự cho jQuery.
Vương

1

Mã HTML:

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

javascript (sử dụng 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>

Hy vọng điều này sẽ giúp bạn


Tại sao nó trả lời câu hỏi?
thực thi

nó sử dụng HTML5 xác thực mà không cần gửi. và sử dụng dữ liệu Biểu mẫu cho mục đích của bạn: form_data = $ ('. validateDontSubmit'). serializeArray ();
Hưng Trịnh

1

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
Bạn có thể giải thích thêm không?
zmag

-1

Khi có một quy trình xác thực rất phức tạp (đặc biệt là không đồng bộ), có một cách giải quyết đơn giản:

<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

Một cách khác để giải quyết vấn đề này:

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

Không hiệu quả với tôi, tôi nhận được: Uncaught TypeError: $(...).oninvalid is not a functionvà tôi không thấy nó trong tài liệu jQuery.
MECU

Tôi nghĩ rằng nó nên nói "không hợp lệ" chứ không phải "oninvalid" như bạn đang sử dụng jQuery ở đây.
Aenadon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.