angularJS中的动态表单验证无效

时间:2022-11-24 19:39:37

I have created dynamic form, And adding the ng-required attributes dynamically to my controls. but now it's not working .

我创建了动态表单,并动态地将ng-required属性添加到我的控件中。但现在它不起作用。

This is my JS :

这是我的JS:

    var app = angular.module('birthdayToDo', []);

    app.controller('main', function($scope){ 
      $scope.Control={};
     $scope.Attributes =[
   {
     "Name":"FirstName",
     "Required":true
   },
   {
     "Name":"LastName",
     "Required":false
   },
   {
     "Name":"Email",
     "Required":true
   },
   {
     "Name":"Age",
     "Required":false
   }];

        $scope.submitForm = function(isValid) {

            // check to make sure the form is completely valid
            if (isValid) { 
                alert('our form is amazing');
                alert($scope.Control[1]);  // to check correct index
            }else{
              return;
            }

        };
    });

And My HTML :

我的HTML:

<html>

<head lang="en">

  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
  <script src="app.js"></script>

</head>

<body ng-app="birthdayToDo" ng-controller="main">
  <form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate>
    <table>
      <tr ng-repeat="attribute in Attributes">
        <td>{{attribute.Name}}</td>
        <td>
          <input type="text" name="Control[$index]" ng-model="Control[$index]" ng-required="{{attribute.Required}}" />
        </td>
        <td>
         <p ng-show="userForm.Control[$index].$error.required">{{attribute.Required == "true" && attribute.Name+' Required' || ''}}</p>
        </td>
      </tr>
    </table>
    <input type="submit" value="Save" />
  </form>
</body>

Plunker Link

I want to show error message when either the textbox value change or form is submitted .

我想在提交文本框值更改或表单时显示错误消息。

But when I'm doing same thing with static form it's working. working plunker

但是当我用静态形式做同样的事情时,它正在发挥作用。工作的plunker

1 个解决方案

#1


5  

Dynamic control names and form validation does not work that well with older angular versions (< 1.3.x). And to add to that you have a very old angular version (1.0.3). If you upgrade to 1.3.x version of angular you could easily achieve this with some changes (some of them you need anyways):

对于较旧的角度版本(<1.3.x),动态控件名称和表单验证效果不佳。另外,你有一个非常古老的角度版本(1.0.3)。如果升级到1.3.x版本的角度,你可以通过一些更改轻松实现这一点(其中一些你还需要):

1) As mentioned by @dfsq you need to provide a boolean value to ng-required bound scope property otherwise you will end up setting truthy "true"/"false" to the controls and it will make everything required.

1)正如@dfsq所提到的,你需要为ng-required绑定范围属性提供一个布尔值,否则你最终会向控件设置truthy“true”/“false”,它将完成所需的一切。

2) Use ng-attr-name to provide interpolated dynamic names. It will automatically expand to name attribute.

2)使用ng-attr-name提供插值动态名称。它会自动扩展为name属性。

3) With 1.3 form controller sets an $error.required property on a property with the same name as that of the control and there are some more special properties it populates. You can always track total number of required errors with form.$error.$required.length

3)使用1.3表单控制器在属性上设置$ error.required属性,该属性与控件的名称相同,并且它会填充一些更特殊的属性。您始终可以使用表单跟踪所需错误的总数。$ error。$ required.length

4) Do not use index to set the ng-model, use the proper attribute name itself so that it is more readable and easy to manage.

4)不要使用索引来设置ng-model,使用适当的属性名称本身,使其更易读,更易于管理。

5) You could also utilize one-time binding (::) to avoid unwanted watches, example field names, display names, required attributes which if they are non changing lists.

5)您还可以利用一次性绑定(::)来避免不需要的监视,示例字段名称,显示名称,必需属性(如果它们是非更改列表)。

6) You can use form controller's special properties to manage your validations and other behaviors and interactions as you need. Here is a sample demo which just utilized only a small subset of what form controller provides.

6)您可以使用表单控制器的特殊属性来根据需要管理验证和其他行为和交互。这是一个示例演示,它只使用了控制器提供的一小部分形式。

View:

<form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate>
    <table>
      <tr ng-repeat="attribute in Attributes">
        <td>{{::attribute.Name}}</td>
        <td>
          <input type="text" ng-attr-name="{{::attribute.Name}}" ng-model="Control[attribute.Name]" ng-required="::attribute.Required" />
        </td>
        <td>
          <p ng-if="userForm[attribute.Name].$error.required" class="error">{{attribute.Name }} Required</p>
        </td>
      </tr>
    </table>
    <input type="submit" value="Save" ng-disabled="userForm.$invalid"/>{{Control}}
  </form>

Controller:

 /* Set proper boolean values to Required*/
 $scope.Attributes = [{
    "Name": "FirstName",
    "Required": true
  }, {
    "Name": "LastName",
    "Required": false
  }, {
    "Name": "Email",
    "Required": true
  }, {
    "Name": "Age",
    "Required": false
  }];

  $scope.submitForm = function(isValid) {

    // check to make sure the form is completely valid
    if (isValid) {
     /*Now control will have proper property names with respective ngmodel names*/
      console.log($scope.Control); 
    } else {
      return;
    }

  };

Sample Demo

var app = angular.module('birthdayToDo', []);

app.controller('main', function($scope) {

  $scope.Control = {};

  //Set boolean values to Required
  $scope.Attributes = [{
    "Name": "FirstName",
    "Required": true 
  }, {
    "Name": "LastName",
    "Required": false
  }, {
    "Name": "Email",
    "Required": true
  }, {
    "Name": "Age",
    "Required": false
  }];

  $scope.submitForm = function(isValid) {


    if (isValid) {
      alert('our form is amazing');
      console.log($scope.Control); /*Use Controle object which has proper property names to reflect respective ngModel*/
    } else {
      return;
    }

  };
});
.error {
  color: red;
}
input.ng-invalid {
  border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
<div ng-app="birthdayToDo" ng-controller="main">
  <form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate>
    <table>
      <tr ng-repeat="attribute in Attributes">
        <td>{{::attribute.Name}}</td>
        <td>
          <input type="text" ng-attr-name="{{::attribute.Name}}" ng-model="Control[attribute.Name]" ng-required="::attribute.Required" />
        </td>
        <td>
          <p ng-if="userForm[attribute.Name].$error.required" class="error">{{attribute.Name }} Required</p>
        </td>
      </tr>
    </table>
    <input type="submit" value="Save" ng-disabled="userForm.$invalid"/>{{Control}}
  </form>
</div>

#1


5  

Dynamic control names and form validation does not work that well with older angular versions (< 1.3.x). And to add to that you have a very old angular version (1.0.3). If you upgrade to 1.3.x version of angular you could easily achieve this with some changes (some of them you need anyways):

对于较旧的角度版本(<1.3.x),动态控件名称和表单验证效果不佳。另外,你有一个非常古老的角度版本(1.0.3)。如果升级到1.3.x版本的角度,你可以通过一些更改轻松实现这一点(其中一些你还需要):

1) As mentioned by @dfsq you need to provide a boolean value to ng-required bound scope property otherwise you will end up setting truthy "true"/"false" to the controls and it will make everything required.

1)正如@dfsq所提到的,你需要为ng-required绑定范围属性提供一个布尔值,否则你最终会向控件设置truthy“true”/“false”,它将完成所需的一切。

2) Use ng-attr-name to provide interpolated dynamic names. It will automatically expand to name attribute.

2)使用ng-attr-name提供插值动态名称。它会自动扩展为name属性。

3) With 1.3 form controller sets an $error.required property on a property with the same name as that of the control and there are some more special properties it populates. You can always track total number of required errors with form.$error.$required.length

3)使用1.3表单控制器在属性上设置$ error.required属性,该属性与控件的名称相同,并且它会填充一些更特殊的属性。您始终可以使用表单跟踪所需错误的总数。$ error。$ required.length

4) Do not use index to set the ng-model, use the proper attribute name itself so that it is more readable and easy to manage.

4)不要使用索引来设置ng-model,使用适当的属性名称本身,使其更易读,更易于管理。

5) You could also utilize one-time binding (::) to avoid unwanted watches, example field names, display names, required attributes which if they are non changing lists.

5)您还可以利用一次性绑定(::)来避免不需要的监视,示例字段名称,显示名称,必需属性(如果它们是非更改列表)。

6) You can use form controller's special properties to manage your validations and other behaviors and interactions as you need. Here is a sample demo which just utilized only a small subset of what form controller provides.

6)您可以使用表单控制器的特殊属性来根据需要管理验证和其他行为和交互。这是一个示例演示,它只使用了控制器提供的一小部分形式。

View:

<form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate>
    <table>
      <tr ng-repeat="attribute in Attributes">
        <td>{{::attribute.Name}}</td>
        <td>
          <input type="text" ng-attr-name="{{::attribute.Name}}" ng-model="Control[attribute.Name]" ng-required="::attribute.Required" />
        </td>
        <td>
          <p ng-if="userForm[attribute.Name].$error.required" class="error">{{attribute.Name }} Required</p>
        </td>
      </tr>
    </table>
    <input type="submit" value="Save" ng-disabled="userForm.$invalid"/>{{Control}}
  </form>

Controller:

 /* Set proper boolean values to Required*/
 $scope.Attributes = [{
    "Name": "FirstName",
    "Required": true
  }, {
    "Name": "LastName",
    "Required": false
  }, {
    "Name": "Email",
    "Required": true
  }, {
    "Name": "Age",
    "Required": false
  }];

  $scope.submitForm = function(isValid) {

    // check to make sure the form is completely valid
    if (isValid) {
     /*Now control will have proper property names with respective ngmodel names*/
      console.log($scope.Control); 
    } else {
      return;
    }

  };

Sample Demo

var app = angular.module('birthdayToDo', []);

app.controller('main', function($scope) {

  $scope.Control = {};

  //Set boolean values to Required
  $scope.Attributes = [{
    "Name": "FirstName",
    "Required": true 
  }, {
    "Name": "LastName",
    "Required": false
  }, {
    "Name": "Email",
    "Required": true
  }, {
    "Name": "Age",
    "Required": false
  }];

  $scope.submitForm = function(isValid) {


    if (isValid) {
      alert('our form is amazing');
      console.log($scope.Control); /*Use Controle object which has proper property names to reflect respective ngModel*/
    } else {
      return;
    }

  };
});
.error {
  color: red;
}
input.ng-invalid {
  border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
<div ng-app="birthdayToDo" ng-controller="main">
  <form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate>
    <table>
      <tr ng-repeat="attribute in Attributes">
        <td>{{::attribute.Name}}</td>
        <td>
          <input type="text" ng-attr-name="{{::attribute.Name}}" ng-model="Control[attribute.Name]" ng-required="::attribute.Required" />
        </td>
        <td>
          <p ng-if="userForm[attribute.Name].$error.required" class="error">{{attribute.Name }} Required</p>
        </td>
      </tr>
    </table>
    <input type="submit" value="Save" ng-disabled="userForm.$invalid"/>{{Control}}
  </form>
</div>