Angular get the current form in the html - javascript

I'm wondering if it is possible to retrieve the current form in a html template.
To be clear, I actually would like to reuse some form fields this way:
<form name="myForm">
<div ng-include src="'templates/form-field/email.html'">
<div ng-include src="'templates/form-field/password.html'">
</form>
Here is templates/form-field/email.html:
<div>
<label>Email:</label>
<input type="email" name="email" ng-model="data.email" ng-required="true">
</div>
<div ng-show="myForm.email.$error.required && myForm.email.$touched" class="error">Email is required</div>
<div ng-show="myForm.email.$error.email && myForm.email.$touched" class="error">Email is not valid</div>
So this works well and allows me to re-use HTML components including error messages.
However, I have to to give a static name to my form (here "MyForm")
Is there any way to retrieve the current form inside the tags?
I'm quite new with angular so there may even be better ways to achieve the same behavior (i.e. re-use html components / error messages) that I'm not aware of.
I'm interesting in any solution as long as it does not include any 3rd parties.
Maybe using $scope to define the name of the form?

With ng-include it creates a child scope from the parent so the data is only shared one-way, from parent to child. You will need to create a directive instead and set scope to false, or not declare it at all since that is the default, so that the controller and the directive will share the same scope.
Email Directive:
directive('emailTemplate', [function(){
return {
templateUrl: 'templates/form-field/email.html',
link: function(scope, elem, attrs) {
}
};
}]);
Password Directive:
directive('passwordTemplate', [function(){
return {
templateUrl: 'templates/form-field/password.html',
link: function(scope, elem, attrs) {
}
};
}]);
HTML
<form name="myForm">
<email-template></email-template>
<password-template></password-template>
</form>
EDIT
Email Directive:
directive('emailTemplate', [function(){
return {
templateUrl: 'templates/form-field/email.html',
link: function(scope, elem, attrs) {
scope.form = scope[attrs.formName];
}
};
}]);
HTML
<form name="myForm">
<email-template form-name="myForm"></email-template>
<password-template form-name="myForm"></password-template>
</form>
Template
<div>
<label>Email:</label>
<input type="email" name="email" ng-model="data.email" ng-required="true">
</div>
<div ng-show="form.email.$error.required && form.email.$touched" class="error">Email is required</div>
<div ng-show="form.email.$error.email && form.email.$touched" class="error">Email is not valid</div>

Related

Retrieving the value of ng-model from Directives template to Another Html file

I can't retrieve the ng-model value of my template-url from my name directive.
team-two.html
<form name="userForm" novalidate>
<div name-directive></div>
</form>
<pre>{{userForm.firstname}}</pre>
here i have name-directive inside the form and a pre tag to view as I type a value in input text of name-directive
name-directive.js
(function () {
'use strict';
var app = angular.module('app.input-form');
app.directive('nameDirective', function () {
return {
restrict: 'AE',
scope: true,
controller: function() {
var vm = this;
vm.namePattern = /^[a-zA-Z ]{1,25}$/;
},
controllerAs: 'vm',
templateUrl: '/src/client/app/input-form/name.html'
}
});
})();
in here, I have a templateUrl dont mind the other codes coz I think it not related to my concern.
name.html
<input type="text" name="firstname" class="form-control" placeholder="Enter
your first name"
ng-model="firstname"
ng-minlength="2"
ng-maxlength="20"
required
ng-pattern="vm.namePattern"/>
in here, I have a ng-model that I want to access which is the firstname..
Edit Note: I discovered that if I add $viewValue in <pre>{{userForm.firstname.$viewValue}}</pre> it works.. I get what I want.. But I think that it is not the exact solution for my problem..
Edit 2 Added link to Plunker: https://plnkr.co/edit/6glStzEq5ckZZzph2qLw?p=preview
Since you use the controllerAs in the directive need to reference that when you are accessing variables from the html.
ng-model="vm.firstname"
<input type="text" name="firstname" class="form-control" placeholder="Enter
your first name"
ng-model="vm.firstname"
ng-minlength="2"
ng-maxlength="20"
required
ng-pattern="vm.namePattern"/>

AngularJS - exclude field from form validation / dirty

I have a checkbox inside ng-form rapped by HTML5 form that I want to exclude so it won't change my form $state($pristine or $dirty).
I have tried using ignoreDirty directive - Angular 1.2: Is it possible to exclude an input on form dirty checking?
and some other solutions and none work for ng-form inside HTML5 form, some example code:
<form name="mainForm" class="col-xs-10 form-validation" novalidate>
<ng-form name="innerForm">
<div>
<span>check my
<span ng-if="vm.utils.mode!=='readonly'">
<input type="checkbox"
ng-model="vm.utils.amalotSecond"
class="secondYearCheckBox">
</span>
</span>
</div>
</ng-form>
<form>
The ignoreDirty directive you provided works fine like in this demo fiddle. The following code example was taken from angular-1-2-is-it-possible-to-exclude-an-input-on-form-dirty-checking. Also try to avoid using nested forms which are not HTML conform. An form element can't have an element form. It will cause problems and errors e.g. the one you are currently facing.
View
<div ng-controller="MyCtrl">
<form name="test">
Watching dirty: <input ng-model="name" /><br />
Ignoring dirty: <select ng-model="gender" ignore-dirty>
<option>male</option>
<option>female</option>
</select><br />
dirty: {{test.$dirty}}
</form>
</div>
AngularJS application
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {
$scope.name = 'Superhero';
});
myApp.directive('ignoreDirty', [function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$setPristine = function() {};
ctrl.$pristine = false;
}
}
}]);

Padding form into templateURL to be used with ngMessages

I'm new to angular and trying my hand at directives.
I would like to be able to use
<div ng-messages="form.$error">
<div ng-message="required">You did not enter a field</div>
</div>
Within a custom directive like so,
<div class="form-group">
<label class="form-label" for="s-input-{{name}}">
{{text.human}}
<span ng-if="text.subtext" class="form-hint">{{text.subtext}}</span>
</label>
<select ng-required="required" ng-model="model" class="form-control" id="s-input-{{name}}" name="{{name}}" ng-options="t for t in text.select"></select>
<div ng-messages="form.$error">
<div ng-message="required">You did not enter a field</div>
</div>
</div>
I can get it to work by passing using ng-messages below the directive element but not in it.
Although I really can't figure out how to pass the form in to the template so it can be accessed by ng-messages.
I've set up a plunker to show you my bare bones setup.
http://plnkr.co/edit/ELx6Fd2eLN4CJjEnzRGM?p=preview
I know I need to require the form with require: '^form', although I'm not sure how to use/access in the template URL.
I've been banging my head for a while so would really appreciate some help! Thanks.
When you require the form directive with require: '^form' you then access that FormController in the link function. You can then simply attach that controller to the directive's scope like so:
link: function(scope, element, attributes, formController) {
scope.form = formController;
}
Then reference it in the template:
<div ng-messages="form.$error">
<div ng-message="required">You did not enter a field</div>
</div>
You could always pass the form to your directive.
javascript
app.directive('selectGov', function (){
return {
restrict: 'E',
templateUrl: 'select.html',
scope: {
text: "=?",
model: "=",
required: "=",
selectItems: "=?",
name: "#?",
form: "="
},
};
});
html
<select-gov model="person.phoneNumberType" text="q.phoneType" required="true" name="phoneType" form="myForm"></select-gov>

Adding custom validation to angular textarea

I want to add custom validation to the angular form.
<div class="form-group" ng-class="{ 'has-error': contactform.inputAmount.$invalid && submitted }">
<label for="inputAmount" class="col-lg-2 control-label">Amount</label>
<div class="col-lg-10">
<textarea ng-model="formData.inputAmount" class="validate[required,custom[comment]] feedback-input" rows="4" id="comment" name="comment" placeholder="Enter Amount to Convert" required></textarea>
</div>
</div>
I want only number or decimal input with inverted commas like
"1"
"123.1"
"123.12221"
How can i add this pattern
Help would be highly appreciated.
Thanks
You can use ng-pattern to validate your textarea.
Checkout here for example.
http://www.java2s.com/Tutorials/AngularJS/AngularJS_Example/Directives/Use_ng_pattern_to_validate.htm
Refer here for dynamic ng-pattern validation Angularjs dynamic ng-pattern validation
Use Directive for custom validations.
First write custom directive:
//Check For FLoat Validation
adminApp.directive('validateFloat', function() {
var FLOAT_REGEXP = /^\-?\d+((\.)\d+)?$/;
return {
require: 'ngModel',
restrict: '',
link: function(scope, elm, attrs, ctrl) {
// only apply the validator if ngModel is present and Angular has added the Float Number validator
ctrl.$validators.validateFloat = function(modelValue) {
return ctrl.$isEmpty(modelValue) || FLOAT_REGEXP.test(modelValue);
};
}
};
});
In directive used Regex for float (or) Decimal to check with ngModel value.
Then use directive in html page.
<input type="text" name="amount" class="form-control" ng-model=test.amount" validate-float required>
<span class="error-container" ng-show="myForm.amount.$dirty && myForm.amount.$invalid">
<span ng-cloak style="color:red" ng-show="myForm.amount.$error.required">Please Enter amount</span>
<span ng-cloak style="color:red" ng-show="!myForm.amount.$error.required&&myForm.amount.$error.validateFloat">Enter valid amount</span>
</span>
In HTML page mention the custom directive "validate-float" as attribute. And for showing error message in ng-Show mention the $error.validateFloat.
For more info about directive and validations: https://docs.angularjs.org/guide/directive,
https://docs.angularjs.org/guide/forms

AngularJS - form wrapper directive, for validation purpose

Consider the form:
<form class="form" name="myForm" ng-submit="submit()">
<div class="form-group" ng-class="{'has-error': myForm.title.$invalid}">
<label for="title">Title: </label>
<input id="title" name="title" class="form-control" ng-model="title"
required>
<div ng-messages="myForm.title.$dirty && myForm.title.$error" role="alert">
<div ng-message="required" class="alert small with-error-font">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
Title is required!
</div>
</div>
</div>
</form>
I want to achieve the following behaviour:
Validation error message should appear if user started typing and left the field empty (it's not pristine anymore). Otherwise, it shouldn't be visible till user clicks submit.
So I thought it could be done by using sort of 'aspect'/'interceptor' which simply checks if form is valid. If it is, then it should invoke ng-submit function. If not, then it should invoke $setDirty on each field (so that validation errors appear) and simply return.
I want to achieve it by creating ma own directive, like the following:
let validateAndSubmit = function (onValidationSuccessCallback) {
return function () {
// this is where validation logic should happen
onValidationSuccessCallback();
};
};
let ValidatingFormDirective = function () {
return {
restrict: 'E',
transclude: true,
replace: true,
scope: {
name: '#',
postValidationCallback: '&'
},
link: function (scope) {
scope.validateAndSubmit = validateAndSubmit(scope.postValidationCallback);
},
templateUrl: 'app/events/common/forms/validating-form.template.html'
}
};
export default ValidatingFormDirective;
and here's my directive template:
<form name="{{name}}" novalidate ng-submit="validateAndSubmit()" ng-transclude></form>
Problem:
Now if I change form to validation-form in my html, it seems like myForm is not recognized at all, because neither ngMessages block nor ng-class appears.
How can I fix it? Or maybe should I try completely different approach?

Categories

Resources