Form Validation in IE8 using Angular UI & webshims - angularjs

I am using webshims for HTML support in IE8. My HTML form validation is working in IE8. But when I have a form in a popup (I am using Angular UI Modal), on form submit(ng-submit) the modal box closes and the validation message appears on top right corner.
My Environment is
jquery-1.11.1.js
AngularJS v1.2.26
Angular UI Modal 0.10.0
webshim-1.15.4
In the console I get this script error
"invalid element seems to be hidden. Make element either visible or use disabled/readonly to bar elements from validation. With With fieldset[disabled] a group of elements can be ignored! In case of select replacement see shims/form-combat.js to fix issue."
part my Angular app HTML loading webshims
<script src="resources/js/jquery-1.11.1.js"></script>
<script src="resources/js/js-webshim/minified/polyfiller.js"></script>
<script>
$.webshims.setOptions('forms', {
overrideMessages : true
});
$.webshims.setOptions({
waitReady : false
});
$.webshims.polyfill();
</script>
// below method in angular app to update Polyfill when dynamic view loads.
angular.module('essApp').run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$('body').updatePolyfill();
});
});
My angular function to call a popup/modal
$scope.showGoalDetail = function(index) {
$log.info('index is', index);
$log.info('goal is', $scope.goals.goalList[index]);
var modalInstance = $modal.open({
templateUrl : 'org/goalDetailPopUp.html',
controller : 'PopUpInstanceCtrl',
size : 'lg',
backdrop : 'static',
resolve : {
valueObject : function() {
var valueObject = new Object();
valueObject.goal = {};
angular.copy($scope.goals.goalList[index], valueObject.goal);
valueObject.kpiList=$scope.goals.kpiList;
return valueObject;
}
}
});
My form in Modal Window
<div class="modal-header" style="background-color: #428bca; color: #FFFFFF">
<h3 class="modal-title">Goal Detail</h3>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading">
<p class="panel-title">Administration of prespective and priority</p>
</div>
<div class="panel-body">
<form class="form-horizontal" role="form" ng-submit="ok()">
<div class="form-group">
<label class="col-md-2 control-label">Dimension</label>
<div class="col-md-6">
<input type="text" class="form-control" required disabled ng-model="valueObject.goal.perspectiveDesc">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Key PerformanceIndicator</label>
<div class="col-md-10">
<textarea class="form-control" required ng-model="valueObject.goal.keyPerformanceIndicator"></textarea>
</div>
</div>
<button type="submit" class="btn btn-primary">OK</button>
<button class="btn btn-danger" ng-click="cancel()">Cancel</button>
</form>
</div>
</div>
</div>
<div class="modal-footer"></div>
I need the validations to appear properly on popup next to the field

Related

$modal is not open for the second time in Angularjs

$modal is called in the $ngonint hook. First time when controller loads, it works perfectly. But for the second time, it is not showing up when the controller loads.
Expectation:
Consider two controllers first and second.
Navigate to second controller from first controller by clicking link.
We need to show below modal when page loads whenever navigate to second controller page.
Actual Result:
For the first time, when it navigate to second controller, it showed the modal as expected. once go back to first page and come again to second controller, modal is not showed up.
Can anyone help me to solve this issue ? Thanks.
Below are the code sample:
Controller
$onInit() {this.showModal();} // Need to show modal when page loads
public showModal= function () {
var modalInstance = $modal.open({
template: ModalTemplate,
controller: [
'$scope',
'$modalInstance',
function ($scope, $modalInstance) {
$scope.answer = '';
$scope.close = function () {
$modalInstance.dismiss();
};
$scope.next = function () {
$modalInstance.close($scope.answer);
};
},
],
windowClass: 'open-account'
});
modalInstance.result.then((response) => {
console.log(response);
})
}
ModalTemplate.html
<div class="modal-header">
<button type="button" class="close" ng-click="close()" aria-hidden="true">
<fa-icon icon="times" prefix="fal" class="close-fa fa-lg"></fa-icon>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-4">
<div class="form-group radio-group-label">
<label class="control-label">
Click
</label>
</div>
</div>
<div class="col-xs-2">
<div class="form-group">
<label class="control-label" for="answer-yes">
<input type="radio" name="answer" ng-model="answer" value="yes"
id="answer-yes" />
Yes
</label>
</div>
</div>
<div class="col-xs-2">
<div class="form-group">
<label class="control-label" for="answer-no">
<input type="radio" name="answer" ng-model="answer" value="no"
id="answer-no" />
No </label>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-disabled="!answer" ng-click="next()">Next</button>
</div>

angular: form not submitting data not showing in firebug

I have a form and in that from there are some text boxes. Textbox are generated at run time. Like user can add or remove text boxes.
Here is the form.
<form name="formprofile3" method="post" id="formprofile3" role="form" ng-submit="formprofile3()">
<div class="container">
<div class="row">
<div ng-app="angularjs-starter" ng-controller="MainCtrl">
<fieldset data-ng-repeat="choice in choices">
<div class="col-xs-12">
<div class="row">
<div class="col-xs-10">
<textarea name="exp_details" ng-model="choice.name" class="form-control textbox1" id="exp_details" placeholder="Experience" required="required" rows="3"></textarea></div>
<div class="col-xs-2">
<button class="remove" ng-show="$last" ng-click="removeChoice()">-</button>
</div>
</fieldset>
<button class="addfields" ng-click="addNewChoice()">+</button>
<div id="choicesDisplay">
{{ choices }}
</div>
</div>
</div>
</div>
<center><button type="submit" class="btn btn-home" name="btn-save1" id="btn-save1" required="required">Save & Finish <i class="icon ion-arrow-right-a"></i></button></center>
</form>
here is the angular code to submit the form.
formApp.controller('formProfile3', function($scope,$http){
$scope.formData = {};
$scope.formprofile3 = function() {
var allData={'formData': $scope.formData, 'uid': uid}
$http({
method : 'POST',
url : 'add_profile.php',
data : allData,
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.success(function(data) {
if (!data.success) {
$scope.message = data.errors.message;
}else{
alert('Your details has been updated.');
}
});
};
})
Problem is when i submit the form. It is not getting submit. no data is getting in post.
Any advise what am i doing wrong.
Edit: i can see the data in {{ choices }}.
Choices are not coming in formdata.
Here is the data in firebug.
{"formData":{},"uid":"75"}:""
Move ng-app & ng-controller directives to body/html tag, so that form & ng-submit directive should get compile
<body ng-app="angularjs-starter" ng-controller="MainCtrl">
<form name="formprofile3" method="post" id="formprofile3" role="form" ng-submit="formprofile3()">
....
</form>
</body>
Also I can't see any formData(as ng-model) two way binding is present there on page. I guess you should look for choices. Additionally add name attribute to each textarea field to it part of form object for validation purpose.

angularjs form inside bootstrap modal popup

I have a form inside a bootstrap modal.But I can't able to get the values of form on controller side with scope variable.
https://plnkr.co/edit/FjKXUpoBDdvQqomI97ml?p=preview
My original code has another problem also. when I click on submit button it will refresh the whole page and submit function is not executing.
My form:
<div class="modal-body">
<form class="form-horizontal" name="contact" ng-submit="contactForm()">
<div class="form-group">
<label class="col-lg-3 control-label">Name* :</label>
<div class="col-lg-8">
<input class="form-control" type="text" id="name" name="_name" ng-model="_name" > </div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Email* :</label>
<div class="col-lg-8">
<input class="form-control" type="email" id="email" name="_email" ng-model="_email" required> </div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Mobile* :</label>
<div class="col-lg-8 row">
<div class="col-lg-4">
<input type="text" class="form-control" ng-model="_cc" placeholder="+91" name="_cc"> </div>
<div class="col-lg-8">
<input class="form-control" type="text" ng-model="_mobile" maxlength="10" ng-pattern="/^[0-9]{5,10}$/" id="mobile" name="_mobile"></div>
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">Message :</label>
<div class="col-lg-8">
<textarea class="form-control" rows="2" name="_condition" ng-model="_condition"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-7 col-lg-5">
<button type="submit" class="btn btn-primary" id="contactSubmit" >Submit</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div></div>
</form>
</div>
Controller:
$scope.contactForm = function(){
console.log($scope._condition,$scope._name,$scope._email,$scope._cc,$scope._mobile);
};
You are opening the modal using plain jQuery approach which is not going to work in Angular, because opened modal is not connected to Angular application, so it doesn't know that modal has to be handled, HTML parsed, etc.
Instead you should use directives properly, or in case of modal dialog you can simply use existent ones, like Angular UI project, which brings ready Bootstrap directives for Angular. In your case you need $modal service and inject the $http service to have your data posted.
Here is the working plunker using angular-ui bootstrap.
PLUNKER:https://plnkr.co/edit/rjtHJl0udyE0PTMQJn6p?p=preview
<html ng-app="plunker">
<head>
<script src="https://code.angularjs.org/1.2.18/angular.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="script.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<form ng-submit="submit()">
<div class="modal-body">
<label>Email address:</label>
<input type="email" ng-model="user.email" />
<label>Password</label>
<input type="password" ng-model="user.password" />
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
<input type="submit" class="btn primary-btn" value="Submit" />
</div>
</form>
</script>
<button class="btn" ng-click="open()">Open Modal</button>
</div>
</body>
</html>
JS:
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log,$http) {
$scope.user = {
email: '',
password: null,
};
$scope.open = function () {
$modal.open({
templateUrl: 'myModalContent.html', // loads the template
backdrop: true, // setting backdrop allows us to close the modal window on clicking outside the modal window
windowClass: 'modal', // windowClass - additional CSS class(es) to be added to a modal window template
controller: function ($scope, $modalInstance, $log, user) {
$scope.user = user;
$scope.submit = function () {
$log.log('Submiting user info.'); // kinda console logs this statement
$log.log(user);
$http({
method: 'POST',
url: 'https://mytesturl.com/apihit',
headers: {
"Content-type": undefined
}
, data: user
}).then(function (response) {
console.log(response);
$modalInstance.dismiss('cancel');
}, function (response) {
console.log('i am in error');
$modalInstance.dismiss('cancel');
});
//$modalInstance.dismiss('cancel'); // dismiss(reason) - a method that can be used to dismiss a modal, passing a reason
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
},
resolve: {
user: function () {
return $scope.user;
}
}
});//end of modal.open
}; // end of scope.open function
};

Angular validation directive not working properly

I am using custom angular directive for showing validation. Directive code is as below
angularFormsApp.directive('showErrors',['$timeout', function ($timeout) {
return {
restrict: 'A',
require: '^form',
link: function (scope, el, attrs, formCtrl) {
// find the text box element, which has the 'name' attribute
var inputEl = el[0].querySelector("[name]");
// convert the native text box element to an angular element
var inputNgEl = angular.element(inputEl);
// get the name on the text box so we know the property to check
// on the form controller
var inputName = inputNgEl.attr('name');
var helpText = angular.element(el[0].querySelector(".help-block"));
// only apply the has-error class after the user leaves the text box
inputNgEl.bind('blur', function () {
el.toggleClass('has-error', formCtrl[inputName].$invalid);
helpText.toggleClass('hide', formCtrl[inputName].$valid);
});
scope.$on('show-errors-event', function () {
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$on('hide-errors-event', function () {
$timeout(function () {
el.removeClass('has-error');
}, 0, false);
});
}
}
}]);
and Html is as below
<div class="container" id="login-form">
<img src="assets/img/logo-big.png">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-heading">
<h2>Login Form</h2>
</div>
<div class="panel-body">
<form name="loginForm" class="form-horizontal" novalidate>
<div class="form-group mb-md" show-errors>
<div class="col-xs-12">
<div class="input-group">
<span class="input-group-addon">
<i class="ti ti-user"></i>
</span>
<input type="text" class="form-control" placeholder="Username" autocomplete="Off" ng-required="true" name="username" autofocus ng-model="loginUser.username">
</div>
<span class="help-block" ng-if="loginForm.username.$error.required">Username is required</span>
</div>
</div>
<div class="form-group mb-md" show-errors>
<div class="col-xs-12" >
<div class="input-group">
<span class="input-group-addon">
<i class="ti ti-key"></i>
</span>
<input type="password" class="form-control" placeholder="Password"
name="password"
ng-model="loginUser.password" autocomplete="Off"
ng-required="true">
</div>
<span class="help-block" ng-if="loginForm.password.$error.required">Password is required</span>
</div>
</div>
<div class="form-group mb-n">
<div class="col-xs-12">
Forgot password?
<div class="checkbox-inline icheck pull-right p-n">
<label for="">
<input type="checkbox"></input>
Remember me
</label>
</div>
</div>
</div>
</form>
</div>
<div class="panel-footer">
<div class="clearfix">
Register
Login
</div>
</div>
</div>
</div>
</div>
</div>
Controller code :
var loginController = function ($scope, $window, $routeParams, $uibModal, $location, $filter, $rootScope, DataService, SharedProperties) {
$rootScope.bodylayout = 'focused-form animated-content';
$scope.loginUser = {
username: "",
password:""
}
$scope.load = function () {
//getAppointmentInfo();
};
$scope.SubmitLoginForm = function () {
$scope.$broadcast('show-errors-event');
if ($scope.loginForm.$invalid)
return;
}
}
angularFormsApp.controller("loginController", ["$scope", "$window", "$routeParams", "$uibModal", "$location", "$filter", "$rootScope", "DataService", "SharedProperties", loginController]);
Now When I open form below input control validation span is displaying by default . When I click on Login button then its showing in red and working fine.
problem is it shouldn't show by default when Page is opend.. Please see image below
Instead of this
loginForm.password.$error.required
try this
(loginForm.$submitted || loginForm.username.$dirty) && loginForm.password.$error.required
Take a look at the ng-messages directive. Its fairly elegant. Example:
<form name="myForm">
<input type="text" ng-model="field" name="myField" required minlength="5" />
<div ng-messages="myForm.myField.$error">
<div ng-message="required">You did not enter a field</div>
<div ng-message="minlength">The value entered is too short</div>
</div>
</form>
You can then combine it with any form validation. Just place the error messages from the validators onto the elements $error object and they are automatically rendered in your UI.
I ended up here as part of my search for an issue. In my case I was using a directive with a changing minimum value like this:
ngOnChanges(changes: SimpleChanges) {
if (changes.minDate && this.control) {
this.control.updateValueAndValidity({ onlySelf: true });
}
}
This means that the form will not be updated, I removed onlySelf and it worked correctly.
this.control.updateValueAndValidity();
Just leaving this as a breadcrumb in case someone else does something similar.

AngularJS apply select2 on element within modal

I'm trying to apply select2 on a select element within a modal.
The modal is defined as a script ng-template. This works fine if it's not a modal (or a template).
<script type="text/javascript">
$(document).ready(function ($) {
$("#typeDescription").select2({
placeholder: 'Select a type...',
allowClear: true
});
});
</script>
However I cannot include the above code within
<script type="text/ng-template" id="myModal">
</script>
So the thing is I want to apply select2 on my element on the modal. How can I do that? How can I access the modal element by id and apply select2 on it?
EDIT:
I made some changes:
On the controller I made a function:
......
$scope.select = function() {
$(document).ready(function ($) {
$("#typeDescription").select2({
placeholder: 'Select a type...',
allowClear: true
});
});
};
and then within my template:
at the select filed (see bellow) I did like this: data-ng-init="select()"
and actually works, it applies the select2 to my element.
Is this a proper approach? Can I make use of ng-init for this case?
<script type="text/ng-template" id="myModal">
<div class="modal-header">
<button type="button" class="close" ng-click="currentModal.close();" aria-hidden="true">×</button>
<h4 class="modal-title">Title</h4>
</div>
<div class="modal-body">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label" for="field-1">Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" data-ng-model="newType.Name" id="field-1" placeholder="Name">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="field-5">Description</label>
<div class="col-sm-10">
<textarea class="form-control" data-ng-model="newType.Description" cols="5" id="field-5" placeholder="Description"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="field-5">Select Type</label>
<div class="col-sm-10">
<select class="form-control" id="typeDescription" data-ng-model="newType.Type" data-ng-init="select()">
<option data-ng-repeat="item in allTypes.Types" value="{{item.Value}}">{{item.Text}}</option>
</select>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-gray btn-single" data-ng-click="currentModal.close();">Cancel</button>
<button type="button" class="btn btn-info btn-single" data-ng-click="createType(); currentModal.dismiss();">Save</button>
</div>
</script>
I would recommend that you create a directive wrapping the select2 plugin:
var lib = angular.module('lib');
lib.directive('mySelect', [function() {
var link = function (scope, element, attrs) {
element.select2({
placeholder: attrs.placeholder,
allowClear: attrs.allowClear
});
}
return {
restrict: 'A',
link: link
};
}]);
use it like this:
<select data-my-select placeholder="'Select a type...'" allowClear="true"></select>
This will initialize the select2 when the select control is rendered.

Resources