I am new to angular js. I want to show the form error in angular bootstrap popover at the right hand side of the element.I tried to create the directive and I got an element when it changes classes. But I don't have an idea how to move next.
(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);
I just want to show the error message
Here is my plnkr which I tried to get the message.
Update
Somehow I displayed the angular bootstrap popover and close button which closes the popover.
I have two issues in the current plunker.
How about putting your template like this:
<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>
Working Plunker here.
UPDATE:
You can use angularjs foreach to loop through all errors in your form, then from there you can show the popover base on your element. Something like this: 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="$("#' + field.$name + '").popover("hide");">×</button>',
content: message,
html: true
});
return $('#' + field.$name).popover("show")
});
};
});
</script>
You can create a directive that intercepts the $setSubmitted
method of the FormController
.
You can find more information regarding the method here
Please find working example here
When this directive intercepts the $setSubmitted
method, we can notify another directive to show the validation errors in a bootstrap popover.
I am working under the following assumptions(feel free to correct me):
ng-submit="nameOfForm.$valid && vm.onSubmit()"
The solution works with two directives:
submitNotify
and popoverValidation
submitNotify
notifies popoverValidation
when the form is submitted, the popoverValidation
directive then shows the form errors if there are any.
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
tag, or ngForm
The link function replaces the $setSubmitted
function with a callback function. The callback function notifies the popoverValidation
directive that the form has been submitted.
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
tag on the parent form
popoverValidation
directive gets notified that the form is submittedng-model
binded property is validComplete 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>
<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');
};
}]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With