提交后,将自定义消息添加到表单字段

时间:2016-04-28 11:32:17

标签: angularjs angular-formly

我有一种形式,我不知道我将提前收到什么验证错误。所以,我的计划是:将表单提交给服务器,如果存在则返回错误,然后将错误消息添加到相关字段。我的代码是这样的:



/* global angular */
(function() {

  'use strict';

  var app = angular.module('formlyExample', [
    'formly',
    'formlyBootstrap',
    'ngAnimate',
    'ngMessages'
  ]);

  app.run(function(formlyConfig, formlyValidationMessages) {
    formlyConfig.extras.errorExistsAndShouldBeVisibleExpression = 'fc.$touched || form.$submitted';
  });

  app.config(function(formlyConfigProvider) {

    formlyConfigProvider.setWrapper({
      name: 'validation',
      types: ['input'],
      templateUrl: 'error-messages.html'
    });

  });

  app.controller('MainCtrl', function MainCtrl(formlyVersion) {
    var vm = this;
    // funcation assignment
    vm.onSubmit = onSubmit;
    vm.env = {
      angularVersion: angular.version.full,
      formlyVersion: formlyVersion
    };

    vm.model = {};
    vm.options = {};

    vm.fields = [{
      key: 'coolValue',
      type: 'input',
      templateOptions: {
        required: false,
        type: 'text',
        label: 'Cool Value'
      }
    }, ];

    vm.originalFields = angular.copy(vm.fields);

    // function definition
    function onSubmit() {
      //if (vm.form.$valid) {
      //    vm.options.updateInitialValue();
      //   alert(JSON.stringify(vm.model), null, 2);
      // }
    }
  });

})();

body {
  margin: 20px
}
.formly-field {
  margin-bottom: 26px;
}
.error-messages {
  position: relative;
}
.error-messages,
.message {
  opacity: 1;
  transition: .3s linear all;
}
.message {
  font-size: .8em;
  position: absolute;
  width: 100%;
  color: #a94442;
  margin-top: 2px;
}
.error-messages.ng-enter.ng-enter-active,
.message.ng-enter.ng-enter-active {
  opacity: 1;
  top: 0;
}
.error-messages.ng-enter,
.message.ng-enter {
  opacity: 0;
  top: -10px;
}
.error-messages.ng-leave,
.message.ng-leave {
  opacity: 1;
  top: 0;
}
.error-messages.ng-leave-active,
.message.ng-leave-active {
  opacity: 0;
  top: -10px;
}

<!DOCTYPE html>
<html>

<head>
  <!-- Twitter bootstrap -->
  <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">

  <!-- apiCheck is used by formly to validate its api -->
  <script src="//npmcdn.com/api-check@latest/dist/api-check.js"></script>
  <!-- This is the latest version of angular (at the time this template was created) -->
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>

  <!-- This is the latest version of formly core. -->
  <script src="//npmcdn.com/angular-formly@latest/dist/formly.js"></script>
  <!-- This is the latest version of formly bootstrap templates -->
  <script src="//npmcdn.com/angular-formly-templates-bootstrap@latest/dist/angular-formly-templates-bootstrap.js"></script>

  <script src="https://rawgit.com/angular/bower-angular-messages/v1.4.4/angular-messages.js"></script>
  <script src="https://rawgit.com/angular/bower-angular-animate/v1.4.4/angular-animate.js"></script>

  <title>Angular Formly Example</title>
</head>

<body ng-app="formlyExample" ng-controller="MainCtrl as vm">
  <div>
    <form ng-submit="vm.onSubmit()" name="vm.form" novalidate>
      <formly-form model="vm.model" fields="vm.fields" options="vm.options" form="vm.form">
        <button type="submit" class="btn btn-primary submit-button">Submit</button>
        <button type="button" class="btn btn-default" ng-click="vm.options.resetModel()">Reset</button>
      </formly-form>
    </form>
  </div>

  <!-- Put custom templates here -->
  <script type="text/ng-template" id="error-messages.html">
    <formly-transclude></formly-transclude>
    <div ng-messages="fc.$error" ng-if="form.$submitted || options.formControl.$touched" class="error-messages">
      <div ng-message="{{ ::name }}" ng-repeat="(name, message) in ::options.validation.messages" class="message">{{ message(fc.$viewValue, fc.$modelValue, this)}}</div>
    </div>
  </script>
</body>

</html>
&#13;
&#13;
&#13;

和JSBin页面:http://jsbin.com/nupumakata/edit?html,js,output

我尝试做的事情:只要点击提交按钮,就应该在Cool Value字段中添加自定义验证消息。由于我事先并不知道会出现什么错误,因此我无法事先配置消息。所以这个:

formlyValidationMessages.addTemplateOptionValueMessage('pattern', 'patternValidationMessage', '', '', 'Invalid Input');

不行。在我正在寻找的答案中,消息是从提交功能内部添加的,仅在按下提交按钮后显示(在按下提交按钮之前不会显示错误)。我无法在Formly文档中找到如何执行此操作。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

所以我所做的就是我继续前进并为该字段提供如下自定义模板:

 formlyConfigProvider.setWrapper({
      name: 'inputWrapper',
  template: '<div ng-class="to.changeColor==\'red\'? \'redBorder\' : \'otherBorder\'"><formly-transclude></formly-transclude>{{to.keyVal}}</div>'
    });

表单元素通过模式格式定义,以允许单独访问每个元素。

vm.schema={
    "schema": {
        "coolValue" : [{
                "key": "coolValue",
                "type": "input",

          "wrapper": ['inputWrapper'],
                "templateOptions": {
                   "type" : "text",
                  "label": 'Cool Value',
                  "keyVal":"",
                  "changeColor":"green"
                }

         }]


    }

};

最后,onSubmit函数

function onSubmit() {

//Do whatever you want here
//Let's say your server returns an error "iNVALID Credentials"
   var response={
  "error": {
    "errors": [
      {
        "domain": "global",
        "reason": "authError",
        "message": "Invalid Credentials",
        "locationType": "header",
        "location": "Authorization",
      }
    ],
    "code": 401,
    "message": "Invalid Credentials"
  }
};
vm.schema.schema.coolValue[0].templateOptions.changeColor="red";
      vm.schema.schema.coolValue[0].templateOptions.keyVal=response.error.message;

    }
  });

您实际上可以从服务器传递任何错误消息或响应。

CSS包含一个用于向字段添加红色border的类。您可以自由禁用此功能。如果您在此区域也需要任何内容​​,请随意ping。

这是DEMO

答案 1 :(得分:0)

这是我的jsbin

注意

  1. 我还没有采用棱角分明的形式。所以它可能不是最有效的解决方案。但它确实能满足您的需求。
  2. 我已对您的error-template.htmlvm.fields.templateOptions
  3. 进行了更改
  4. 我创建了一个新字段vm.fields.tempalteOptions.customErrorMessage。我从onSubmit()
  5. 更改此字段的值
  6. 为了保持示例简单,我正在做vm.fields[0].templateOptions.customErrorMessage = "Custom error message from rest service";。您可以按field获取vm.fields.key,而不是按索引获取vm.fields[0]
  7. 同样为了保持答案简单并避免注意不必要的细节我已经为此输入标记了required:true,这在您的情况下是错误的。因此,在您的代码中,您可以使用formly编写自定义验证器,然后当rest服务返回特定字段的错误时,使此验证器将验证设置为无效,然后显示自定义消息。 custom validator
  8. 希望以上解决你的问题。如果您需要更多帮助,请告诉我。