Angular Form 제출의 모든 필드에 대한 유효성 검사 트리거


81

이 방법을 사용하고 있습니다 : http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview 를 사용하여 흐림에 대한 필드 만 확인합니다. 이것은 잘 작동하지만 사용자가 '제출'버튼 (실제 제출이 아니라 함수에 대한 data-ng-click 호출)을 클릭 할 때 유효성을 검사 (따라서 해당 필드에 대한 오류가있는 경우 표시)하고 싶습니다.

해당 버튼을 클릭 할 때 모든 필드에 대한 유효성 검사를 다시 트리거하는 방법이 있습니까?


플 런커의 버튼은 어디에 있습니까?
callmekatootie 2013-06-05

죄송합니다. 플 런커는 내 코드를 기반으로 한 것입니다 .. 내 상황과 더 가깝게 닮은 포크를 만들었습니다. plnkr.co/edit/VfvCSmjlzpIgUH4go2Jn?p=preview
Maarten

답변:


44

나를 위해 일한 것은 $setSubmitted1.3.20 버전의 앵귤러 문서에 처음 표시되는 함수를 사용하는 것입니다.

유효성 검사를 트리거하려는 클릭 이벤트에서 다음을 수행했습니다.

vm.triggerSubmit = function() {
    vm.homeForm.$setSubmitted();
    ...
}

그게 전부였습니다. 문서에 따르면 "양식을 제출 된 상태로 설정합니다." 여기에 언급되어 있습니다 .


4
이것은 사용할 때 작동하지 않고 $ error && $ dirtyng-messages 때만 표시합니다 .
JobaDiniz 2013 년

@JobaDiniz $ setDirty 함수를 사용해 보셨습니까? 내 대답의 링크에도 언급되어 있습니다 : code.angularjs.org/1.3.20/docs/api/ng/type/form.FormController 도움이 되기를 바랍니다 !
developering

2
작동하지 않습니다 form... 모든 입력을 반복하고 호출 $setDirty()해야했습니다.
JobaDiniz

43

대답하기에는 너무 늦었지만, 모든 양식을 더럽 히기 만하면됩니다. 다음 스 니펫을 살펴보십시오.

angular.forEach($scope.myForm.$error.required, function(field) {
    field.$setDirty();
});

그런 다음 다음을 사용하여 양식이 유효한지 확인할 수 있습니다.

if($scope.myForm.$valid) {
    //Do something
}   

마지막으로 모든 것이 좋아 보인다면 경로를 변경하고 싶을 것입니다.

$location.path('/somePath');

편집 : 제출 이벤트가 트리거 될 때까지 양식이 범위에 등록되지 않습니다. ng-submit 지시문을 사용하여 함수를 호출하고 위의 함수를 해당 함수에 래핑하면 작동합니다.


1
프로그래밍 방식으로 ng-submit지시문을 트리거하는 예를 제공 할 수 있습니까?
chovy

@chovy는 ng-submit단순히 함수를 제출 이벤트에 바인딩합니다. 왜 그 함수를 호출하지 않습니까?
Thilak Rao

지시문 외부의 양식 필드를 업데이트하는 양식에 지시문이 포함되어 있습니다. ... 유효성 검사를 원하는 양식 필드를 클릭하고 흐리게하지 않는 한 유효성 검사기가 적용되지 않습니다.
chovy

나는 그것에게 전달되는 양식 객체를 가지지 않을 것입니다
chovy

@chovy 나는 당신을 올바르게 이해하지 못합니다. 하지만 제가 도와 드리겠습니다. 디 바운스 검증을 시도해 보셨습니까?
Thilak Rao

17

누군가가 나중에 이것에 다시 올 경우 ... 위의 어느 것도 나를 위해 일하지 않았습니다. 그래서 각도 형식 유효성 검사의 핵심을 파헤 치고 주어진 필드에서 유효성 검사기를 실행하기 위해 호출하는 함수를 찾았습니다. 이 속성은 편리하게 호출 $validate됩니다.

명명 된 form이있는 경우 myForm프로그래밍 방식으로 호출 myForm.my_field.$validate()하여 필드 유효성 검사를 실행할 수 있습니다 . 예를 들면 :

<div ng-form name="myForm">
    <input required name="my_field" type="text" ng-blur="myForm.my_field.$validate()">
</div>

호출 $validate은 모델에 영향을 미칩니다. ngModelCtrl. $ validate에 대한 각도 문서에서 :

등록 된 각 유효성 검사기를 실행합니다 (첫 번째 동기 유효성 검사기 다음 비동기 유효성 검사기). 유효성이 유효하지 않은 것으로 변경되면 ngModelOptions.allowInvalid가 true가 아닌 한 모델이 정의되지 않음으로 설정됩니다. 유효성이 valid로 변경되면 모델이 마지막으로 사용 가능한 유효한 $ modelValue, 즉 마지막으로 구문 분석 된 값 또는 범위에서 설정된 마지막 값으로 설정됩니다.

따라서 유효하지 않은 모델 값 (예 : 그렇게 알리는 메시지 표시)으로 무언가를 할 계획이라면 모델 allowInvalidtrue대해 로 설정되어 있는지 확인해야합니다 .


부재시 매우 놀라운 "모델이 정의되지 않음"결과에 대한 자세한 내용은 allowInvalid여기에서 읽을 수 있습니다. github.com/angular/angular.js/issues/10035
pestophagous

12

Angular-Validator 를 사용 하여 원하는 작업을 수행 할 수 있습니다. 사용하기는 어리 석습니다.

그것은 :

  • 필드의 유효성을 검사합니다 $dirty.submit
  • 유효하지 않은 경우 양식 제출 방지
  • 필드가 $dirty있거나 양식이 제출 된 후 사용자 지정 오류 메시지 표시

데모보기

<form angular-validator 
       angular-validator-submit="myFunction(myBeautifulForm)"
       name="myBeautifulForm">
       <!-- form fields here -->
    <button type="submit">Submit</button>
</form>

필드가 통과하지 못하면 validator사용자는 양식을 제출할 수 없습니다.

확인 각도 - 검증의 사용 사례 및 예제를 자세한 내용은.

면책 조항 : 저는 Angular-Validator의 저자입니다.


11

음, 각진 방법은 유효성 검사를 처리하도록하는 것입니다.-모든 모델 변경에서 수행되기 때문에-원하는 경우에만 결과를 사용자에게 보여줍니다.

이 경우 오류를 표시 할시 기를 결정하고 플래그를 설정하기 만하면됩니다. http://plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p=preview

내가 아는 한 더 고급 양식 제어를 할 수 있도록 각도에 문제가 있습니다. 해결되지 않았기 때문에 기존의 모든 유효성 검사 방법을 재발 명하는 대신 이것을 사용합니다.

편집 : 그러나 당신이 당신의 길을 주장한다면, 여기에 제출하기 전에 유효성 검사가있는 수정 된 바이올린이 있습니다. http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview 컨트롤러는 버튼을 클릭 할 때 이벤트를 브로드 캐스트하고 지시문은 유효성 검사 마법을 수행합니다.


이것은이 예제에서 작동하지만, 제 경우에있는 것처럼 (하지만 그 plunkr .. 죄송합니다!) 이메일과 같은 하나 이상의 지시문이 있다면 어떻게 될까요? 어떻게 든 지시문의 유효성 검사를 별도의 유효성 검사 클래스로 이동 한 다음이 양식의 모든 유효성 검사 메서드를 호출해야합니까, 아니면 모든 지시문에 대해 다른 방식으로 유효성 검사를 트리거 할 수 있습니까? 유효성 검사는 블러에 의해 트리거되므로 코드에서 블러를 트리거 할 수도 있지만 끔찍한 것 같습니다.
Maarten

아 그리고 나는 그 문제에 대해 알고 있습니다. 불행히도 아직 베타 버전에없는 내가 이야기하고있는 워크 플로우는이 회사를 위해 일을해야합니다
마틴

브로드 캐스트 된 이벤트는 모든 지시문이 컨트롤러의 범위에 있기 때문에 모든 지시문에서 $ on 콜백을 트리거합니다.
Oliver

아 .. 정말 그 부분을 이해하지 못했습니다. 감사!
Maarten

1
이벤트를 브로드 캐스트 할 때 매개 변수를 전달할 수 있습니다. $ scope. $ broadcast ( 'startValidations', param1, param2); 청취는 변경되지 않습니다. scope. $ on ( 'startValidations', validateMe); 그리고 콜백에서 fn : function validateMe (event, param1, param2) {} 문서 참조 : docs.angularjs.org/api/ng.$rootScope.Scope#$broadcast
Oliver

9

한 가지 접근 방식은 모든 속성을 더티하게 만드는 것입니다. 각 컨트롤러에서 할 수 있지만 매우 지저분합니다. 일반적인 해결책이있는 것이 좋습니다.

제가 생각할 수있는 가장 쉬운 방법은

  • 양식 제출 속성을 처리합니다.
  • 모든 양식 필드를 반복하고 깨끗한 필드를 더티 표시합니다.
  • 제출 함수를 호출하기 전에 양식이 유효한지 확인합니다.

다음은 지침입니다.

myModule.directive('submit', function() {
  return {
    restrict: 'A',
    link: function(scope, formElement, attrs) {
      var form;
      form = scope[attrs.name];
      return formElement.bind('submit', function() {
        angular.forEach(form, function(field, name) {
          if (typeof name === 'string' && !name.match('^[\$]')) {
            if (field.$pristine) {
              return field.$setViewValue(field.$value);
            }
          }
        });
        if (form.$valid) {
          return scope.$apply(attrs.submit);
        }
      });
    }
  };
});

다음과 같이 양식 html을 업데이트하십시오.

 <form ng-submit='justDoIt()'>

된다 :

 <form name='myForm' novalidate submit='justDoIt()'>

여기에서 전체 예를 참조하십시오. http://plunker.co/edit/QVbisEK2WEbORTAWL7Gu?p=preview


4

다음은 양식 오류 메시지를 표시하는 전역 함수입니다.

 function show_validation_erros(form_error_object) {
        angular.forEach(form_error_object, function (objArrayFields, errorName) {
            angular.forEach(objArrayFields, function (objArrayField, key) {
                objArrayField.$setDirty();
            });
        });
    };

그리고 내 모든 컨트롤러에서

if ($scope.form_add_sale.$invalid) { 
    $scope.global.show_validation_erros($scope.form_add_sale.$error);
}

1
이것은 질문에 대한 답이 아닙니다.
Rafael Herscovici

나는 내 대답을 바꿨다. 지금 확인하세요
Namal

2

Thilak의 답변을 바탕으로이 솔루션을 생각 해낼 수있었습니다.

내 양식 필드는 필드가 유효하지 않고 사용자가 터치 한 경우에만 유효성 검사 메시지를 표시하므로 버튼으로 트리거 된이 코드를 사용하여 유효하지 않은 필드를 표시 할 수있었습니다.

// Show/trigger any validation errors for this step
angular.forEach(vm.rfiForm.stepTwo.$error, function(error) {
  angular.forEach(error, function(field) {
    field.$setTouched();
  });
});
// Prevent user from going to next step if current step is invalid
if (!vm.rfiForm.stepTwo.$valid) {
  isValid = false;
}
<!-- form field -->
<div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }">

  <!-- field label -->
  <label class="control-label">Suffix</label>
  <!-- end field label -->
  <!-- field input -->
  <select name="Parent_Suffix__c" class="form-control"
          ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes"
          ng-model="rfi.contact.Parent_Suffix__c" />
  <!-- end field input -->
  <!-- field help -->
  <span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched">
    <span ng-message="required">this field is required</span>
  </span>  
  <!-- end field help -->
</div>
<!-- end form field -->


2

참고 : 이것이 해킹이라는 것을 알고 있지만 간단한 메커니즘을 제공하지 않은 Angular 1.2 및 이전 버전에서는 유용했습니다.

유효성 검사는 변경 이벤트에서 시작되므로 프로그래밍 방식으로 값을 변경하는 것과 같은 일부 항목은이를 트리거하지 않습니다. 그러나 변경 이벤트를 트리거하면 유효성 검사가 트리거됩니다. 예를 들어, jQuery를 사용하는 경우 :

$('#formField1, #formField2').trigger('change');

이 접근 방식은 간단합니다. 또한 Angular의 이전 (모든) 버전에서 작동한다는 이점이 있습니다.
Paul LeBeau

3
아니 angular way.
Rafael Herscovici

1

내가 원할 때 양식의 모든 필드의 유효성을 검사하려면 다음과 같이 $$ controls의 각 필드에 대한 유효성 검사를 수행합니다.

angular.forEach($scope.myform.$$controls, function (field) {
    field.$validate();
});


0

이것을 시도 할 수 있습니다.

// The controller

$scope.submitForm = function(form){
   		//Force the field validation
   		angular.forEach(form, function(obj){
   			if(angular.isObject(obj) && angular.isDefined(obj.$setDirty))
   			{ 
   				obj.$setDirty();
   			}
   		})
        
        if (form.$valid){
		
			$scope.myResource.$save(function(data){
		     	//....
			});
		}
}
<!-- FORM -->

  <form name="myForm"  role="form" novalidate="novalidate">
<!-- FORM GROUP to field 1 -->
  <div class="form-group" ng-class="{ 'has-error' : myForm.field1.$invalid && myForm.field1.$dirty }">
      <label for="field1">My field 1</label>
        <span class="nullable"> 
        <select name="field1" ng-model="myresource.field1" ng-options="list.id as list.name for list in listofall"
          class="form-control input-sm" required>
            <option value="">Select One</option>
        </select>
        </span>
        <div ng-if="myForm.field1.$dirty" ng-messages="myForm.field1.$error" ng-messages-include="mymessages"></div>
  </div>
    
<!-- FORM GROUP to field 2 -->
  <div class="form-group" ng-class="{ 'has-error' : myForm.field2.$invalid && myForm.field2.$dirty }">
    <label class="control-label labelsmall" for="field2">field2</label> 
      <input name="field2" min="1" placeholder="" ng-model="myresource.field2" type="number" 
      class="form-control input-sm" required>
    <div ng-if="myForm.field2.$dirty" ng-messages="myForm.field2.$error" ng-messages-include="mymessages"></div>
  </div>

  </form>

<!-- ... -->
<button type="submit" ng-click="submitForm(myForm)">Send</button>


0

나는 그것을 작동시키기 위해 다음과 같은 일을했다.

<form name="form" name="plantRegistrationForm">
  <div ng-class="{ 'has-error': (form.$submitted || form.headerName.$touched) && form.headerName.$invalid }">
    <div class="col-md-3">
      <div class="label-color">HEADER NAME 
        <span class="red"><strong>*</strong></span></div>
    </div>
    <div class="col-md-9">
      <input type="text" name="headerName" id="headerName" 
             ng-model="header.headerName" 
             maxlength="100" 
             class="form-control" required>
      <div ng-show="form.$submitted || form.headerName.$touched">
        <span ng-show="form.headerName.$invalid" 
              class="label-color validation-message">Header Name is required</span>
      </div>
    </div>
  </div>

  <button ng-click="addHeader(form, header)" 
          type="button" 
          class="btn btn-default pull-right">Add Header
  </button>

</form>

컨트롤러에서 할 수 있습니다.

addHeader(form, header){
        let self = this;
        form.$submitted = true;
        ... 
    }

CSS도 필요합니다.

.label-color {
            color: $gray-color;
        }
.has-error {
       .label-color {
            color: rgb(221, 25, 29);
        }
        .select2-choice.ui-select-match.select2-default {
            border-color: #e84e40;
        }
    }
.validation-message {
       font-size: 0.875em;
    }
    .max-width {
        width: 100%;
        min-width: 100%;
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.