【问题标题】:How to display angular form validation error inside angular bootstrap popover?如何在角度引导弹出窗口中显示角度表单验证错误?
【发布时间】:2017-02-07 07:42:58
【问题描述】:

我是 Angular js 的新手。我想在元素右侧的角度引导弹出窗口中显示表单错误。我尝试创建指令,当它更改类时我得到了一个元素。但我不知道下一步该怎么走。

(function(angular) {
  'use strict';
var app=angular.module('formExample', [])
  .controller('ExampleController', ['$scope', function($scope) {
    $scope.master = {};

    $scope.update = function(user) {
      $scope.master = angular.copy(user);
    };

    $scope.reset = function(form) {
      if (form) {
        form.$setPristine();
        form.$setUntouched();
      }
      $scope.user = angular.copy($scope.master);
    };

    $scope.reset();
  }]);
app.directive("alert", function(){
    return {
        restrict: 'C',
        priority: -1000,
        link: function(scope, ele, attrs, ctrl){
          scope.$watch(function() {console.log(ele.attr('class')); })
          if (ctrl) {
            console.log("applying custom behaviour to input: ", ele.attr('id'));
            // ... awesomeness here
          }
        }
    };
});
})(window.angular);

我只想显示错误信息

  1. 当用户点击保存按钮时(所有表单字段错误消息)
  2. 元素模糊(仅针对失去焦点的元素)

这是我的plnkr,我试图通过它来获取消息。

更新

不知何故,我显示了角度引导弹出框和关闭弹出框的关闭按钮。

我当前的plunker有两个问题。

  1. 我想在弹出框模板中显示错误消息 相对于它被打开的元素。我需要这个 模板,因为我需要一个关闭按钮。
  2. 一旦我关闭了弹出框,如果该字段为空并且用户单击 提交弹出框下次不打开。我想显示错误 每次提交时都会发送消息。

【问题讨论】:

  • 根据我的经验,uib-popovers 并非旨在处理此类动态内容(如错误验证)。我在一个项目中尝试了类似的方法,但最终不值得使用uib-popover。相反,我们只是使用 css 和 ng-class 来模仿弹出框的感觉。然后我们的指令只需要根据我们的表单处理何时隐藏/显示“弹出框”。
  • 请看下面我的回答

标签: angularjs popover angular-bootstrap


【解决方案1】:

如何把你的模板像这样:

<script type="text/ng-template" id="myPopoverTemplate.html">
  <div class="gmePopover">
    <div class="popover-header">
      <button type="button" class="close" popover-toggle><span aria-hidden="true">&times;</span></button>
    </div>
    <div class="popover-content">
        somecontent
    </div>
  </div>
</script>

工作 Plunker here.

更新:

您可以使用 angularjs foreach 循环遍历表单中的所有错误,然后从那里您可以显示基于元素的弹出框。像这样:working plunker

<script type="text/javascript">
  var app=angular.module('testApp', ['ngAnimate', 'ngSanitize'], function($httpProvider) {});
  app.controller("PopoverDemoCtrl", function($scope, $http, $window) {
    $scope.validate = function() {
        var _popover;
        var error = $scope.testForm.$error;
        angular.forEach(error.required, function(field){
            var message = 'This field (' + field.$name + ') is required';
            _popover = $('#' + field.$name).popover({
              trigger: 'manual',
              title: '<span class="text-info"><strong>title</strong></span>'+
            '<button type="button" id="close" class="close" onclick="$(&quot;#' + field.$name + '&quot;).popover(&quot;hide&quot;);">&times;</button>',
              content: message,
              html: true
            });

            return $('#' + field.$name).popover("show")
        });
    };
  });
</script>

【讨论】:

  • 我需要对应于父元素的弹出框内容。我不知道我更新的 plunker 和你的有什么区别。
  • 不同之处:我将 myPopoverTemplate.html 放在了一个 ng-template 中。我不确定相对于父元素是什么意思。一个简化的例子会有所帮助,我们可以提供帮助。
  • 好的,例如,在给定的 plunker 中,考虑第一个文本框是用户名和第二个文本框密码。如果用户点击提交按钮,没有输入任何值(即两个文本框都是空的),那么我们必须在第一个弹出窗口中显示“请输入用户名”,在第二个弹出窗口中我们必须显示“请输入密码”。
  • ...如果我们可以找出已经打开弹出框的元素,有没有办法。当我打印错误对象时,如果元素与特定模式不匹配,那么对于同一个元素,我会在错误中得到两个对象。在这种情况下,我必须停止打开另一个 popover 的元素。即,Required 不仅是验证。
  • 未测试,但我相信你想要 $yourElement.data()['bs.popover'].tip().hasClass('in') 如果弹出框可见,它将返回 true 跨度>
【解决方案2】:

您可以创建一个指令来拦截FormController$setSubmitted 方法。

你可以找到更多关于方法here的信息

请找到工作示例here

当此指令拦截$setSubmitted 方法时,我们可以通知另一个指令以在bootstrap popover 中显示验证错误。

我在以下假设下工作(请随时纠正我):

  • 您将使用表单标签
  • 在您的表单标签上,您将拥有ng-submit="nameOfForm.$valid &amp;&amp; vm.onSubmit()"

该解决方案适用于两个指令:

submitNotifypopoverValidation

submitNotify 通知popoverValidation 提交表单时,popoverValidation 指令然后显示表单错误(如果有)。

指令 1:submitNotify

directive('submitNotify', function () {
    return {
        restrict: 'A',
        require: 'form',
        controller: function SubmitNotify() { },
        link: function (scope, element, attrs, form) {                
            var $setSubmitted = form.$setSubmitted;
            form.$setSubmitted = function () {
                $setSubmitted.bind(form)();
                scope.$broadcast('onSubmitNotify');
            };
        }
    };
})

说明:

  • 只能用作属性指令
  • 需要form 标签或ngForm

链接功能:

链接函数将$setSubmitted 函数替换为回调函数。回调函数通知popoverValidation指令表单已经提交。

指令 2:popoverValidation

directive('popoverValidation', [function () {
    return {
        restrict: 'A',
        require: ['ngModel', '^submitNotify'],
        link: function (scope, element, attrs, require) {
            scope.$on('onSubmitNotify', function () {
                var ngModel = require[0];
                if (!ngModel.$valid) {
                    showPopover(ngModel.$error);
                }
            });

            function showPopover( $error) {
                var options = {
                    content: getValidationErrorsHtml($error),
                    html: true,
                    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content popover-content-errors"></div></div>',
                    title: '<span class="text-info"><strong>Error</strong></span><button type="button" data-dismiss="popover" class="close">&times;</button>',
                    trigger: 'manual'
                }
                $(element).popover(options);
                $(element).on('shown.bs.popover', hidePopover);
                $(element).popover('show');                    
            }

            function hidePopover() {
                $(this).next('.popover').find('button[data-dismiss="popover"]').click(function (e) {
                    $(element).popover('hide');
                });
            }

            function getValidationErrorsHtml($error) {
                var errors = [];

                if ($error.required) {
                    errors.push(requiredErrorMessage());
                }

                if ($error.email) {
                    errors.push(invalidEmailAddress());
                }

                var errorHtml = '<ul class="list-group">';

                for (var i = 0; i < errors.length; i++) {
                    errorHtml += '<li class="list-group-item">' + errors[i] + '</li>';
                }

                errorHtml += '</ul>';

                return errorHtml;
            }

            function requiredErrorMessage() {
                return 'This field is required';
            }

            function invalidEmailAddress() {
                return 'Please enter a valid email address';
            }
        }
    };
}]);

说明:

  • 只能用作属性指令
  • 需要父 form 上的 submitNotify 标签

链接功能:

  • popoverValidation 指令收到表单已提交的通知
  • 它检查ng-model 绑定的属性是否有效
  • 如果无效,则会显示弹出框

完整的 HTML:

<form name="myForm" ng-controller="MyFormController as vm" ng-submit="myForm.$valid && vm.onSubmit()" submit-notify="" novalidate>
    <div class="panel panel-primary">
        <div class="panel-heading">Form Validation with Popovers</div>
        <div class="panel-body">
            <div class="form-group">
                <label>First name</label>
                <input type="text" name="firstName" class="form-control" required ng-model="person.firstName" popover-validation="" />
            </div>
            <div class="form-group">
                <label>Surname</label>
                <input type="text" name="surname" class="form-control" required ng-model="person.surname" popover-validation="" />
            </div>
            <div class="form-group">
                <label>Email</label>
                <input type="email" name="email" class="form-control" ng-model="person.email" popover-validation="" />
            </div>
        </div>
        <div class="panel-footer">
            <button type="submit" class="btn btn-success">Submit</button>
        </div>
    </div>
</form>

一些 CSS:

<style type="text/css">
    .popover-content-errors {
        padding:0px;
    }

    .popover-content-errors .list-group {
        margin-bottom:0px
    }

    .popover-content-errors .list-group-item {
        border-left:none;
        white-space:nowrap;
    }

    .popover-content-errors .list-group-item:first-child {
        border-top:none;
    }

    .popover-content-errors .list-group-item:last-child {
        border-bottom:none;
    }
</style>

我的表单控制器

controller('MyFormController', ['$scope', function ($scope) {
    var self = this;
    $scope.person = {
        email:'john.doe.com'
    }
    self.onSubmit = function () {   
        console.log('MyFormController.onSubmit');
    };
}]);

【讨论】:

  • ...我没有完全通过。但是我刚刚进入 plunker 并输入了正确的电子邮件地址。错误仍然没有消失。
猜你喜欢
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多