jQuery Validate - 그룹에 하나 이상의 필드를 채워야 합니다.
일부 양식의 유효성을 검사하기 위해 우수한 jQuery Validate Plugin을 사용하고 있습니다.하나의 양식에서 사용자가 필드 그룹 중 하나 이상을 입력해야 합니다.저는 꽤 좋은 해결책이 있다고 생각합니다. 그리고 그것을 공유하고 싶었습니다.당신이 생각할 수 있는 개선 사항을 제안해 주십시오.
이를 위한 내장된 방법을 찾지 못하고 검색해보니 레베카 머피의 맞춤형 검증 방법이 매우 도움이 되었습니다.
이를 세 가지 방법으로 개선했습니다.
- 필드 그룹에 대한 선택기를 전달하려면
- 유효성 검사를 통과하려면 해당 그룹 중 몇 개를 채워야 하는지 지정하려면 다음과 같이 하십시오.
- 그룹의 모든 입력 중 하나가 유효성 검사를 통과하는 즉시 유효성 검사를 통과한 것으로 표시합니다.(마지막으로 닉 크레이버에게 고함치는 것을 참조하십시오.)
따라서 "선택기 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인 경우를 제외하고 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."));
만세!
소리 질러!
이제 그 외침을 위해 - 원래 제 코드는 오류 메시지를 재검증하는 대신 다른 일치하는 필드에 맹목적으로 숨겼습니다. 즉, '숫자만 허용되고 문자를 입력했습니다'와 같은 다른 문제가 발생하면 사용자가 제출하려고 할 때까지 숨겨졌습니다.위의 댓글에 언급된 피드백 루프를 피하는 방법을 몰랐기 때문입니다.저는 방법이 있을 것이라는 것을 알고 질문을 던졌고, 닉 크레이버가 저를 깨우쳐주었습니다.고마워, 닉!
해결된 질문
이것은 원래 "이것을 공유하고 개선을 제안할 수 있는 사람이 있는지 알아보겠습니다"라는 질문이었습니다.저는 여전히 피드백을 환영하지만, 저는 이 시점에서 그것이 꽤 완성되었다고 생각합니다.(더 짧을 수도 있지만, 반드시 간결하지 않고 읽기 쉬웠으면 합니다.)그러니 그냥 즐기세요!
업데이트 - 이제 jQuery Validation의 일부입니다.
2012년 4월 3일에 jQuery Validation에 공식적으로 추가되었습니다.
훌륭한 해결책입니다 네이쓴정말 감사해요.
다음은 제가 했던 것처럼 누군가가 코드를 통합하는 데 문제가 발생할 경우를 대비해 위 코드를 작동시키는 방법입니다.
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);
}
고마워 션.그것은 다른 규칙을 무시한 코드에 대한 문제를 해결했습니다.
또한 '1개 이상의 필드를 작성하십시오...' 메시지가 모든 필드가 아닌 별도의 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 메서드에 추가 메서드 추가 함수
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에서는 필요하지만 자바스크립트에서는 꽤 이상한(IMHO) 것입니다.그리고 $module은 두 번, module은 한 번이라고 말씀하시는 거죠?이 코드는 작동하지 않는 것 같습니다.
또한, 정상적인 jQuery 플러그인 구문인지는 잘 모르겠지만, 당신의 addMethod 호출 위에 당신이 무엇을 달성하는지 설명하는 주석을 추가할 수도 있습니다.위의 텍스트 설명에도 불구하고 필드 집합, :filled, value, element 또는 selector가 무엇을 참조하는지 잘 모르기 때문에 코드를 따르기가 어렵습니다.이 중 대부분은 Validate 플러그인에 익숙한 사용자에게 분명하므로 올바른 설명 양에 대한 판단을 사용합니다.
아마도 코드를 자체 문서화하기 위해 몇 개의 변수를 분리할 수 있을 것입니다. 예를 들어,
var atLeastOneFilled = module.find(...).length > 0;
if (atLeastOneFilled) {
var stillMarkedWithErrors = module.find(...).next(...).not(...);
stillMarkedWithErrors.text("").addClass(...)
(내가 당신 코드의 이 덩어리들의 의미를 이해했다고 가정하면! :)
저는 "모듈"이 무엇을 의미하는지 정확히 모르겠습니다. 이 변수에 더 구체적인 이름을 붙일 수 있을까요?
전체적으로 코드가 좋네요!
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."));
이제 남은 유일한 문제는 에지 케이스입니다. 에지 케이스는 필드가 비어있다가 채워졌다가 다시 비어있습니다.이 경우 오류가 그룹이 아닌 단일 필드에 적용됩니다.하지만 그런 일은 어떤 빈도로도 일어날 가능성이 매우 낮아 보이고 기술적으로 여전히 작동합니다.
제가 작업하고 있는 양식에 다음과 같이 그룹화된 입력을 가진 복제 영역이 여러 개 있기 때문에 require_from_group 생성자에게 추가 인수를 전달하여 addMethod 함수의 한 줄을 정확히 변경했습니다.
var commonParent = $(element).parents(options[2]);
이렇게 하면 셀렉터, ID 또는 요소 이름을 한 번 전달할 수 있습니다.
jQuery.validator.addClassRules("reqgrp", {require_from_group: [1, ".reqgrp", 'fieldset']});
그리고 유효성 검사기는 폼의 모든 .reqgrp 클래스 요소를 카운트하지 않고 각 필드 집합 내에서만 해당 클래스를 포함하는 요소로 유효성 검사를 제한합니다.
다른 규칙이 이와 함께 확인되지 않아 문제가 발생하여 변경했습니다.
fields.valid();
대상:
var validator = this;
fields.each(function(){
validator.valid(this);
});
또한 몇 가지 (개인적인) 개선 작업을 수행했으며, 현재 사용 중인 버전은 다음과 같습니다.
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);
}
return validOrNot;
}, jQuery.format("Please fill out at least {0} of these fields."));
고마워, 네이쓴당신 덕분에 시간이 많이 절약됐어요.
그러나 이 규칙은 jQuery.noConflict() 준비되지 않았습니다.따라서 모든 $를 jQuery로 대체하여 작업해야 합니다.var $j = jQuery.noConflict()
그리고 질문이 있습니다. 어떻게 하면 기본 규칙처럼 행동하게 만들 수 있을까요?예를 들어 전자 메일을 입력하면 "유효한 전자 메일을 입력하십시오"라는 메시지가 자동으로 사라지지만 그룹 필드 중 하나를 채우면 오류 메시지가 유지됩니다.
언급URL : https://stackoverflow.com/questions/1300994/jquery-validate-require-at-least-one-field-in-a-group-to-be-filled
'programing' 카테고리의 다른 글
mariadb 10.2.26에서 기본 키 +10000으로 열(항상 생성됨)을 생성하려면 어떻게 해야 합니까? (0) | 2023.08.30 |
---|---|
PHP와 Javascript 간에 배열을 전송하는 가장 좋은 방법 (0) | 2023.08.30 |
AJAX 호출 중 JS 변수 이름 끝에 있는 대괄호를 제거하려면 어떻게 해야 합니까? (0) | 2023.08.30 |
웹사이트 요청 시 보낸 사용자 에이전트와 다른 Javascript 사용자 에이전트(jax) (0) | 2023.08.30 |
파일 업로드 컨트롤을 사용하여 파일의 전체 경로 가져오기 (0) | 2023.08.30 |