Как отобразить angular ошибку проверки формы внутри angular bootstrap popover?
Я новичок в angular js. Я хочу показать ошибку формы в angular bootstrap popover в правой части элемента. Я попытался создать директиву, и я получил элемент, когда он меняет классы. Но я не знаю, как двигаться дальше.
(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);
Я просто хочу показать сообщение об ошибке
-
, когда пользователь нажимает кнопку сохранения (все сообщения об ошибках формы)
-
размытие элемента (только для элемента, который потерял фокус)
Вот мой plnkr, который я пытался получить.
Обновить
Как-то я отобразил кнопку angular bootstrap popover и close, которая закрывает popover.
У меня есть две проблемы в текущем plunker.
- Я хочу отобразить сообщение об ошибке внутри моего шаблона popover
соответствующий элементу, где он открывается. мне нужно это
шаблон, потому что мне нужна кнопка закрытия.
- Как только я закрыл popover, если поле пустое и пользователь нажимает
отправить popover не открывается в следующий раз. Я хочу показать ошибку
сообщение каждый раз при отправке.
Ответы
Ответ 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">×</span></button>
</div>
<div class="popover-content">
somecontent
</div>
</div>
</script>
Рабочий Plunker здесь.
UPDATE:
Вы можете использовать angularjs foreach, чтобы перебирать все ошибки в вашей форме, а затем оттуда вы можете показать базу popover для своего элемента. Что-то вроде этого: рабочий плункер
<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="$("#' + field.$name + '").popover("hide");">×</button>',
content: message,
html: true
});
return $('#' + field.$name).popover("show")
});
};
});
</script>
Ответ 2
Вы можете создать директиву, которая перехватывает метод $setSubmitted
FormController
.
Подробнее о методе здесь
Пожалуйста, найдите рабочий пример здесь
Если эта директива перехватывает метод $setSubmitted
, мы можем уведомить другую директиву о том, чтобы показать ошибки проверки в bootstrap popover.
Я работаю при следующих предположениях (не стесняйтесь исправлять меня):
- вы будете использовать тег формы
- в теге формы вы получите
ng-submit="nameOfForm.$valid && vm.onSubmit()"
Решение работает с двумя директивами:
submitNotify
и popoverValidation
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">×</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';
}
}
};
}]);
Пояснение:
- Может использоваться только как директива атрибута
- Требуется тег
submitNotify
в родительском form
Функция связи:
- Директива
popoverValidation
получает уведомление о том, что форма отправлена
- Проверяет, действительно ли свойство привязано
ng-model
- Если недействительно, отображается popover.
Завершить 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>
MyFormController
controller('MyFormController', ['$scope', function ($scope) {
var self = this;
$scope.person = {
email:'john.doe.com'
}
self.onSubmit = function () {
console.log('MyFormController.onSubmit');
};
}]);