I have a formly form of which I do not know what validation errors I will receive in advance. So, my plan: submit the form to the server, get errors back if they exist, then add the error message to the field in question. My code is this:
/* global angular */
(function() {
'use strict';
var app = angular.module('formlyExample', [
'formly',
'formlyBootstrap',
'ngAnimate',
'ngMessages'
]);
app.run(function(formlyConfig, formlyValidationMessages) {
formlyConfig.extras.errorExistsAndShouldBeVisibleExpression = 'fc.$touched || form.$submitted';
});
app.config(function(formlyConfigProvider) {
formlyConfigProvider.setWrapper({
name: 'validation',
types: ['input'],
templateUrl: 'error-messages.html'
});
});
app.controller('MainCtrl', function MainCtrl(formlyVersion) {
var vm = this;
// funcation assignment
vm.onSubmit = onSubmit;
vm.env = {
angularVersion: angular.version.full,
formlyVersion: formlyVersion
};
vm.model = {};
vm.options = {};
vm.fields = [{
key: 'coolValue',
type: 'input',
templateOptions: {
required: false,
type: 'text',
label: 'Cool Value'
}
}, ];
vm.originalFields = angular.copy(vm.fields);
// function definition
function onSubmit() {
//if (vm.form.$valid) {
// vm.options.updateInitialValue();
// alert(JSON.stringify(vm.model), null, 2);
// }
}
});
})();
body {
margin: 20px
}
.formly-field {
margin-bottom: 26px;
}
.error-messages {
position: relative;
}
.error-messages,
.message {
opacity: 1;
transition: .3s linear all;
}
.message {
font-size: .8em;
position: absolute;
width: 100%;
color: #a94442;
margin-top: 2px;
}
.error-messages.ng-enter.ng-enter-active,
.message.ng-enter.ng-enter-active {
opacity: 1;
top: 0;
}
.error-messages.ng-enter,
.message.ng-enter {
opacity: 0;
top: -10px;
}
.error-messages.ng-leave,
.message.ng-leave {
opacity: 1;
top: 0;
}
.error-messages.ng-leave-active,
.message.ng-leave-active {
opacity: 0;
top: -10px;
}
<!DOCTYPE html>
<html>
<head>
<!-- Twitter bootstrap -->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<!-- apiCheck is used by formly to validate its api -->
<script src="//npmcdn.com/api-check@latest/dist/api-check.js"></script>
<!-- This is the latest version of angular (at the time this template was created) -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<!-- This is the latest version of formly core. -->
<script src="//npmcdn.com/angular-formly@latest/dist/formly.js"></script>
<!-- This is the latest version of formly bootstrap templates -->
<script src="//npmcdn.com/angular-formly-templates-bootstrap@latest/dist/angular-formly-templates-bootstrap.js"></script>
<script src="https://rawgit.com/angular/bower-angular-messages/v1.4.4/angular-messages.js"></script>
<script src="https://rawgit.com/angular/bower-angular-animate/v1.4.4/angular-animate.js"></script>
<title>Angular Formly Example</title>
</head>
<body ng-app="formlyExample" ng-controller="MainCtrl as vm">
<div>
<form ng-submit="vm.onSubmit()" name="vm.form" novalidate>
<formly-form model="vm.model" fields="vm.fields" options="vm.options" form="vm.form">
<button type="submit" class="btn btn-primary submit-button">Submit</button>
<button type="button" class="btn btn-default" ng-click="vm.options.resetModel()">Reset</button>
</formly-form>
</form>
</div>
<!-- Put custom templates here -->
<script type="text/ng-template" id="error-messages.html">
<formly-transclude></formly-transclude>
<div ng-messages="fc.$error" ng-if="form.$submitted || options.formControl.$touched" class="error-messages">
<div ng-message="{{ ::name }}" ng-repeat="(name, message) in ::options.validation.messages" class="message">{{ message(fc.$viewValue, fc.$modelValue, this)}}</div>
</div>
</script>
</body>
</html>
And a JSBin page: http://jsbin.com/nupumakata/edit?html,js,output
What I'm trying to do: as soon as you hit the submit button, a custom validation message should be added to the Cool Value field. Since I don't know beforehand what errors will appear, I can't configure messages beforehand. So this:
formlyValidationMessages.addTemplateOptionValueMessage('pattern', 'patternValidationMessage', '', '', 'Invalid Input');
Would not work. In the answer I'm looking for, the message is added from inside the Submit function and only shown after the submit button is pressed (no error is shown until the submit button is pressed). I can't find in the documentation for Formly how to do this. Can anyone help please?
So what I've done is I've gone ahead and given the field a custom template as follows:
formlyConfigProvider.setWrapper({
name: 'inputWrapper',
template: '<div ng-class="to.changeColor==\'red\'? \'redBorder\' : \'otherBorder\'"><formly-transclude></formly-transclude>{{to.keyVal}}</div>'
});
The form elements are defined through a schema format to allow each element to be individually accessed.
vm.schema={
"schema": {
"coolValue" : [{
"key": "coolValue",
"type": "input",
"wrapper": ['inputWrapper'],
"templateOptions": {
"type" : "text",
"label": 'Cool Value',
"keyVal":"",
"changeColor":"green"
}
}]
}
};
Finally, the onSubmit
function
function onSubmit() {
//Do whatever you want here
//Let's say your server returns an error "iNVALID Credentials"
var response={
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization",
}
],
"code": 401,
"message": "Invalid Credentials"
}
};
vm.schema.schema.coolValue[0].templateOptions.changeColor="red";
vm.schema.schema.coolValue[0].templateOptions.keyVal=response.error.message;
}
});
You can essentially pass any error message or response from the server here.
The CSS contains a class to add a red border
to the field.You are free to disable this.Feel free to ping if you need anything in this area as well.
Here is a DEMO
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