如何在输入更改之前显示错误消息?

时间:2014-09-24 05:11:12

标签: javascript angularjs

我有一个带有服务器端验证的表单。如果服务器返回验证错误,我想在表单中显示它们,但只有在用户编辑任何内容之前。

理想情况下,我希望有类似的内容:

<form name='MyForm' ng-submit='doSomething()'>
    <label for='my-field-id'>Some field</label>
    <input type='text' id='my_field_id' ng-model='myField' name='my_field'>
    <div ng-show-if-changed='MyForm.my_field.serverSideError'
         ng-show-until='MyForm.my_field.changed'>Error!</div>
</form>

如何实现这种行为?我真的想避免将这个逻辑放在一个控制器中,并希望提出一些聪明的可重用指令。

更新

这里主要是如何实现ng-show-until-changed功能。它的逻辑必须是“如果显示一个元素并且目标被改变 - 隐藏它”。这里的问题是:

  • 如果目标只是某个范围变量,例如MyForm.my_field.serverSideError - 我可能需要在更改时手动启动$digest吗?例如,在AJAX请求完成后,可能会有一些错误从服务器到达?如何正确监视这些服务器端错误的变化?
  • 以与ng-show指令相同的方式隐藏/显示自定义指令中的某个元素的正确方法是什么?是否有一些内置的实用工具?

2 个答案:

答案 0 :(得分:0)

最简单和最原始的方法是在表单中添加一个文本框,并将其设置为只读,这样用户就无法对其执行任何操作。但您仍然可以使用JavaScript将文本放入框中,例如从服务器获取的错误消息。当然,您可以随时擦除文本(例如,由用户编辑的数据输入字段的onkeydown事件处理程序触发)。

类似且更优雅的方式涉及表单HTML中的<p>元素,位于您希望用户进行某些编辑的位置附近:

<p id="errmsg">&nbsp;</p>

在你的Javascript中你会做这样的事情,准备:

var P=document.getElementById("errmsg");

然后,当您需要从服务器显示错误消息时:

P.innerHTML="Text of error message";

当用户开始编辑时(再次使用onkeydown事件处理程序进行检测),您可以将错误消息文本替换为另一个&nbsp;

如果你真的想隐藏/显示错误信息,你可以考虑构建几个段落,所有段落都有相同的行数。每个都包含预先写好的错误消息,尽管其中一个可能是关于应该输入的数据的指令。这是默认显示的那个。所有段落都可以堆叠在表单的相同位置,这样:

<div style="position:relative;">
 <p id="p1" style="position:absolute;top='0px';left='0px';" hidden="">paragraph 1 text</p>
 <p id="p2" style="position:absolute;top='0px';left='0px';" hidden="hidden">paragraph 2</p>
 <p id="p3" style="position:absolute;top='0px';left='0px';" hidden="hidden">paragraph 3</p>
</div>
<br /> <!-- you will discover that some line-breaks are needed here -->
<br />

您将再次使用JavaScript来获取每个段落的getElementById(),或许可以使用P []变量数组。然后,您可以使用

隐藏或显示任何段落
P[x].hidden="hidden";
P[x].hidden="";

答案 1 :(得分:0)

您可以在模型更改时隐藏错误消息,并在提交时出现错误时再次显示错误消息。 请参阅下面的示例或[plunker] [1]

&#13;
&#13;
<!DOCTYPE html>
<html>

<head>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
</head>

<body ng-app="changeExample">
  <!-- snippet adapted from https://docs.angularjs.org/api/ng/directive/ngChange. -->
  <script>
    angular.module('changeExample', [])
      .controller('ExampleController', [
        '$scope',
        function($scope) {
          var model;

          function simulateError(model) {
            model.hasError = true;
            model.errorMessage = "Some validation error!"
          }

          $scope.model = model = {
            myField: 'my field value',
            hasError: false,
            errorMessage: '',
            changed: false
          };

          $scope.change = function() {
            model.hasError = false; // soon as the model changes unset the error.
          };

          $scope.doSomething = simulateError;
        }
      ]);
  </script>
  <!-- 
        snippet adapted from SO question
        NOTES: 
        - using ng-change to listen to input field changes
        - ng-trim="false" to listen to whitespace e.g spacebar
        - hide error when user uses text input field
    -->

  <form name="myForm" ng-controller="ExampleController" ng-submit="doSomething(model)">
    <label for="my-field-id">Fill in:</label>
    <input type="text" id="my_field_id" ng-model="model.myField" ng-change="change()" ng-trim="false" />
    <input type="submit" />
    <div ng-show="model.hasError" ng-bind="model.errorMessage">
      Error from server goes here!
    </div>
  </form>
</body>

</html>
&#13;
&#13;
&#13;   [1]:http://plnkr.co/edit/BNBgiT?p=preview

相关问题