Show Input Error Using Custom directives Without Using NgMessages - javascript

I Have input and I use a custom directive to display the input error with use of ng-messages. And I want to use attribute for showing the error, not ng-message.
Here is my Code
<md-input-container class="md-block" flex-gt-sm>
<label>Enter Your Message</label>
<input required md-no-asterisk ng-model="newEmployee.message" type="text" id="name" name="name" formValidate>
<div ng-messages="Employeeform.message.$error">
<div ng-message="messageValidator">Message is Invalid
</div>
</md-input-container>
Directive :
app.directive('formValidate', function() {
return {
restrict: 'A',
require: 'ngModel',
template: '<p>Name is required</p>',
link: function(scope, element, attr, ctrl) {
function formValidate(ngModelValue) {
if ([A - z].test(ngModelValue)) {
ctrl.$setValidity('formValidate', false)
} else {
ctrl.$setValidity('formValidate', true),
}
return ngModelValue;
}
ctrl.$parsers.push(formValidate);
}
};
});

Make use of angular-form. Go through this doc https://docs.angularjs.org/guide/forms
Without ng-messages
<div class="form-group" ng-class="{ 'has-error': vm.form.firstname.$touched && vm.form.firstname.$invalid }">
<label class="control-label col-xs-3" for="firstname">First Name</label>
<div class="col-xs-9">
<input class="form-control" name="firstname" id="firstname" ng-model="vm.firstname" type="text" ng-change = "vm.resetValidationErrors('firstname')" required/>
<p ng-show="vm.form.firstname.$error.required && vm.form.firstname.$touched" class="help-block">First name is required.</p>
<p ng-show="vm.form.firstname.$error.firstname && vm.form.firstname.$touched" class="help-block">{{ vm.form.firstname.errorMessage }}</p>
</div>
</div>

Related

Text field displays value but doesn't catch it

I am working on the project that needs to be updates with some functions. One is where i need to update EAV registration form and make choose option, where i have 2 radio buttons and text field. When I click on one of the radio buttons, it takes the value and places it in the input textbox. The problems starts when i try to save registration. This text field attributes are saved in database where one of them is "isRequired". I can't save form because textfield asks to type something in it, but there is already a value. When I disable "isRequired" it saves the form, but there is no value saved in database. When I type any symbol next to radio button value required field disappears and then I can save the value in database. That's why my question is why field can't catch the value. I will put some of the code in this question because I can't make test environment. Have only files on the server. Hope someone can answer or give some clues what to do. I have opinions that this problem might be cause by keypress events, angularjs, jquery or EAV model.
Image: https://postimg.org/image/j8mgjia1d/
Creating fields:
backendComponents.directive('eavFormatted', function($compile)
{
return {
restrict: "E",
scope: true,
replace: true,
transclude: true,
template: '<div class="form-group field_eav field_eav_{{ config.ID }} field_eav_{{ config.handle }}"><label class="control-label">{{ config.name }}</label><div ng-transclude></div></div>',
link: function(scope, element, attrs)
{
var config = JSON.parse(attrs.config);
scope.config = config;
delete attrs.config;
element.removeAttr('ng-transclude');
}
}
});
backendComponents.directive('eavField', function($compile, $timeout) {
return {
restrict: "E",
scope: true,
replace: true,
link: function(scope, element, attrs)
if (html) {
var fieldName = 'eav_' + config.ID;
if (config.isRequired) {
html = html + '<div class="text-danger" ng-show="isSubmitted && eavform.' + fieldName + '.$error.required">Lūdzu aizpildiet šo lauku</div>';
}
html = '<div><ng-form name="eavform">' + html + element.html() + '</ng-form></div>';
var newElem = angular.element(html);
var attrElem = input ? newElem.find(input) : newElem;
attrElem.attr('ng-model', 'vals.eav.' + config.ID);
attrElem.addClass('form-control');
attrElem.attr('placeholder', config.description);
attrElem.attr('name', fieldName);
if (config.isRequired) {
attrElem.attr('ng-required', true);
}
}
}
}
Fields from inspect element from browser:
<div class="form-group field_eav field_eav_2 field_eav_epasts" config="{"ID":2,"eavFieldGroupID":null,"classID":2,"stringIdentifier":null,"name":"E-pasts","description":"E-PASTS *","type":3,"dataType":1,"position":1,"handle":"epasts","isMultiValue":null,"isRequired":1,"isDisplayed":null,"isDisplayedInList":null,"valuePrefix":null,"valueSuffix":null,"valueFieldID":null,"fieldName":"specField_2"}">
<label class="control-label ng-binding">E-pasts</label>
<div ng-transclude="">
<div class="ng-scope">
<ng-form name="eavform" class="ng-pristine ng-invalid ng-invalid-required">
<input type="text" ng-model="vals.eav.2" class="form-control ng-pristine ng-invalid ng-invalid-required" placeholder="E-PASTS *" name="eav_2" ng-required="true" required="required">
<div class="text-danger ng-hide" ng-show="isSubmitted && eavform.eav_2.$error.required">Lūdzu aizpildiet šo lauku</div>
</ng-form>
</div>
</div>
</div>
<div ng-transclude="">
<div class="ng-scope">
<ng-form name="eavform" class="ng-pristine ng-invalid ng-invalid-required">
<input type="text" ng-model="vals.eav.2" class="form-control ng-pristine ng-invalid ng-invalid-required" placeholder="E-PASTS *" name="eav_2" ng-required="true" required="required">
<div class="text-danger ng-hide" ng-show="isSubmitted && eavform.eav_2.$error.required">Lūdzu aizpildiet šo lauku</div>
</ng-form>
</div>
</div>
Code from the file
<eav-formatted config="[[ eavFieldsHandle.epasts.toJson() ]]">
<eav-field></eav-field>
</eav-formatted>
<legend style="padding-top: 0px;">Izvēlieties piegādes veidu: </legend>
<input type="radio" class="input" name="radio-1" id="radio-1" value="Option1">
<span><b>Choose 1</span>
<input type="radio" class="input" name="radio-1" id="radio-2" value="Option2">
<span><b>Choose 2</span>
Script of the file
$( function() {
$('input[name="radio-1"]').on('change', function() {
$('input[name="eav_2"]').val($(this).val());
});
} );

Dynamically display form data using AngularJS

I would like to dynamically display Person and Address data using label and input value in Summary Section. As the user edits the form fields, a list items with label + value should display in the summary tables. If value has been removed in the form, that associated label and value should be removed from the Summary Section.
I have added client side validation for each input element. I tried to solve this and couldn't figure out what is best way to do it. Any help would be appreciated.
Example:
// the main (app) module
var myApp = angular.module("myApp", []);
// add a controller
myApp.controller("myCtrl", function($scope) {
$scope.vm = {
caller: {
person: {
firstName: '',
lastName: '',
phoneOne: '',
email: ''
},
address: {
lineOne: '',
lineTwo: ''
}
}
};
$scope.save = function() {
console.log($scope.vm);
}
});
// add a directive
myApp.directive('showErrors', function($timeout, $compile) {
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
var inputName = inputNgEl.attr('name');
// only apply the has-error class after the user leaves the text box
var blurred = false;
inputNgEl.bind('blur', function() {
blurred = true;
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$watch(function(scope) {
return formCtrl[inputName].$invalid;
}, function(invalid, scope) {
// we only want to toggle the has-error class after the blur
// event or if the control becomes valid
if (!blurred && invalid) {
return
}
el.toggleClass('has-error', invalid);
});
scope.$on('show-errors-check-validity', function() {
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$on('show-errors-reset', function() {
$timeout(function() {
el.removeClass('has-error');
}, 0, false);
});
}
}
});
.form-group .help-block {
display: none;
}
.form-group.has-error .help-block {
display: inline;
}
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<form name="claimForm" ng-submit="save()">
<h3>PERSON</h3>
<div class="col-md-6">
<div class="form-group form-caller" show-errors>
<label class="control-label">First Name<span class="help-block" ng-if="claimForm.callerFirstName.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="callerFirstName" ng-model="vm.caller.person.firstName" class="form-control" required="" />
</div>
</div>
<div class="col-md-6">
<div class="form-group form-caller" show-errors>
<label class="control-label">Last Name<span class="help-block" ng-if="claimForm.callerLastName.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="callerLastName" ng-model="vm.caller.person.lastName" class="form-control" required="" />
</div>
</div>
<hr />
<h3>ADDRESS</h3>
<div class="col-md-6">
<div class="form-group" show-errors>
<label class="control-label">Address Line 1<span class="help-block" ng-if="claimForm.addressOne.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="addressOne" ng-model="vm.caller.address.lineOne" class="form-control" required="" />
</div>
</div>
<div class="col-md-6">
<div class="form-group" show-errors>
<label class="control-label">Address Line 2<span class="help-block" ng-if="claimForm.addressTwo.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="addressTwo" ng-model="vm.caller.address.lineTwo" class="form-control" required="" />
</div>
</div>
<hr />
<input type="submit" id="submit" value="SUBMIT" class="btn btn-primary btn-lg" />
{{vm | json }}
</form>
<h2>Summary</h2>
<div id="person">
<h3>PERSON </h3>
</div>
<hr />
<div id="address">
<h3>ADDRESS</h3>
</div>
</body>
Thanks in Advance

Add class to input parent

I need to add class to input parent if input is not empty or focus because I want to change label position.
<div class="input-field">
<input type="email" name="email" ng-model="email" required />
<label for="email">Email</label>
</div>
I can do this:
<div class="input-field" ng-class="{ active: signIn.email.$viewValue.length > 0 || isFocus }">
<input type="email" name="email" ng-model="email" ng-focus="isFocus=true" ng-blur="isFocus=false" required />
<label for="email">Email</label>
</div>
But I have many inputs and my code will be very large and ugly.
How can I do it better?
Thank you.
Go with attribute directive where you can have logic which class you need to add to input-filed.
angular.directive('myClass', function() {
return {
restrict: 'A',
link: function (scope, element,attr) {
// your logic
}
};
or
$scope.myClass = "";
<div class="input-field" ng-class="myClass" />
angularjs : setting class attribute in a directive template
You can use a scope variable for this.
myApp = angular.module("myApp",[]).controller("myController",['$scope',function($scope){
var someCondition = 2 > 1;
$scope.myClass = {
active : someCondition ? "active" : "not-so-active"
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div class="input-field" ng-class="{{myClass}}">
<input type="email" name="email" ng-model="email" ng-focus="focus=true" ng-blur="focus=false" required />
<label for="email">Email</label>
</div>
</div>

Part's of form not being rendered - AngularJS

I can't seem to find why the "start" and "finish" part of my form isn't being rendered. This is the first time I've ever worked with AngularJS, and after following quite a few tuts online, I used to yo meanjs generator with the articles example. I then took the articles example and tried to port it over to this scheduling thing. It really doesn't matter though, I just want to know why the last two inputs in the form aren't being rendered in my view.
Any help is much appreciated
Here's the code for my view:
<section data-ng-controller="SchedulesController">
<div class="page-header">
<h1>New Schedule</h1>
</div>
<div class="col-md-12">
<form name="scheduleForm" class="form-horizontal" data-ng-submit="create()" novalidate>
<fieldset>
<div class="form-group" ng-class="{ "has-error": scheduleForm.title.$dirty && scheduleForm.title.$invalid }">
<label class="control-label" for="title">Title</label>
<div class="controls">
<input name="title" type="text" data-ng-model="title" id="title" class="form-control" placeholder="Title" required>
</div>
</div>
<div class="form-group">
<label class="control-label" for="content">Content</label>
<div class="controls">
<textarea name="content" data-ng-model="content" id="content" class="form-control" cols="30" rows="10" placeholder="Content"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label" for="start">Start</label>
<div class="controls">
<input name="finish" value="" type="date" data-ng-model="start" class="form-control" required>
</div>
</div>
<div class="form-group">
<label class="control-label" for="finish">Finish</label>
<div class="controls">
<input name="finish" value ="" type="date" data-ng-model="finish", class="form-control" required>
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-default">
</div>
<div data-ng-show="error" class="text-danger">
<strong data-ng-bind="error"></strong>
</div>
</fieldset>
</form>
</div>
</section>
Here's the code for my controller:
'use strict';
angular.module('schedules').controller('SchedulesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Schedules',
function($scope, $stateParams, $location, Authentication, Schedules) {
$scope.authentication = Authentication;
$scope.create = function() {
var schedule = new Schedules({
title: this.title,
content: this.content,
start: this.start,
finish: this.finish
});
schedule.$save(function(response) {
$location.path('schedules/' + response._id);
console.log('hola!');
$scope.title = '';
$scope.content = '';
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
$scope.remove = function(schedule) {
if (schedule) {
schedule.$remove();
for (var i in $scope.schedules) {
if ($scope.schedules[i] === schedule) {
$scope.schedules.splice(i, 1);
}
}
} else {
$scope.schedule.$remove(function() {
$location.path('schedules');
});
}
};
$scope.update = function() {
var schedule = $scope.schedule;
schedule.$update(function() {
$location.path('schedules/' + schedule._id);
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
$scope.find = function() {
$scope.schedules = Schedules.query();
};
$scope.findOne = function() {
$scope.schedule = Schedules.get({
scheduleId: $stateParams.scheduleId
});
};
}
]);
Um... Well guys.... I don't know WHY this worked, and everything in me tells me this wasn't the problem, BUT:
Notice line
<input name="finish" value ="" type="date" data-ng-model="finish", class="form-control" required>
The "," was a mistake (I wrote a script that ported everything from articles into schedule, maintining code structure and just changing all mentions of [Aa]rticle{s} -> [Ss]chedule{s}, and this was left over in that (for some reason, don't know where it came in). Anyway, I deleted the comment and ran grunt build && grunt test && grunt and it worked. I'm now getting the correct render.

Grab all input data with Angular

Im trying to post input data with angular, but I don't know how to grab the data from the input fields.
Here is my HTML:
<div ng-controller="Test">
<div class="container">
<div class="col-sm-9 col-sm-offset-2">
<div class="page-header"><h1>Testar</h1></div>
<form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate> <!-- novalidate prevents HTML5 validation since we will be validating ourselves -->
<div class="form-group" ng-class="{'has-error' : userForm.name.$invalid && !userForm.name.$pristine, 'has-success' : userForm.name.$valid }">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="name" required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">Fel namn</p>
</div>
<div class="form-group" ng-class="{'has-error' : userForm.username.$invalid && !userForm.username.$pristine, 'has-success' : userForm.username.$valid && !userForm.username.$pristine}">
<label>Username</label>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" ng-maxlength="8">
<p ng-show="userForm.username.$error.minlength" class="help-block">För kort</p>
<p ng-show="userForm.username.$error.maxlength" class="help-block">För långt</p>
</div>
<div class="form-group" ng-class="{'has-error' : userForm.email.$invalid && !userForm.email.$pristine, 'has-success' : userForm.email.$valid && !userForm.email.$pristine}">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="email">
<p ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="help-block">Ange korrekt e-post</p>
</div>
<button type="submit" class="btn btn-primary">Lägg till</button>
</form>
</div>
</div>
</div>
Here is my controller:
as.controller('Test', function($scope, $http, $rootScope)
{
$scope.submitForm = function(isValid) {
if(isValid)
{
$http.post($rootScope.appUrl + '/nao/test', {"data": $scope.userForm})
.success(function(data, status, headers, config) {
console.log(data);
}).error(function(data, status) {
});
}
};
});
A post is made when I hit the button, but the data that Is being sent looks like this:
{"data":{"name":{},"username":{},"email":{}}}
How can I take the data from all the input fields? Should I refer to userForm as I do in the controller?
I suggest to create one more $scope object - at beginning it will be empty:
$scope.form = {};
Every field will be a part of this object:
<input type="text" name="name" class="form-control" ng-model="form.name" required>
After send all fields you will have in object $scope.form.
jsFiddle: http://jsfiddle.net/krzysztof_safjanowski/QjNd6/
you have ng-model variables in scope:
$scope.name
$scope.user.username
$scope.email
you can all of these prefix with user. and then send with ajax $scope.user instead of $scope.userForm
or
try to send object which is copied by: angular.copy($scope.userForm)
You can have a property in your scope, say user. Have all your ng-model values be user.SOMETHING. This way you can easily send the $scope.user holding all the data, as in {data: $scope.user }.

Categories

Resources