우수한 jQuery Validate Plugin 을 사용하여 일부 양식의 유효성을 검사하고 있습니다. 한 양식에서 사용자가 필드 그룹 중 하나 이상을 채우도록해야합니다. 꽤 좋은 해결책이 있다고 생각하고 공유하고 싶었습니다. 생각할 수있는 개선 사항을 제안하십시오.
이 작업을 수행하는 기본 제공 방법을 찾지 못한 채로 Rebecca Murphey의 사용자 지정 유효성 검사 방법을 검색하고 찾았습니다 . 이는 매우 유용했습니다.
나는 이것을 세 가지 방법으로 개선했습니다.
- 필드 그룹에 대한 선택기를 전달하려면
- 유효성 검사를 통과하기 위해 채워야하는 해당 그룹의 수를 지정하려면
- 그룹의 모든 입력이 유효성 검사를 통과하자마자 유효성 검사를 통과 한 것으로 표시합니다. ( 마지막 에 Nick Craver 에게 외침을 참조하십시오 .)
그래서 당신은 말할 수 있습니다 “선택기 Y와 일치하는 입력을 X 개 이상 채워야합니다.” .
다음과 같은 마크 업이있는 최종 결과 :
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
… 다음과 같은 규칙 그룹입니다.
// Both these inputs input will validate if
// at least 1 input with class 'productinfo' is filled
partnumber: {
require_from_group: [1,".productinfo"]
}
description: {
require_from_group: [1,".productinfo"]
}
항목 # 3은 .checked
성공적인 유효성 검사시 오류 메시지에 의 클래스를 추가한다고 가정합니다 . 여기에 설명 된 대로 다음과 같이이 작업을 수행 할 수 있습니다 .
success: function(label) {
label.html(" ").addClass("checked");
}
위에 링크 된 데모에서와 같이 CSS를 사용 span.error
하여 클래스가없는 경우 각각 의 X 이미지를 배경으로 제공합니다 ..checked
경우 체크 표시 이미지가 표시됩니다.
지금까지 내 코드는 다음과 같습니다.
jQuery.validator.addMethod("require_from_group", function(value, element, options) {
var numberRequired = options[0];
var selector = options[1];
//Look for our selector within the parent form
var validOrNot = $(selector, element.form).filter(function() {
// Each field is kept if it has a value
return $(this).val();
// Set to true if there are enough, else to false
}).length >= numberRequired;
// The elegent part - this element needs to check the others that match the
// selector, but we don't want to set off a feedback loop where each element
// has to check each other element. It would be like:
// Element 1: "I might be valid if you're valid. Are you?"
// Element 2: "Let's see. I might be valid if YOU'RE valid. Are you?"
// Element 1: "Let's see. I might be valid if YOU'RE valid. Are you?"
// ...etc, until we get a "too much recursion" error.
//
// So instead we
// 1) Flag all matching elements as 'currently being validated'
// using jQuery's .data()
// 2) Re-run validation on each of them. Since the others are now
// flagged as being in the process, they will skip this section,
// and therefore won't turn around and validate everything else
// 3) Once that's done, we remove the 'currently being validated' flag
// from all the elements
if(!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
// .valid() means "validate using all applicable rules" (which
// includes this one)
fields.valid();
fields.data('being_validated', false);
}
return validOrNot;
// {0} below is the 0th item in the options field
}, jQuery.format("Please fill out at least {0} of these fields."));
만세!
외쳐
이제 그 외침을 위해-원래 내 코드는 다시 확인하는 대신 다른 일치하는 필드에 오류 메시지를 맹목적으로 숨겼습니다. 즉, 다른 문제가있는 경우 ( ‘숫자 만 허용되고 문자를 입력했습니다’) , 사용자가 제출을 시도 할 때까지 숨겨졌습니다. 위의 주석에서 언급 한 피드백 루프를 피하는 방법을 몰랐기 때문입니다. 나는 방법이 있어야한다는 것을 알았 기 때문에 질문 을했고 Nick Craver가 나를 깨달았다 . 고마워, 닉!
해결 된 질문
이것은 원래 “이것을 공유하고 누구든지 개선을 제안 할 수 있는지 보자”와 같은 종류의 질문이었습니다. 여전히 피드백을 환영하지만이 시점에서 꽤 완벽하다고 생각합니다. (더 짧을 수도 있지만, 읽기 쉽고 간결하지 않기를 바랍니다.) 그러니 즐기세요!
업데이트-이제 jQuery 유효성 검사의 일부
이것은 공식적 으로 2012 년 4 월 3 일에 jQuery 유효성 검사 에 추가되었습니다 .
답변
그것은 훌륭한 솔루션 Nathan입니다. 감사합니다.
내가 한 것처럼 누군가가 그것을 통합하는 데 문제가 발생하는 경우 위의 코드를 작동시키는 방법은 다음과 같습니다.
additional-methods.js 파일 내부의 코드 :
jQuery.validator.addMethod("require_from_group", function(value, element, options) {
...// Nathan's code without any changes
}, jQuery.format("Please fill out at least {0} of these fields."));
// "filone" is the class we will use for the input elements at this example
jQuery.validator.addClassRules("fillone", {
require_from_group: [1,".fillone"]
});
html 파일 내부의 코드 :
<input id="field1" class="fillone" type="text" value="" name="field1" />
<input id="field2" class="fillone" type="text" value="" name="field2" />
<input id="field3" class="fillone" type="text" value="" name="field3" />
<input id="field4" class="fillone" type="text" value="" name="field4" />
additional-methods.js 파일을 포함하는 것을 잊지 마십시오!
답변
좋은 솔루션입니다. 그러나 다른 필수 규칙이 작동하지 않는 문제가있었습니다. 양식에 대해 .valid ()를 실행하면이 문제가 해결되었습니다.
if(!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
$(element.form).valid();
fields.data('being_validated', false);
}
답변
숀 감사합니다. 다른 규칙을 무시하는 코드와 관련된 문제가 해결되었습니다.
또한 모든 필드가 아닌 별도의 div에 ‘적어도 하나의 필드를 입력하십시오 ..’메시지가 표시되도록 몇 가지 변경 사항을 적용했습니다.
양식 유효성 검사 스크립트에 넣어
showErrors: function(errorMap, errorList){
$("#form_error").html("Please fill out at least 1 field before submitting.");
this.defaultShowErrors();
},
페이지 어딘가에 추가
<div class="error" id="form_error"></div>
require_from_group 메소드 addMethod 함수에 추가
if(validOrNot){
$("#form_error").hide();
}else{
$("#form_error").show();
}
......
}, jQuery.format(" (!)"));
답변
현재 버전이하는 문제로 고통받지 않는 패치 를 제출했습니다 ( “필수”옵션이 다른 필드에서 제대로 작동하지 않는 경우, 현재 버전의 문제에 대한 토론은 github에 있습니다.).
http://jsfiddle.net/f887W/10/의 예
jQuery.validator.addMethod("require_from_group", function (value, element, options) {
var validator = this;
var minRequired = options[0];
var selector = options[1];
var validOrNot = jQuery(selector, element.form).filter(function () {
return validator.elementValue(this);
}).length >= minRequired;
// remove all events in namespace require_from_group
jQuery(selector, element.form).off('.require_from_group');
//add the required events to trigger revalidation if setting is enabled in the validator
if (this.settings.onkeyup) {
jQuery(selector, element.form).on({
'keyup.require_from_group': function (e) {
jQuery(selector, element.form).valid();
}
});
}
if (this.settings.onfocusin) {
jQuery(selector, element.form).on({
'focusin.require_from_group': function (e) {
jQuery(selector, element.form).valid();
}
});
}
if (this.settings.click) {
jQuery(selector, element.form).on({
'click.require_from_group': function (e) {
jQuery(selector, element.form).valid();
}
});
}
if (this.settings.onfocusout) {
jQuery(selector, element.form).on({
'focusout.require_from_group': function (e) {
jQuery(selector, element.form).valid();
}
});
}
return validOrNot;
}, jQuery.format("Please fill at least {0} of these fields."));
답변
$로 변수 이름을 시작하는 것은 PHP에서는 필요하지만 Javascript에서는 상당히 이상합니다 (IMHO). 또한 “$ module”은 두 번, “module”은 한 번 언급하시는 것 같습니다. 이 코드는 작동하지 않는 것 같습니다.
또한 일반적인 jQuery 플러그인 구문인지 확실하지 않지만 addMethod 호출 위에 주석을 추가하여 수행 한 작업을 설명 할 수 있습니다. 위의 텍스트 설명이 있어도 어떤 fieldset, : filled, value, element 또는 selector가 참조하는지 잘 모르기 때문에 코드를 따르기가 어렵습니다. 아마도 이것의 대부분은 Validate 플러그인에 익숙한 사람에게 명백하므로 올바른 설명이 무엇인지 판단하십시오.
아마도 코드를 자체 문서화하기 위해 몇 가지 변수를 분리 할 수 있습니다. 처럼,
var atLeastOneFilled = module.find(...).length > 0;
if (atLeastOneFilled) {
var stillMarkedWithErrors = module.find(...).next(...).not(...);
stillMarkedWithErrors.text("").addClass(...)
(이 코드 덩어리의 의미를 이해했다고 가정하면! :))
“모듈”이 무엇을 의미하는지 정확히 모르겠습니다.이 변수에 더 구체적인 이름을 지정할 수 있습니까?
전반적으로 좋은 코드입니다!
답변
작업중인 양식에는 다음과 같은 그룹화 된 입력이있는 여러 복제 영역이 있기 때문에 addMethod 함수의 정확히 한 줄을 변경하여 require_from_group 생성자에 추가 인수를 전달했습니다.
var commonParent = $(element).parents(options[2]);
이렇게하면 선택자, ID 또는 요소 이름을 한 번 전달할 수 있습니다.
jQuery.validator.addClassRules("reqgrp", {require_from_group: [1, ".reqgrp", 'fieldset']});
유효성 검사기는 양식의 모든 .reqgrp 클래스 요소를 계산하려고 시도하지 않고 각 필드 집합 내에서만 해당 클래스가있는 요소로 유효성 검사를 제한합니다.
답변
Rocket Hazmat의 답변에 대한 내 균열은 유효성 검사가 필요한 다른 정의 된 필드 문제를 해결하려고 노력하지만 성공적으로 채울 때 모든 필드를 유효한 것으로 표시합니다.
jQuery.validator.addMethod("require_from_group", function(value, element, options){
var numberRequired = options[0],
selector = options[1],
$fields = $(selector, element.form),
validOrNot = $fields.filter(function() {
return $(this).val();
}).length >= numberRequired,
validator = this;
if(!$(element).data('being_validated')) {
$fields.data('being_validated', true).each(function(){
validator.valid(this);
}).data('being_validated', false);
}
if (validOrNot) {
$(selector).each(function() {
$(this).removeClass('error');
$('label.error[for='+$(this).attr('id')+']').remove();
});
}
return validOrNot;
}, jQuery.format("Please fill out at least {0} of these fields."));
이제 남은 문제는 필드가 비어있다가 채운 다음 다시 비어있는 경우입니다.이 경우 오류는 그룹이 아닌 단일 필드에 적용됩니다. 그러나 그것은 어떤 빈도로도 일어날 가능성이 거의없는 것처럼 보이며이 경우에도 여전히 기술적으로 작동합니다.