validation for dynamically added fields - angularjs

i have a form in that i provide an option to add fileds dynamically, for that i used ng-repeat, my promblem is for that added field form validation is not working. Here is my working code.
<fieldset data-ng-repeat="choice in choices" ng-init="count=0">
<div class="form-group">
<label class="col-sm-4 col-md-3">Designation </label>
<div class="col-sm-5 col-md-6">
<input type="text" name="desg_{{$index}}" class="form-control" ng-model="user2.choices[choice.id]" placeholder="Your Job Title" required/>
<span ng-messages="employeeform['desg_' + $index].$error" ng-show="employeeform['desg_' + $index].$touched || employeeform.$submitted">
<span ng-message = "required" class="errorcol">select day</span>
</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 col-md-3">Company </label>
<div class="col-sm-5 col-md-6">
<input type="text" class="form-control" name="company_{{$index}}" ng-focus="usercompany_msg=true" ng-model="user2.choices[choice.id_f]" placeholder="where your are currently working"/>
<p ng-show="errorDesg">{{errorDesg}}</p>
</div>
</div>
</fieldset>`
` -
and my controller code is
$scope.addfields = function(){
console.log($scope.choices.length);
if($scope.choices.length<3){
var newItemNo = $scope.choices.length + 1;
var item = {};
item.id = "company" + newItemNo;
item.id_f = "designation" + newItemNo;
item.id_s = "sallac" + newItemNo;
item.id_t = "saltho" + newItemNo;
$scope.choices.push(item);
console.log(JSON.stringify($scope.choices));
}
};
the error i am getting is

it is a parser error. you have wrong expression inside one of angular directive. try to comment part of your code/ one by one to localize parse error. why do you have ng-init="count=0" inside ng-repeat?

Related

Hiding multiple <div> elements using ng-show/ng-hide (AngularJS)

Good day!
So I trying to make Single Page App, but I am stuck with trying to hide/show div elements using checkbox. Since I was unsure how to make module, to hide/show elements, I used google to search up some tutorial, and found this code:
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope) {
//This will hide the DIV by default.
$scope.IsVisible = false;
$scope.ShowHide = function () {
//If DIV is visible it will be hidden and vice versa.
$scope.IsVisible = $scope.IsVisible ? false : true;
}
});
Unfortunately, when I try to apply this module to my html code, I always get this error:
Error: [ng:areq] Argument 'MyController' is not a function, got undefined
Here is my html code:
<div ng-app="MyApp" ng-controller="MyController">
<div class="form-group" ng-show = "IsVisible">
<label class="form-label" for="field-6">{{"NOTES_INSPECTOR"| translate}}</label>
<span class="desc"></span>
<div class="controls">
<textarea class="form-control" cols="5" id="field-6" ng-model="comment"></textarea>
</div>
</div>
<div class="form-group" ng-show = "IsVisible">
<label class="form-label" for="manager">{{"PREPAYMENT"| translate}}</label>
<span class="input-group-addon">€</span>
<input type="text" class="form-control" ng-model="avans">
<span class="input-group-addon">.00</span>
</div>
<div class="form-group" ng-show = "IsVisible">
<label class="form-label" for="manager">{{"THE_FINAL_PRICE"| translate}}</label>
<span class="input-group-addon">€</span>
<input type="text" class="form-control" ng-model="finalPrice">
<span class="input-group-addon">.00</span>
</div>
<div class="form-group">
{{"ORDER_IS_USER_ORDER"| translate}}
<label class="iswitch iswitch-md bg-info">
<input type="checkbox" ng-model="IsVisible">
<i></i>
</label> {{"ALLOWED"| translate}}
</div>
</div>
Idea behind this html code is, whenever user presses button which is 4th div in the code, elements should appear, else, be hidden. Unfortunately it doesn't work. Any ideas why?
DEMO
var app = angular.module('MyApp', [])
app.controller('MyController', function ($scope) {
//This will hide the DIV by default.
$scope.IsVisible = false;
$scope.ShowHide = function () {
//If DIV is visible it will be hidden and vice versa.
$scope.IsVisible = $scope.IsVisible ? false : true;
}
});
<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="form-group" ng-show = "IsVisible">
<label class="form-label" for="field-6">{{"NOTES_INSPECTOR"}}</label>
<span class="desc"></span>
<div class="controls">
<textarea class="form-control" cols="5" id="field-6" ng-model="comment"></textarea>
</div>
</div>
<div class="form-group" ng-show = "IsVisible">
<label class="form-label" for="manager">{{"PREPAYMENT"}}</label>
<span class="input-group-addon">€</span>
<input type="text" class="form-control" ng-model="avans">
<span class="input-group-addon">.00</span>
</div>
<div class="form-group" ng-show = "IsVisible">
<label class="form-label" for="manager">{{"THE_FINAL_PRICE"}}</label>
<span class="input-group-addon">€</span>
<input type="text" class="form-control" ng-model="finalPrice">
<span class="input-group-addon">.00</span>
</div>
<div class="form-group">
{{"ORDER_IS_USER_ORDER"}}
<label class="iswitch iswitch-md bg-info">
<input type="checkbox" ng-model="IsVisible">
<i></i>
</label> {{"ALLOWED"}}
</div>
</div>

angularjs dynamic form field undefined scope

Hi I have done this to add dynamic form field
<div ng-repeat="wspVdcMuniTbl in wspVdcMuniTbls">
<div class="col-sm-5">
<label>VDC/Municipalities</label>
<select
ng-model="wspVdcMuniTbl.tbl_vdc_municipality_id[$index]"
options="municipalities"
ng-options="municipality.id as municipality.name for municipality in municipalities">
</select>
</div>
<div class="col-sm-5">
<label>Wards</label>
<input type="text"
ng-model="wspVdcMuniTbl.wards[$index]"
id="Location">
</div>
<div class="col-sm-2">
<label> </label>
<button ng-hide="$first" ng-click="removeServiceArea($index)">-</button>
</div>
</div>
<div class="col-sm-2">
<button ng-click="addServiceArea()">+</button>
and my js part is
$scope.wspVdcMuniTbls = [{}];
$scope.addServiceArea = function(){
$scope.wspVdcMuniTbls.push({});
}
$scope.removeServiceArea = function(index){
$scope.wspVdcMuniTbls.splice(index,1);
}
here adding dynamic form field is working fine but after submit console.log($scope.wspVdcMuniTbl) is undefined what will be the problem please help

Radio button event not getting fired second time

I have two radio buttons 1. employee 2 customer when i have to select employee employee id textbox should get open n wen i click on customer it should get disappear. when i am clicking it for first tym its working fine second time its not working .
HTML FILE
<div class="row control-group">
<label >
<input name="cssPre" id="css1" value="geEmp" class="input-xlarge" type="radio" data-ng-model="addUser.Emp" ng-change="ge()">{{::'label.addUser.employee'|translate}}
</label>
<label >
<input name="cssPre" id="css2" value="customer" type="radio" data-ng-model="addUser.customer" ng-change="customer()">{{::'label.addUser.Customer'|translate}}
</label>
Textbox which i wanna show
<div ng-show="ge == true">
<div class="row control-group" ng-show="addUser.geEmp" ng-class="{error:addUserForm.phone.$dirty && !addUserForm.phone.$valid && !addUserForm.phone.$error.pattern, success:addUserForm.phone.$valid}">
<label class="col-xs-4 col-sm-4 col-md-3 col-lg-3 control-label">{{::'label.addUser.SSO'|translate}}</label>
<div class="col-xs-7 col-sm-7 col-md-9 col-lg-9 controls">
<input type="text"
class="input-xlarge"
id="sso"
name="phone"
ng-model="addUser.user.phone"
ng-pattern="ph_numbr"
placeholder="{{::'placeholder.addUser.phone'|translate}}"
ng-change="addUserForm.phone.$setValidity('duplicateName', true);"
required="true"
ng-maxlength=8
ng-minlength=8
ge-auto-focus
/>
<span class="help-block" ng-show="addUserForm.phone.$dirty && addUserForm.phone.$error.required">{{::'error.required'|translate}}</span>
<span class="help-block" ng-show="addUserForm.phone.$dirty && addUserForm.phone.$error.pattern">{{::'error.number'|translate}}</span>
<span class="help-block" ng-show="addUserForm.phone.$dirty && addUserForm.phone.$error.maxlength">{{::'error.max.length'|translate}}</span>
<span class="help-block" ng-show="addUserForm.phone.$dirty && addUserForm.phone.$error.duplicateName">{{::'error.editOrganization.duplicateName'|translate}}</span>
</div>
</div>
JS file
$scope.ge = function() {
$scope.ge = true;
}
$scope.customer = function() {
$scope.ge = false;
}
You have defined variable as well as a function as ge rename either of these one.
You are refining the $scope.ge variable as per your code
$scope.ge = function () {
$scope.ge = true;
}
So change to
$scope.someProperFunctionName = function () {
$scope.ge = true;
}
HTML
<input name="cssPre" id="css1" value="geEmp" class="input-xlarge" type="radio" data-ng-model="addUser.Emp" ng-change="someProperFunctionName ()">

Angularjs Form Validation of a group of input

With Angular I use specific directive for validate single input field. (i.e. email, username etc.)
In this project I have this scenario:
I need to set an Advance Payment field, this Advance must be between min/max value.
To set the Advance I have three input text:
Cash
Old Car Value
Financed Advance
the sum of those three input is my Advance value.
So I need to validate Advance but I have no a single input with ng-model setted on.
What is the best way to check and validate the Advance Payment value?
I need to add a directive to all those three input fields? or is better a directive for the form?
Any suggestion will be appreciated.
jsfiddle example
(function () {
var app = angular.module("myApp", ['ngMessages']);
app.controller('myFormCtrl', function($scope) {
$scope.plan = {};
$scope.plan.advance = 0;
$scope.plan.min_advance = 3000;
$scope.plan.max_advance = 6000;
$scope.updateAdvance = function(){
var advance = 0;
if ($scope.quotationAdvanceType && !isNaN($scope.plan.quotation))
advance += $scope.plan.quotation;
if ($scope.cashAdvanceType && !isNaN($scope.plan.cash))
advance += $scope.plan.cash;
if ($scope.financedAdvanceType && !isNaN($scope.plan.financed))
advance += $scope.plan.financed;
$scope.plan.advance = advance;
}
});
})();
Just to give you (and perhaps others) another option.
To simplify, you can use a number input with its ng-model set to plan.advance. This will allow you to use the min/max attributes. You can set the input to hidden if you prefer not to display it.
<input type="number" name="advance" ng-model="plan.advance" min="{{plan.min_advance}}" max="{{plan.max_advance}}" hidden />
Then you can use the built in validation for min and max such as:
<span ng-messages="myForm.advance.$error" role="alert">
<span ng-message="min">Minimum not reached.</span>
<span ng-message="max">Maximum exceeded.</span>
</span>
Run the code snippet below to see it in action:
(function () {
var app = angular.module("myApp", ['ngMessages']);
app.controller('myFormCtrl', function ($scope) {
var advance = [];
$scope.plan = {};
$scope.plan.advance = 0;
$scope.plan.min_advance = 3000;
$scope.plan.max_advance = 6000;
$scope.reset = function(val) {
$scope.plan[val] = undefined;
$scope.updateAdvance();
};
$scope.updateAdvance = function () {
advance = [$scope.plan.quotation, $scope.plan.cash, $scope.plan.financed];
$scope.plan.advance = advance.reduce(function (a, b) {
a = a ? a : 0;
b = b ? b : 0;
return a + b;
}, 0);
}
});
})();
#import url("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css");
<script src="https://code.angularjs.org/1.3.15/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.15/angular-messages.min.js"></script>
<div ng-app="myApp" class="container">
<form name="myForm" ng-controller="myFormCtrl" class="form-horizontal">
<div class="form-group" ng-class="{ 'has-error' : myForm.plan.min_advance.$invalid && myForm.plan.min_advance.$touched}">
<label for="plan.min_advance" class="control-label col-xs-4 col-sm-2">Min Advance</label>
<div class="col-xs-8 col-sm-10">
<input type="number" ng-model="plan.min_advance" class="form-control" />
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : myForm.plan.max_advance.$invalid && myForm.plan.max_advance.$touched}">
<label for="plan.max_advance" class="control-label col-xs-4 col-sm-2">Min Advance</label>
<div class="col-xs-8 col-sm-10">
<input type="number" ng-model="plan.max_advance" class="form-control" />
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : myForm.surname.$invalid && myForm.surname.$touched}">
<div class="col-xs-12">
<label for="surname" class="control-label">Surname</label>
<input type="text" value="" name="surname" id="surname" ng-model="surname" ng-minlength="3" ng-mAXlength="20" required="required" class="form-control" />
<span ng-messages="myForm.surname.$error" class="help-block" role="alert" ng-show="myForm.surname.$touched">
<span ng-message="required">You forgot to enter your surname</span>
<span ng-message="minlength">Surname is too short</span>
<span ng-message="maxlength">Surname is too long</span>
</span>
</div>
</div>
<p>Set the Advance between minimun <strong>{{plan.min_advance | currency}}</strong> and maximum <strong>{{plan.max_advance | currency}}</strong>
</p>
<div class="form-group">
<label for="quotation" class="col-xs-4 col-sm-2 control-label">
<input type="checkbox" name="quotationAdvanceType" ng-model="quotationAdvanceType" ng-change="reset('quotation')"/> Quotation:
</label>
<div class="col-xs-8 col-sm-10">
<input type="number" name="quotation" ng-value="plan.quotation" ng-model="plan.quotation" ng-change="updateAdvance()" class="form-control" ng-disabled="!quotationAdvanceType" placeholder="{{'max '+ (plan.max_advance-plan.advance)}}" />
</div>
</div>
<div class="form-group">
<label for="cash" class="col-xs-4 col-sm-2 control-label">
<input type="checkbox" name="cashAdvanceType" ng-model="cashAdvanceType" ng-change="reset('cash')" /> Cash:
</label>
<div class="col-xs-8 col-sm-10">
<input type="number" name="cash" ng-value="plan.cash" ng-model="plan.cash" ng-change="updateAdvance()" class="form-control" ng-disabled="!cashAdvanceType" placeholder="{{'max '+ (plan.max_advance-plan.advance)}}" />
</div>
</div>
<div class="form-group">
<label for="financed" class="col-xs-4 col-sm-2 control-label">
<input type="checkbox" name="financedAdvanceType" ng-model="financedAdvanceType" ng-change="reset('financed')" /> Financed:
</label>
<div class="col-xs-8 col-sm-10">
<input type="number" name="financed" ng-value="0" ng-model="plan.financed" ng-change="updateAdvance()" class="form-control" ng-disabled="!financedAdvanceType" placeholder="{{'max '+ (plan.max_advance-plan.advance)}}" />
</div>
</div>
<div ng-class="{'has-error' : myForm.advance.$invalid && (quotationAdvanceType || cashAdvanceType || financedAdvanceType) && (myForm.quotation.$dirty || myForm.cash.$dirty || myForm.financed.$dirty)}">
<input type="number" name="advance" ng-model="plan.advance" min="{{plan.min_advance}}" max="{{plan.max_advance}}" hidden />
<p class="help-block">Total Advance: <strong>{{plan.advance ? (plan.advance | currency) : 'none'}}</strong>
<span ng-messages="myForm.advance.$error" role="alert" ng-show="myForm.quotation.$dirty || myForm.cash.$dirty || myForm.financed.$dirty">
<span ng-message="min">Minimum not reached.</span>
<span ng-message="max">Maximum exceeded.</span>
</span>
</p>
</div>
<button type="submit" class="btn btn-primary" ng-disabled="myForm.$invalid">Send</button>
</form>
</div>
Is there an advantage over your custom directive approach? I would say yes and here's why:
Your directive is tightly coupled to your controller scope, so you can't reuse it elsewhere in your application and it will require you to separately update it if you change one of your scope variables in the future.
You are essentially duplicating code for functionality that already exists in the framework. That results in more upfront cost of development and maintenance effort down the line.
I solve my question with a brand new directive.
I don't know if this is the right way to do that, but it works fine and the behaviour is correct.
app.directive('totalAdvance', function() {
return {
restrict: 'E',
require: '^form',
link: function(scope, element, attrs, formCtrl) {
var advanceValue = 0;
var advanceValidator = function() {
if (advanceValue >= attrs.min && advanceValue <= attrs.max){
formCtrl.$setValidity('minAdvance', true);
formCtrl.$setValidity('maxAdvance', true);
return advanceValue;
}else if (advanceValue < attrs.min) {
formCtrl.$setValidity('minAdvance', false);
formCtrl.$setValidity('maxAdvance', true);
return null;
}else if (advanceValue > attrs.max){
formCtrl.$setValidity('minAdvance', true);
formCtrl.$setValidity('maxAdvance', false);
return null;
}
};
scope.$watch('plan.advance', function(value) {
advanceValue = value;
return advanceValidator();
});
scope.$watch('plan.min_advance', function() {
return advanceValidator();
});
scope.$watch('plan.max_advance', function() {
return advanceValidator();
});
}
};
});
jsfiddle example

how to append typeahead dynamically by click?

Am new to angularjs. and am using this link to create typeahead.
It is working fine. but am unable to create this dynamically.
Please refer a solution.
This is my code
$scope.addField = function() {
var html = '<div class="form-group">
<label for="area2">Area 2</label>
<input type="text" name="area2" ng-model="doctor.area2" placeholder="Search Countries" typeahead="c as c.country for c in countries | orderBy:'+"'country'"+' | filter:$viewValue | limitTo:10" typeahead-min-length="1" typeahead-on-select="onSelectPart($item, $model, $label)" typeahead-template-url="customTemplate.html" class="form-control" >
</div>';
var topScope = angular.element(document).scope();
var elem = $compile(html)(topScope);
angular.element(document.getElementById('more_Areas')).append(elem);
};
<div class="form-group" >
<label ><a ng-click='addField()'>Add More Practice Areas</a></label>
</div>
<div id="more_Areas" >
</div>
You could use this, I've used it a couple of times.. and you can also specify a model for each new field you add by changing the ng-model to field.modelName
$scope.fields = [];
$scope.addField = function() {
var topScope = angular.element(document).scope();
var elem = $compile(html)(topScope);
$scope.fields.push({});
};
<div class="form-group" >
<label>
<a ng-click='addField()'>Add More Practice Areas</a>
</label>
</div>
<div id="more_Areas" >
<div ng-repeat="field in fields">
<input name="category" type="text" ng-model="person.category" placeholder="Category" required/> <span class="alert alert-error ng-show="add-bro.input.$error.required">Required</span>
</div>
</div>

Resources