Dynamically creating ng-model values - angularjs

I am building out a debt consolidation calculator that has two tables that allows the user to add and remove rows. The rows contain 4 inputs for different values:
code plunker: plnkr.co/edit/AS6M8zi3VrqKKgfTGwVT?p=preview
HTML
.directive('cuDebtConsolidation',
function() {
return {
restrict: 'E',
scope: false,
template:
'<div id="debtConsolidationPrint">' +
'<form name="debtConsolidationForm" role="form" data-toggle="validator" novalidate>' +
'<div class="row mb-3 mt-5 mx-auto calcRow">' +
'<div class="col m-3">' +
'<div ng-repeat="table in tables">' +
'<h3 class="mt-4">{{table.name}}</h3>' +
'<table>' +
'<thead>' +
'<tr>' +
'<th>Loan Name</th>' +
'<th>Remaining Balance</th>' +
'<th>Monthly Payment</th>' +
'<th>Loan Term</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr ng-repeat="(rowIndex, row) in table.rows" name="{{row.name}}">' +
'<td><input class="form-control form-control-md text-transform-none" title="Please Enter loan name" maxlength="7" required type="text"></td>' +
'<td><input class="form-control form-control-md text-transform-none" title="Please Enter remaining balance" maxlength="7" required type="number"></td>' +
'<td><input class="form-control form-control-md text-transform-none" title="Please Enter Monthly Payment" maxlength="7" required type="number"></td>' +
'<td><input class="form-control form-control-md text-transform-none" title="Please Enter loan term" maxlength="7" required type="number" ></td>' +
'<td><input type="button" class="btn btn-round btn-sm btn-brand" value="Remove" ng-click="removeRow(rowIndex, table)"/></td>' +
'</tr>' +
'</tbody>' +
'</table>' +
'<button class="btn btn-round btn-sm btn-brand mt-2" ng-click="addRow(table)">Add Row</button>' +
'</div>' +
'<div class="d-flex">' +
'<button class="btn btn-round btn-lg btn-brand d-block mt-2 w-100" ng-click="debtConsolidation();">Calculate!</button>' +
'</div>' +
'</div>' +
'</div>' +
'</form>' +
'</div>'
};
});
Controller:
$scope.tables=[{name: "Installment Table"}, {name: "Credit Card Table"}];
$scope.tables[0].rows = [{name: "row1"}];
$scope.tables[1].rows = [{name: "row1"}];
$scope.counter = 2;
$scope.addRow = function(table) {
table.rows.push({ name: "row" + $scope.counter});
$scope.counter++;
};
$scope.removeRow = function(rowIndex, table) {
table.rows.splice(rowIndex, 1);
};
$scope.debtConsolidation = function() {
console.log($scope.debtConsolidationForm);
};
I use ng-repeat to loop over the two tables and then ng-repeat to loop over the rows. This is all within a form, I'm try to ng-click="debtConsolidation();" run calculations but i cant seem to figure out how to bind the dynamic inputs to then be able to use the data from each dynamic row.

You can give each input an ng-model attribute. This will put a value property on your $scope.tables.rows object.
Here's an example:
'<tbody>' +
'<tr ng-repeat="(rowIndex, row) in table.rows" name="{{row.name}}">' +
'<td><input ng-model="row.loanName" class="form-control form-control-md text-transform-none" title="Please Enter loan name" maxlength="7" required type="text"></td>' +
'<td><input ng-model="row.remainingBalance" class="form-control form-control-md text-transform-none" title="Please Enter remaining balance" maxlength="7" required type="number"></td>' +
'<td><input ng-model="row.monthlyPayment" class="form-control form-control-md text-transform-none" title="Please Enter Monthly Payment" maxlength="7" required type="number"></td>' +
'<td><input ng-model="row.loanTerm" class="form-control form-control-md text-transform-none" title="Please Enter loan term" maxlength="7" required type="number" ></td>' +
'<td><input type="button" class="btn btn-round btn-sm btn-brand" value="Remove" ng-click="removeRow(rowIndex, table)"/></td>' +
'</tr>' +
'</tbody>'
And if you console.log the object in the $scope.debtConsolidation function, you can see the object.

Related

$parent.$index displaying incorrectly in ng-repeat

I have a repeater nested in another repeater. I need to create unique element names for fields that I need to be required. I'm using the $parent$.$index method to create unique name attributes but for some reason, it's not working on the textbox input. I pulled out the ng-model and assigned the same naming code into the input's value attribute and it creates the value correctly. What am I doing wrong here or how can I do this a different way that works.
<div ng-repeat="r in model.form.rules" class="form-inline">
<fieldset>
<legend>
<span class="pull-right">
<button class="btn btn-default btn-xs" ng-click="model.copyRule(r)"><span class="fa fa-copy"></span></button>
<button class="btn btn-danger btn-xs" ng-click="model.deleteRule(r)"><span class="fa fa-remove"></span></button>
</span>
Rule {{$index + 1}}
</legend>
<div ng-repeat="c in r.conditions">
<div class="form-group" ng-show="$index > 0">
<select class="form-control" ng-model="r.conjunction">
<option>or</option>
<option>and</option>
</select>
</div>
<div class="input-group" ng-class="{ 'has-error': (rulesForm['ConditionField_' + $parent.$index + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['ConditionField_' + $parent.$index + '_' + $index].$invalid && !rulesForm['ConditionField_' + $parent.$index + '_' + $index].$pristine && rulesForm['ConditionField_' + $parent.$index + '_' + $index].$touched) }">
<span class="input-group-addon">IF</span>
<select class="form-control" name="{{'ConditionField_' + $parent.$index + '_' + $index}}" ng-model="c.field" ng-options="f.label for f in model.form.fields" required>
<option value="">-- Select a Field --</option>
</select>
</div>
<span ng-switch="c.field.type">
<select class="form-control" ng-model="c.numberCondition" ng-switch-when="number">
<option>is equal to</option>
<option>is greater than</option>
<option>is less than</option>
</select>
<select class="form-control" ng-model="c.dateCondition" ng-switch-when="date">
<option>is on</option>
<option>is before</option>
<option>is after</option>
<option>is not on</option>
</select>
<select class="form-control" ng-model="c.condition" ng-switch-default>
<option>is</option>
<option>is not</option>
<option>contains</option>
<option>does not contain</option>
<option>begins with</option>
<option>ends with</option>
</select>
</span>
<span ng-switch="c.field.type">
<span ng-class="{ 'has-error': (rulesForm['NumberValue_' + $parent.$index + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['NumberValue_' + $parent.$index + '_' + $index].$invalid && !rulesForm['NumberValue_' + $parent.$index + '_' + $index].$pristine && rulesForm['NumberValue_' + $parent.$index + '_' + $index].$touched) }">
<input type="number" class="form-control" name="{{'NumberValue_' + $parent.$index + '_' + $index}}" ng-switch-when="number" required />
</span>
<span ng-class="{ 'has-error': (rulesForm['DataValue_' + $parent.$index + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['DataValue_' + $parent.$index + '_' + $index].$invalid && !rulesForm['DataValue_' + $parent.$index + '_' + $index].$pristine && rulesForm['DataValue_' + $parent.$index + '_' + $index].$touched) }">
<input type="date" class="form-control" name="{{'DataValue_' + $parent.$index + '_' + $index}}" ng-switch-when="date" required />
</span>
<span ng-class="{ 'has-error': (rulesForm['Value_' + $parent.$index + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['Value_' + $parent.$index + '_' + $index].$invalid && !rulesForm['Value_' + $parent.$index + '_' + $index].$pristine && rulesForm['Value_' + $parent.$index + '_' + $index].$touched) }">
{{'Value_' + $parent.$index + '_' + $index}}<input type="text" class="form-control" name="{{'Value_' + $parent.$index + '_' + $index}}" ng-switch-default required value="{{'Value_' + $parent.$index + '_' + $index}}" />
</span>
</span>
<button class="btn btn-default" ng-click="model.addCondition(r)" ng-show="$index == 0"><span class="fa fa-plus"></span></button>
<button class="btn btn-danger" ng-click="model.deleteCondition(r, c)" ng-show="$index > 0"><span class="fa fa-remove"></span></button>
<br /><br />
</div>
<div class="input-group">
<span class="input-group-addon">THEN</span>
<select class="form-control" ng-model="r.action">
<option value="hide">hide</option>
<option value="require">require</option>
</select>
</div>
<span ng-class="{ 'has-error': (rulesForm['ActionField_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['ActionField_' + $index].$invalid && !rulesForm['ActionField_' + $index].$pristine && rulesForm['ActionField_' + $index].$touched) }">
<select class="form-control" name="{{'ActionField_' + $index}}" ng-model="r.field" ng-options="f.label for f in model.form.fields" required>
<option value="">-- Select a Field --</option>
</select>
</span>
<br /><br />
</fieldset>
</div>
<div class="form-group">
<button type="button" ng-click="model.addRule()" class="btn btn-default">Add Rule</button>
</div>
First Init the parent index into other variable
<div ng-repeat="r in model.form.rules" class="form-inline" ng-init="parentIndex = $index">
<fieldset>
<legend>
<span class="pull-right">
<button class="btn btn-default btn-xs" ng-click="model.copyRule(r)"><span class="fa fa-copy"></span></button>
<button class="btn btn-danger btn-xs" ng-click="model.deleteRule(r)"><span class="fa fa-remove"></span></button>
</span>
Rule {{$index + 1}}
</legend>
<div ng-repeat="c in r.conditions">
<div class="form-group" ng-show="$index > 0">
<select class="form-control" ng-model="r.conjunction">
<option>or</option>
<option>and</option>
</select>
</div>
<div class="input-group" ng-class="{ 'has-error': (rulesForm['ConditionField_' + parentIndex + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['ConditionField_' + parentIndex + '_' + $index].$invalid && !rulesForm['ConditionField_' + parentIndex + '_' + $index].$pristine && rulesForm['ConditionField_' + parentIndex + '_' + $index].$touched) }">
<span class="input-group-addon">IF</span>
<select class="form-control" name="{{'ConditionField_' + parentIndex + '_' + $index}}" ng-model="c.field" ng-options="f.label for f in model.form.fields" required>
<option value="">-- Select a Field --</option>
</select>
</div>
<span ng-switch="c.field.type">
<select class="form-control" ng-model="c.numberCondition" ng-switch-when="number">
<option>is equal to</option>
<option>is greater than</option>
<option>is less than</option>
</select>
<select class="form-control" ng-model="c.dateCondition" ng-switch-when="date">
<option>is on</option>
<option>is before</option>
<option>is after</option>
<option>is not on</option>
</select>
<select class="form-control" ng-model="c.condition" ng-switch-default>
<option>is</option>
<option>is not</option>
<option>contains</option>
<option>does not contain</option>
<option>begins with</option>
<option>ends with</option>
</select>
</span>
<span ng-switch="c.field.type">
<span ng-class="{ 'has-error': (rulesForm['NumberValue_' + parentIndex + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['NumberValue_' + parentIndex + '_' + $index].$invalid && !rulesForm['NumberValue_' + parentIndex + '_' + $index].$pristine && rulesForm['NumberValue_' + parentIndex + '_' + $index].$touched) }">
<input type="number" class="form-control" name="{{'NumberValue_' + parentIndex + '_' + $index}}" ng-switch-when="number" required />
</span>
<span ng-class="{ 'has-error': (rulesForm['DataValue_' + parentIndex + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['DataValue_' + parentIndex + '_' + $index].$invalid && !rulesForm['DataValue_' + parentIndex + '_' + $index].$pristine && rulesForm['DataValue_' + parentIndex + '_' + $index].$touched) }">
<input type="date" class="form-control" name="{{'DataValue_' + parentIndex + '_' + $index}}" ng-switch-when="date" required />
</span>
<span ng-class="{ 'has-error': (rulesForm['Value_' + parentIndex + '_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['Value_' + parentIndex + '_' + $index].$invalid && !rulesForm['Value_' + parentIndex + '_' + $index].$pristine && rulesForm['Value_' + parentIndex + '_' + $index].$touched) }">
{{'Value_' + parentIndex + '_' + $index}}<input type="text" class="form-control" name="{{'Value_' + parentIndex + '_' + $index}}" ng-switch-default required value="{{'Value_' + parentIndex + '_' + $index}}" />
</span>
</span>
<button class="btn btn-default" ng-click="model.addCondition(r)" ng-show="$index == 0"><span class="fa fa-plus"></span></button>
<button class="btn btn-danger" ng-click="model.deleteCondition(r, c)" ng-show="$index > 0"><span class="fa fa-remove"></span></button>
<br /><br />
</div>
<div class="input-group">
<span class="input-group-addon">THEN</span>
<select class="form-control" ng-model="r.action">
<option value="hide">hide</option>
<option value="require">require</option>
</select>
</div>
<span ng-class="{ 'has-error': (rulesForm['ActionField_' + $index].$invalid && rulesForm.$submitted) || (rulesForm['ActionField_' + $index].$invalid && !rulesForm['ActionField_' + $index].$pristine && rulesForm['ActionField_' + $index].$touched) }">
<select class="form-control" name="{{'ActionField_' + $index}}" ng-model="r.field" ng-options="f.label for f in model.form.fields" required>
<option value="">-- Select a Field --</option>
</select>
</span>
<br /><br />
</fieldset>
</div>
<div class="form-group">
<button type="button" ng-click="model.addRule()" class="btn btn-default">Add Rule</button>
</div>

ng-model not updated for select drop-down list in angular ui-bootstrap modal

Please see the problem in action:
Working Plunker
I have a web page for adding person info. It should allow add/edit/delete multiple addresses for the person.
There is an Add New Address button on the page which opens a modal dialog to enter address info.
Clicking on Add Address button in modal dialog adds this address to the addresses list in the page.
After adding an address, the user can click on Edit button to edit it. This is where I am having issues.
For some reason, while editing an address, the drop-down lists for Address Type and State are not getting updated with model values even though values are seemingly set and served.
I am using angular 1.6.2 with angular-ui-bootstrap 2.5.0 for this.
This is because you are using ng-option as ng-options="key as value for (key, value) in $ctrl.statesjson track by key" so due to this key value pairs angular is not able to bind value from your dropdown.
Use ng-repeat instead of ng-options T
Try this
<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap#3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script data-require="jquery#3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script data-require="bootstrap#3.3.7" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script data-require="angularjs#1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
<script data-require="ui-bootstrap#2.5.0" data-semver="2.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script>
(function (angular)
{
"use strict";
// make sure you define all dependencies in main app only
// you need NOT define these again in dependent components
var addPerson = angular.module('addPerson', ['ui.bootstrap']);
// only pass required dependencies in the controller
// just because you've defined the dependency 'ui.bootstrap' in main app
// does NOT necessarily require you to pass it again in the controller
// when you do not use it here
addPerson.controller('myCtrl', ['appFactory', '$scope', '$filter', '$log', function (appFactory, $scope, $filter, $log) {
// functions must be defined before they are called
var clearPerson = function () {
$scope.selTitleVal = "";
$scope.fname = "";
$scope.mi = "";
$scope.lname = "";
return (null);
};
// clear all entries
clearPerson();
}])
.factory('appFactory', function () {
return {};
});
})(window.angular);
</script>
<script>
/*
Contains following custom angular components:
1. addresses: Add Address button and displays the list of addresses added with Edit, Delete buttons
2. addressModal: Modal dialog to add/edit an address
*/
// 1. Angular Component: addresses
(function (angular) {
'use strict';
var stmpl = '';
stmpl += '<div><input type="button" class="btn btn-info" value="+ Address" ng-click="$ctrl.open();" /></div>';
stmpl += '<table class="table table-striped table-bordered" ng-if="$ctrl.isShow">';
stmpl += ' <thead>';
stmpl += ' <tr>';
stmpl += ' <th style="display:none">Address Type Id</th>';
stmpl += ' <th>Address Type</th>';
stmpl += ' <th>Address1</th>';
stmpl += ' <th style="display:none">State Id</th>';
stmpl += ' <th>Actions</th>';
stmpl += ' </tr>';
stmpl += ' </thead>';
stmpl += ' <tbody>';
stmpl += ' <tr ng-repeat="x in $ctrl.addresses track by $index">';
stmpl += ' <td style="display:none">{{ x.addresstypeid }}</td>';
stmpl += ' <td>{{ x.addresstype }}</td>';
stmpl += ' <td>{{ x.address1 }}<br />{{ x.address2 }}<br />{{ x.city }} {{ x.state }} {{ x.zip }}</td>';
stmpl += ' <td style="display:none">{{ x.stateid }}</td>';
stmpl += ' <td><input type="button" class="btn-xs btn-info" style="width:60px" value="Edit..." ng-click="$ctrl.editAddress($index);" /> <input type="button" class="btn-xs btn-info" style="width:60px" value="Delete..." ng-click="$ctrl.deleteAddress($index);" /></td>';
stmpl += ' </tr>';
stmpl += ' </tbody>';
stmpl += '</table>';
stmpl += '<br />';
function tableRowController($scope, $uibModal) {
this.$scope = $scope;
// these are fields in modal dialog - format for json
$scope.$ctrl.dataForModal = {
addresstypeid: '',
addresstype: '',
address1: '',
address2: '',
city: '',
stateid: '',
state: '',
zip: ''
};
$scope.$ctrl.title = "Addresses";
$scope.$ctrl.addresses = [];
$scope.$ctrl.isShow = false;
// below is how you call the dependent component 'addressModal'
// +Address is button's click event is wired to this
$scope.$ctrl.open = function () {
$scope.$ctrl.title = "Add New Address";
// read documentation for 'ui.bootstrap.modal'
// open the modal dialog for Add Address
$uibModal.open({
// addressModal.init() - initialize the modal dialog
component: "addressModal",
//windowClass: "my-dialog",
resolve: {
modalData: function () {
return $scope.$ctrl.dataForModal;
},
title: function(){
return $scope.$ctrl.title;
}
}
}).result.then(function (result) {
$scope.$ctrl.result = result;
console.info(result);
$scope.$ctrl.addAddress();
}, function (reason) {
// addressModal.closeAddress() is invoked here - same as cancel the modal dialog event
});
};
$scope.$ctrl.addAddress = function () {
$scope.$ctrl.addresses.push({
addresstypeid: $scope.$ctrl.result.addresstypeid,
addresstype: $scope.$ctrl.result.addresstype,
address1: $scope.$ctrl.result.address1,
address2: $scope.$ctrl.result.address2,
city: $scope.$ctrl.result.city,
stateid: $scope.$ctrl.result.stateid,
state: $scope.$ctrl.result.state,
zip: $scope.$ctrl.result.zip
});
$scope.$ctrl.isShow = true;
}
$scope.$ctrl.deleteAddress = function ($index) {
if (confirm("Do you want to delete this address?\r\nOK: Yes Cancel: No")) {
$scope.$ctrl.addresses.splice($index, 1);
if ($scope.$ctrl.addresses.length > 0) $scope.$ctrl.isShow = true;
else $scope.$ctrl.isShow = false;
}
}
$scope.$ctrl.editAddress = function ($index) {
$scope.$ctrl.title = "Edit Address";
$scope.$ctrl.dataForModal = {
addresstypeid: $scope.$ctrl.addresses[$index].addresstypeid,
addresstype: $scope.$ctrl.addresses[$index].addresstype,
address1: $scope.$ctrl.addresses[$index].address1,
address2: $scope.$ctrl.addresses[$index].address2,
city: $scope.$ctrl.addresses[$index].city,
stateid: $scope.$ctrl.addresses[$index].stateid,
state: $scope.$ctrl.addresses[$index].state,
zip: $scope.$ctrl.addresses[$index].zip
};
$uibModal.open({
// addressModal.init() - initialize the modal dialog
component: "addressModal",
scope: $scope,
resolve: {
modalData: function () {
$scope.$ctrl.dataForModal.addresstypeid = "102";
$scope.$ctrl.dataForModal.addresstype = "PO Box";
return $scope.$ctrl.dataForModal;
},
title: function () {
return $scope.$ctrl.title;
}
}
}).result.then(function (result) {
$scope.$ctrl.result = result;
console.info(result);
$scope.$ctrl.addresses[$index].addresstypeid = $scope.$ctrl.result.addresstypeid;
$scope.$ctrl.addresses[$index].addresstype = $scope.$ctrl.result.addresstype;
$scope.$ctrl.addresses[$index].address1 = $scope.$ctrl.result.address1;
$scope.$ctrl.addresses[$index].address2 = $scope.$ctrl.result.address2;
$scope.$ctrl.addresses[$index].city = $scope.$ctrl.result.city;
$scope.$ctrl.addresses[$index].stateid = $scope.$ctrl.result.stateid;
$scope.$ctrl.addresses[$index].state = $scope.$ctrl.result.state;
$scope.$ctrl.addresses[$index].zip = $scope.$ctrl.result.zip;
$scope.$ctrl.isShow = true;
}, function (reason) {
// addressModal.closeAddress() is invoked here - same as cancel the modal dialog event
});
}
}
angular.module('addPerson').component('addresses', {
bindings: { title: '<' }, // two way data-binding
template: stmpl,
controller: tableRowController
});
})(window.angular);
// 2. Angular Component: addressModal
(function (angular) {
var stmpl = "";
stmpl += '<!-- MODAL DIALOG: Add Address -->';
stmpl += ' <div class="modal-content">';
stmpl += ' <div class="modal-header">';
stmpl += ' <button type="button" class="close" data-dismiss="modal" ng-click="$ctrl.closeAddress();">×</button>';
stmpl += ' <h4 class="modal-title">{{ $ctrl.title }}</h4>';
stmpl += ' </div>';
stmpl += ' <div class="modal-body">';
stmpl += ' <div class="row form-group">';
stmpl += ' <label class="control-label col-md-2" for="ddlAddressType">Address Type</label>';
stmpl += ' <div class="col-md-10">';
stmpl += ' <select class="form-control" id="ddlAddressType" name="ddlAddressType" ng-model="$ctrl.modalData.addresstypeid" ng-change="$ctrl.changeAddressType();">';
stmpl += ' <option value="">** Select Address Type **</option >';
stmpl += ' <option ng-repeat="(id, value) in $ctrl.addresstypesjson track by id" value="{{id}}">{{value}}</option>';
stmpl += ' </select>';
stmpl += ' <span class="field-validation-valid text-danger" data-valmsg-for="ddlAddressType" data-valmsg-replace="true"></span>';
stmpl += ' </div> ';
stmpl += ' </div>';
stmpl += ' <div class="row form-group">';
stmpl += ' <label class="control-label col-md-2" for="Address1">Address1</label>';
stmpl += ' <div class="col-md-10">';
stmpl += ' <input class="form-control text-box single-line" id="Address1" name="Address1" ng-model="$ctrl.modalData.address1" type="text" value="" />';
stmpl += ' <span class="field-validation-valid text-danger" data-valmsg-for="Address1" data-valmsg-replace="true"></span>';
stmpl += ' </div> ';
stmpl += ' </div>';
stmpl += ' <div class="row form-group">';
stmpl += ' <label class="control-label col-md-2" for="Address1">Address2</label>';
stmpl += ' <div class="col-md-10">';
stmpl += ' <input class="form-control text-box single-line" id="Address2" name="Address2" ng-model="$ctrl.modalData.address2" type="text" value="" />';
stmpl += ' <span class="field-validation-valid text-danger" data-valmsg-for="Address2" data-valmsg-replace="true"></span>';
stmpl += ' </div>';
stmpl += ' </div>';
stmpl += ' <div class="row form-group">';
stmpl += ' <label class="control-label col-md-2" for="City">City</label>';
stmpl += ' <div class="col-md-10">';
stmpl += ' <input class="form-control text-box single-line" id="City" name="City" ng-model="$ctrl.modalData.city" type="text" value="" />';
stmpl += ' <span class="field-validation-valid text-danger" data-valmsg-for="City" data-valmsg-replace="true"></span>';
stmpl += ' </div>';
stmpl += ' </div>';
stmpl += ' <div class="row form-group">';
stmpl += ' <label class="control-label col-md-2" for="ddlState">State</label>';
stmpl += ' <div class="col-md-10">{{getValue($ctrl.modalData.stateid)}}';
stmpl += ' <select class="form-control" id="ddlState" name="ddlState" ng-model="$ctrl.modalData.stateid">';
stmpl += ' <option value="">** Select State **</option>';
stmpl += ' <option ng-repeat="(id, value) in $ctrl.statesjson" value="{{id}}">{{value}}</option>';
stmpl += ' </select>';
stmpl += ' <span class="field-validation-valid text-danger" data-valmsg-for="ddlState" data-valmsg-replace="true"></span>';
stmpl += ' </div>';
stmpl += ' </div>';
stmpl += ' <div class="row form-group">';
stmpl += ' <label class="control-label col-md-2" for="Zip">Zip</label>';
stmpl += ' <div class="col-md-10">';
stmpl += ' <input class="form-control text-box single-line" id="Zip" name="Zip" ng-model="$ctrl.modalData.zip" type="text" value="" />';
stmpl += ' <span class="field-validation-valid text-danger" data-valmsg-for="Zip" data-valmsg-replace="true"></span>';
stmpl += ' </div> ';
stmpl += ' </div>';
stmpl += ' </div>';
stmpl += ' <div class="modal-footer">';
stmpl += ' <input type="button" value="Add Address" class="btn btn-success" ng-click="$ctrl.addAddress();"/>';
stmpl += ' <input type="button" value="Close" class="btn btn-default" ng-click="$ctrl.closeAddress();" />';
stmpl += ' </div>';
stmpl += ' </div> <!-- model - content -->';
function tableRowController($scope, $http, $uibModal) {
this.$scope = $scope;
//var $ctrl = this;
$scope.$ctrl.addresstypesjson = {"100": "Home", "101": "Work", "102": "PO Box"};
$scope.$ctrl.statesjson = {"AN": "Andaman and Nicobar Islands", "AP": "Andhra Pradesh", "AR": "Arunachal Pradesh", "DD": "Daman and Diu", "DH": "Dadra and Nagar Haveli", "DL": "Delhi"};
// Events
// 1. init - initialize
$scope.$ctrl.$onInit = function () {
$scope.$ctrl.modalData = $scope.$ctrl.resolve.modalData;
$scope.$ctrl.title = $scope.$ctrl.resolve.title;
if ($scope.$ctrl.title != "Edit Address") {
$scope.$ctrl.modalData.addresstypeid = "";
$scope.$ctrl.modalData.addresstype = "";
$scope.$ctrl.modalData.address1 = "";
$scope.$ctrl.modalData.address2 = "";
$scope.$ctrl.modalData.city = "";
$scope.$ctrl.modalData.stateid = "";
$scope.$ctrl.modalData.state = "";
$scope.$ctrl.modalData.zip = "";
}
}
// 2. dismiss - cancel model dialog
$scope.$ctrl.closeAddress = function () {
$scope.$ctrl.modalInstance.dismiss("cancel");
}
// 3. close - add new address and close the dialog
$scope.$ctrl.addAddress = function () {
// assign selected text for drop-down list items
$scope.$ctrl.modalData.addresstype = $scope.$ctrl.addresstypesjson[$scope.$ctrl.modalData.addresstypeid];
$scope.$ctrl.modalData.state = $scope.$ctrl.statesjson[$scope.$ctrl.modalData.stateid];
$scope.$ctrl.modalInstance.close($scope.$ctrl.modalData);
}
$scope.getValue = function(id){
debugger
}
$scope.$ctrl.changeAddressType = function () {
console.info("Address Type drop-down list changed");
}
}
// register the component - dependecies automatically follow from app (parent)
angular.module('addPerson').component('addressModal', {
bindings: {
title: '<',
modalInstance: "<",
resolve: "<"
}, // two way data-binding
template: stmpl,
controller: tableRowController
});
})(window.angular);
</script>
</head>
<body>
<h2>Add New Person</h2>
<hr />
<form action="#">
<div class="form-horizontal" ng-app="addPerson" ng-controller="myCtrl">
<div class="form-group">
<label class="control-label col-md-2" for="Title_Title_Title">Title</label>
<div class="col-md-10">
<select class="form-control" id="Title_Title_Title" name="Title.Title_Title" ng-value="selTitleVal"><option value="">** Select Title **</option>
<option value="104">Dr.</option>
<option value="103">Ma'am</option>
<option value="102">Miss</option>
<option value="100">Mr.</option>
<option value="101">Mrs.</option>
<option value="106">Smt.</option>
<option value="105">Sri</option>
</select>
<span class="field-validation-valid text-danger" data-valmsg-for="Title.Title_Title" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="Person_FName">First Name</label>
<div class="col-md-10">
<input class="form-control text-box single-line" id="Person_FName" name="Person_FName" ng-model="fname" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="Person_FName" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="Person_MI">MI</label>
<div class="col-md-10">
<input class="form-control text-box single-line" id="Person_MI" name="Person_MI" ng-model="mi" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="Person_MI" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="Person_LName">Last Name</label>
<div class="col-md-10">
<input class="form-control text-box single-line" id="Person_LName" name="Person_LName" ng-model="lname" type="text" value="" />
<span class="field-validation-valid text-danger" data-valmsg-for="Person_LName" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create Person" class="btn btn-primary" />
</div>
</div>
<div class="container-fluid" style="padding:unset;margin:unset;">
<div class="row" style="padding:unset;margin:unset;">
<div class="col-md-12" style="padding:unset;margin:unset;">
<addresses id="addresses1" title="'Addresses'"></addresses>
</div>
</div>
</div>
</div>
</form>
</body>
</html>
Here is the working plunker.
simple remove track by key syntax from ng-options and everything will be fine.
ng-options="key as value for (key, value) in $ctrl.statesjson" will be fine
see working exmaple
I am not sure, but returned old string
stmpl += '<option ng-repeat="(id, value) in $ctrl.addresstypesjson track by id" value="{{id}}">{{value}}</option>';
Also I found somewhere in your controller this
modalData: function() {
// $scope.$ctrl.dataForModal.addresstypeid = "102";
// $scope.$ctrl.dataForModal.addresstype = "PO Box";
return $scope.$ctrl.dataForModal;
},
So, I commented hardcoded address
My plunkr

How to clear directive ngmodel value from controller?

I am newbie in angularjs. I have create directive called newActivity and bind object, variables and function with this directive. Here i want that when i clicked on submit/cancel button then it should clear all ng-model bind variables from both newActivity directive and from controller.
Example
Directive:-
angular
.module('app')
.directive('newActivity', newActivity);
function newActivity() {
var directive = {
restrict: 'E',
scope: {
newActivity: '=',
underUsers: '=',
actTypes: '=',
callTypes: '=',
forAct: '#',
action: '&',
cancel: '&'
},
template: '<div class="box-header"> <h2>{{forAct}} {{newActivity.type | uppercase}} Activity</h2> </div> <div class="box-divider m-a-0">' +
'</div> <div class="box-body"> <form ng-submit="action()" name="newActForm" role="form">' +
'<div class="form-group row"><div class="col-sm-10"><select class="form-control" ng-model="newActivity.type" ng-options="actType.type as actType.title for actType in actTypes"></select></div></div> ' +
'<div ng-if="newActivity.type==\'notes\'" class="form-group row"><div class="col-sm-10"><textarea required ng-model="newActivity.description" class="form-control" rows="2"></textarea></div></div> ' +
'<div ng-if="newActivity.type==\'meeting\' || newActivity.type==\'email\' || newActivity.type==\'task\'" class="form-group row"><div class="col-sm-10">' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Select Date" type="text" class="form-control w-auto inline" ng-model="newActivity.date" data-date-format="dd-MM-yyyy" data-autoclose="true" data-date-type="number" data-icon-left="fa fa-chevron-left" data-icon-right="fa fa-chevron-right" placeholder="From" bs-datepicker></div></div>' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Select Time" type="text" class="form-control" ng-model="newActivity.time" data-time-format="HH:mm" data-time-type="number" name="time2" data-icon-up="fa fa-chevron-up" data-icon-down="fa fa-chevron-down" bs-timepicker></div></div>' +
'<div class="form-group row"> <label class="col-sm-4 form-control-label">Reminder</label> <div class="col-sm-8"> <div class="checkbox"> <label class="ui-switch m-t-xs m-r"> <input type="checkbox" ng-model="newActivity.isReminder" value=""> <i></i> </label> </div> </div> </div>' +
'<div ng-if="newActivity.isReminder" col-sm-8>' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Reminder Date" type="text" class="form-control w-auto inline" ng-model="newActivity.reminder.date" data-icon-left="fa fa-chevron-left" data-date-format="dd-MM-yyyy" data-autoclose="true" data-date-type="number" data-icon-right="fa fa-chevron-right" placeholder="From" bs-datepicker></div></div> ' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Reminder Time" type="text" class="form-control" ng-model="newActivity.reminder.time" data-time-format="HH:mm" data-time-type="number" name="time1" data-icon-up="fa fa-chevron-up" data-icon-down="fa fa-chevron-down" bs-timepicker></div></div> ' +
'</div>' +
'<div class="form-group row"> <label class="col-sm-4 form-control-label">Assign To Other</label> <div class="col-sm-8"> <div class="checkbox"> <label class="ui-switch m-t-xs m-r"> <input type="checkbox" ng-model="newActivity.isAssignOther" value=""> <i></i> </label> </div> </div> </div>' +
'<div ng-if="newActivity.isAssignOther" col-sm-8>' +
'<div class="form-group row"><div class="col-sm-10"><select class="form-control" ng-model="newActivity.assignTo" ng-options="user._id as user.name for user in underUsers"></select></div></div> ' +
'</div>' +
'<div class="form-group row"><div class="col-sm-10"><textarea required placeholder="Remarks" class="form-control" ng-model="newActivity.description" rows="2"></textarea></div></div>' +
'</div></div> ' +
'<div ng-if="newActivity.type==\'call\'" class="form-group row"><div class="col-sm-10">' +
'<div class="form-group row"><div class="col-sm-10"><select class="form-control" ng-init="newActivity.callType = \'out\'" ng-model="newActivity.callType" ng-options="callType.type as callType.title for callType in callTypes"></select></div></div>' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Select Date" type="text" class="form-control w-auto inline" ng-model="newActivity.date" data-date-format="dd-MM-yyyy" data-autoclose="true" data-date-type="number" data-icon-left="fa fa-chevron-left" data-icon-right="fa fa-chevron-right" placeholder="From" bs-datepicker></div></div>' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Select Time" type="text" class="form-control" ng-model="newActivity.time" data-time-format="HH:mm" data-time-type="number" name="time2" data-icon-up="fa fa-chevron-up" data-icon-down="fa fa-chevron-down" bs-timepicker></div></div>' +
'<div class="form-group row"> <label class="col-sm-4 form-control-label">Reminder</label> <div class="col-sm-8"> <div class="checkbox"> <label class="ui-switch m-t-xs m-r"> <input type="checkbox" ng-model="newActivity.isReminder" value=""> <i></i> </label> </div> </div> </div>' +
'<div ng-if="newActivity.isReminder" col-sm-8>' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Reminder Date" type="text" class="form-control w-auto inline" ng-model="newActivity.reminder.date" data-icon-left="fa fa-chevron-left" data-date-format="dd-MM-yyyy" data-autoclose="true" data-date-type="number" data-icon-right="fa fa-chevron-right" placeholder="From" bs-datepicker></div></div> ' +
'<div class="form-group row"><div class="col-sm-10"><input required placeholder="Reminder Time" type="text" class="form-control" ng-model="newActivity.reminder.time" data-time-format="HH:mm" data-time-type="number" name="time1" data-icon-up="fa fa-chevron-up" data-icon-down="fa fa-chevron-down" bs-timepicker></div></div> ' +
'</div>' +
'<div class="form-group row"> <label class="col-sm-4 form-control-label">Assign To Other</label> <div class="col-sm-8"> <div class="checkbox"> <label class="ui-switch m-t-xs m-r"> <input type="checkbox" ng-model="newActivity.isAssignOther" value=""> <i></i> </label> </div> </div> </div>' +
'<div ng-if="newActivity.isAssignOther" col-sm-8>' +
'<div class="form-group row"><div class="col-sm-10"><select class="form-control" ng-model="newActivity.assignTo" ng-options="user._id as user.name for user in underUsers"></select></div></div> ' +
'</div>' +
'<div class="form-group row"><div class="col-sm-10"><textarea required placeholder="Remarks" class="form-control" ng-model="newActivity.description" rows="2"></textarea></div></div>' +
'</div></div> ' +
'<div class="form-group row m-t-md"> <div class="col-sm-offset-2 col-sm-10">' +
'<input type="submit" class="btn success" value="Save">' +
'<button type="button" style="margin-left:5px" ng-click="cancel()" class="btn danger">Cancel</button>' +
'</div></form> </div>',
link: function(scope, element, attrs) {},
controller: function($scope) {}
};
return directive;
}
Controller:-
function addNewActivity() {
vm.loading = true;
vm.newActivity = {}; //Here vm.newActivity is not clear fields from "newActivity" directive
}
HTML:-
<new-activity for-act='Add' action='addNewActivity()' cancel='closeAddNewActivity()' new-activity='newActivity' under-users='underUsers' act-types='actTypes' call-types='callTypes'></new-activity>
You are using the controllerAs synthax, you should prefix your calls to functions and use of variables with the name you specify (here vm).
For example if your code:
<new-activity for-act='Add'
action='addNewActivity()'
cancel='closeAddNewActivity()'
new-activity='newActivity'
under-users='underUsers'
act-types='actTypes'
call-types='callTypes'>
</new-activity>
Shoud be:
<new-activity for-act='Add'
action='vm.addNewActivity()'
cancel='vm.closeAddNewActivity()'
new-activity='vm.newActivity'
under-users='vm.underUsers'
act-types='vm.actTypes'
call-types='vm.callTypes'>
</new-activity>
Use new-activity='vm.newActivity' instead of new-activity='newActivity
And also use vm.addNewActivity() and vm.closeAddNewActivity()
So that every bindings have the correct source from your controller
<new-activity for-act='Add' action='vm.addNewActivity()' cancel='vm.closeAddNewActivity()' new-activity='vm.newActivity' under-users='vm.underUsers' act-types='vm.actTypes' call-types='vm.callTypes'></new-activity>

How to validate forms in Angular JS

i'm a newbie in angular JS. and i was trying the input type="text", i'm retrieving my name from my controller and i was using $dirty and $invalid to validate my data but it isn't showing when i make the input field empty.
JS Fiddle : https://jsfiddle.net/U3pVM/24718/
var FormValidations = angular.module('FormValidations',[]);
FormValidations.controller('FormsValidations', function( $scope ){
$scope.formsToBeValidated = {
firstName : 'Daniel'
};
});
Unless you add name attribute to form level field, that will not get included in form object when you specified in the name attribute on form, currentlyh it is name="studentForm". Do add name="firstName" to your input field
<input type="text" class="form-control"
name="firstName" ng-model="formsToBeValidated.firstName" required/>
Forked Fiddle
For more information you could refer this answer, which has more detailed
More convenient way to solve this issue would be using ng-messages instead of using ng-show/ng-hide, for that you have to include ng-messages module with its ng-messages dependency.
you should try this:
<input name="firstName" type="text" class="form-control"
ng-model="formsToBeValidated.firstName" required>
fiddle
as other says , add "name" attribute to your input.
I made a custom directive to display error on input using ng-message ( so you have to include it )
directives.directive('inputerrormsg', function () {
return {
replace: true,
restrict: 'E',
plain: true,
scope: {
inputdata: "=",
dpattern: '#'
},
template: '<div class="help-block has-error text-center" ng-messages="inputdata[\'$error\']" >' +
'<p ng-message="required">{{\'The field is required\'| translate }}</p>' +
'<p ng-message="minlength">{{\'Input too short\'| translate }}</p>' +
'<p ng-message="maxlength">{{\'Input too long\'| translate }}</p>' +
'<p ng-message="email">{{\'Email invalid\'| translate }}</p>' +
'<p ng-message="date">{{\'Date invalid\'| translate }}</p>' +
'<p ng-message="number">{{\'Write number only\'| translate }}</p>' +
'<p ng-message="pattern">' +
'<span ng-switch="dpattern">' +
'<span ng-switch-when="date">{{\'Date incorrecte: YYYY, YYYY/MM, YYYY/MM/DD\' |translate}}</span>' +
'<span ng-switch-default>{{\'Saisir uniquement des lettres\'| translate }}</span>' +
'</span>' +
'</p>' +
'</div>'
}
});
USAGE :
required field
<div style="padding-left: 0px;" ng-class="{ 'has-error' : !formDeter.scientificname.$valid">
<div class="input-group no-padding">
<input type="text"
class="form-control input-md" name="scientificname"
required />
<span class="input-group-addon">
<span class="glyphicon glyphicon-question-sign"></span>
</span>
</div>
<dir.inputerrormsg inputdata="formDeter.scientificname" ></dir.inputerrormsg>
EMail :
<div class="form-group row" ng-class="{ 'has-error' : !formData.email.$valid }">
<label class="col-xs-4 control-label">{{"Email" | translate }}</label>
<div class="col-xs-8 input-group">
<input type="email" class="form-control input-md" ng-model="email" name="email" id="email" required
placeholder="{{'Email' | translate }}"/>
</div>
<dir.inputerrormsg inputdata="formData.email" dpattern="email" ></dir.inputerrormsg>
</div>
Number only :
<div class="form-group row" ng-class="{ 'has-error' : !formLocalisation.decimallongitude.$valid }">
<label class="col-xs-4 control-label">{{"Longitude" | translate }}</label>
<div class="col-xs-8 input-group">
<input type="number" popover-trigger="focus" placeholder="{{'Longitude' | translate }}"
class="form-control input-md"
ng-model="specimen.decimallongitude" name="decimallongitude"
/>
<span class="input-group-addon" >
<span class="glyphicon glyphicon-question-sign"></span>
</span>
</div>
<dir.inputerrormsg inputdata="formLocalisation.decimallongitude" ></dir.inputerrormsg>
</div>
...
You didn't specified name to your input. Try this:
<form name="studentForm" novalidate>
<input type="text" class="form-control" name ="input" ng-model="formsToBeValidated.firstName" required>
<span studentForm.input.$error.required && studentForm.input.$dirty>First Name is Required</span>
</form>

how to create dynamic form in angularjs?

My error description:
step 1: I am appending template using this directive.
step 2: Now I remove this appended template using this scope function "removeMilestoneDiv".
step 3: After submit my form. But, I can't submitted.
I think I have add template then bind this scope variable. But, i have remove this template then scope variable is can't unbind.
Create directive for add milestone:
app.directive('addMilestone', ['$compile', function ($compile) { // inject $compile service as dependency
return {
restrict: 'A',
link: function (scope, element, attrs) {
// click on the button to add new input field
element.find('a').bind('click', function () {
// I'm using Angular syntax. Using jQuery will have the same effect
// Create input element
// var input = angular.element('<div id="scope.mileStoneId_'+ scope.mileStoneCounter +'" class="form">Milestone - '+scope.mileStoneCounter+'</div>');
var input = angular.element(''+
'<div class="card bg-white" id="mileStoneDiv_'+ scope.mileStoneCounter +'">'+
'<div class="card-header" ng-bind="\'project.ADD_MILESTONE\' | translate"></div>'+
''+
'<div class="card-block m-b-0">'+
'<div compile-template class="form-group">'+
'<label class="col-sm-2 control-label"><span ng-bind="\'project.COMPANY_MILESTONE_ID\' | translate"></span></label>'+
'<div class="col-sm-5">'+
'<input type="text" class="form-control" ng-model="company_milestone_id['+ scope.mileStoneCounter +']" ng-maxlength="100" name="company_milestone_id_'+ scope.mileStoneCounter +'" required>'+
'<div ng-messages="frmProjectAdd[\'company_milestone_id_'+scope.mileStoneCounter+'\'].$error" role="alert" class="help-block has-error">'+
'<span ng-message="required" class="help-block has-error">Company Milestone Id is required.</span>'+
'<span class="help-block has-error" ng-message="maxlength">Maximum 100 characters allowed!</span>'+
'</div>'+
'</div>'+
'</div>'+
'<div compile-template class="form-group">'+
'<label class="col-sm-2 control-label" ng-bind="\'project.MILESTONE_NAME\' | translate"></label>'+
'<div class="col-sm-5">'+
'<input type="text" ng-maxlength="100" class="form-control" ng-model="milestone_name['+ scope.mileStoneCounter +']" name="milestone_name_'+ scope.mileStoneCounter +'" required>'+
'<div ng-messages="frmProjectAdd[\'milestone_name_'+scope.mileStoneCounter+'\'].$error" class="has-error login-error">'+
'<span ng-message="required" class="help-block has-error">Milestone Name is required.</span>'+
'</div>'+
'</div>'+
'</div>'+
'<div compile-special-template class="form-group">'+
'<label class="col-sm-2 control-label" ng-bind="\'project.SELECT_EMPLOYEE\' | translate"></label>'+
'<div class="col-sm-10">'+
'<select style="min-width:250px;" ui-select2 name="select_new_employee_'+scope.mileStoneCounter+'" ng-model="selectEmployee['+ scope.mileStoneCounter +']" data-placeholder="Select Employee" ng-required="true" multiple>'+
'<option ng-repeat="manager in managerList" value="{{manager.id}}">{{manager.username}}</option>'+
'</select>'+
'</div>'+
'<div ng-messages="frmProjectAdd[\'select_new_employee_'+scope.mileStoneCounter+'\'].$error" class="has-error login-error">'+
'<span ng-message="required" class="help-block has-error">Employee is required.</span>'+
'</div>'+
'</div>'+
'</div>');
// Compile the HTML and assign to scope
var compile = $compile(input)(scope);
// Append input to div
$('#milestoneHtml').append(input);
// Increment the counter for the next input to be added
scope.mileStoneCounter++;
});
}
}
}]);
Remove milestone using this function:
$scope.removeMilestoneDiv = function(key, id, flag) {
var confirmVal = confirm("Are you sure you want to delete this Milestone?");
if(confirmVal) {
$('#mileStoneDiv_'+key).remove();
if(flag == 1){
if(id != 0) {
$scope.deletedMilestoneIds.push(id);
}
}
}
},
Create One Array:
$scope.mileStoneCounterNew = [{
'countId':1,
'company_milestone_id':'',
'milestone_name':'',
'milestone_start_date':'',
'milestone_end_date':'',
'milestone_completion_date':'',
'selectEmployee':'',
}];
Create one scope function
$scope.milestoneHtmlAdd = function() {
$scope.mileStoneCounter++;
var counterObj = {countId: $scope.mileStoneCounter };
$scope.mileStoneCounterNew.push(counterObj);
};
My Dynamic HTML
<!-- Add Milestone - Start -->
<div class="row" ng-repeat="(counterKey, counterValue) in mileStoneCounterNew" id="milestone_display_id_{{counterValue.countId}}">
<div class="card bg-white mt50">
<div class="card-header"><span ng-bind="'project.ADD_MILESTONE' | translate"></span></div>
<a ng-if="counterKey > 0" href="javascript:void(0)" class="removebtn glyphicon glyphicon-remove form-control-feedback" ng-click="milestoneDivRemove(counterKey,0,0)"></a>
<div class="card-block m-b">
<!--Milestone sub section-->
<!-- Company Milestone Id -->
<div class="form-group">
<label class="col-sm-2 control-label"><span ng-bind="'project.COMPANY_MILESTONE_ID' | translate"></span></label>
<div class="col-sm-5">
<input type="text" class="form-control" ng-model="counterValue.company_milestone_id" ng-maxlength="100" name="company_milestone_id_{{counterValue.countId}}" required>
<div ng-if="frmProjectAdd.$submitted || frmProjectAdd['company_milestone_id_'+counterValue.countId].$touched" ng-messages="frmProjectAdd['company_milestone_id_'+counterValue.countId].$error" role="alert" class="help-block has-error">
<span ng-message="required" class="help-block has-error">Company Milestone Id is required.</span>
<span class="help-block has-error" ng-message="maxlength">Maximum 100 characters allowed!</span>
</div>
</div>
</div>
<!-- Milestone name -->
<div class="form-group">
<label class="col-sm-2 control-label"><span ng-bind="'project.MILESTONE_NAME' | translate"></span></label>
<div class="col-sm-5">
<input type="text" class="form-control" ng-model="counterValue.milestone_name" ng-maxlength="100" name="milestone_name_{{counterValue.countId}}" required>
<div ng-if="frmProjectAdd.$submitted || frmProjectAdd['milestone_name_'+counterValue.countId].$touched" ng-messages="frmProjectAdd['milestone_name_'+counterValue.countId].$error" role="alert" class="help-block has-error">
<span ng-message="required" class="help-block has-error">Milestone Name is required.</span>
<span class="help-block has-error" ng-message="maxlength">Maximum 100 characters allowed!</span>
</div>
</div>
</div>
<!-- Milestone Start Date -->
<div class="form-group">
<label class="col-sm-2 control-label"><span ng-bind="'project.MILESTONE_START_DATE' | translate"></span></label>
<div class="col-sm-3">
<div class="input-group">
<input name="milestone_start_date_{{counterValue.countId}}" type="text" uib-datepicker-popup="MM/dd/yyyy" ng-model="counterValue.milestone_start_date" is-open="dpOpened['milestone_start_date_'+counterValue.countId]" ng-click="milestone_start_date[counterValue.countId].open = true" max-date="maxDate" datepicker-options="dateOptions" close-text="Close" ng-required="true" class="form-control"
min-date="minDate" ng-change="set_min_milestone_end_Date(milestone_start_date[counterValue.countId])"
disabled>
<span class="input-group-addon" ng-click="open($event,'milestone_start_date_{{counterValue.countId}}')"><i class="fa fa-calendar"></i></span>
</div>
<div ng-if="frmProjectAdd.$submitted || frmProjectAdd['milestone_start_date_'+counterValue.countId].$touched" ng-messages="frmProjectAdd['milestone_start_date_'+counterValue.countId].$error" role="alert" class="help-block has-error">
<span ng-message="required" class="help-block has-error">Milestone Start Date is required.</span>
</div>
</div>
</div>
<!-- Milestone End Date -->
<div class="form-group">
<label class="col-sm-2 control-label"><span ng-bind="'project.MILESTONE_END_DATE' | translate"></span></label>
<div class="col-sm-3">
<div class="input-group">
<input name="milestone_end_date_{{counterValue.countId}}" type="text" uib-datepicker-popup="MM/dd/yyyy" ng-model="counterValue.milestone_end_date" is-open="dpOpened['milestone_end_date_'+counterValue.countId]" ng-click="milestone_end_date[counterValue.countId].open = true" max-date="maxDate" datepicker-options="dateOptions" close-text="Close" ng-required="true" class="form-control"
min-date="milestone_end_minDate" ng-change="set_min_milestone_completed_Date(milestone_end_date[counterValue.countId])"
disabled>
<span class="input-group-addon" ng-click="open($event,'milestone_end_date_{{counterValue.countId}}')"><i class="fa fa-calendar"></i></span>
<div ng-if="frmProjectAdd.$submitted || frmProjectAdd['milestone_end_date_'+counterValue.countId].$touched" ng-messages="frmProjectAdd['milestone_end_date_'+counterValue.countId].$error" role="alert" class="help-block has-error">
<span ng-message="required" class="help-block has-error">Milestone End Date is required.</span>
</div>
</div>
</div>
</div>
<!-- Milestone Completion Date -->
<div class="form-group">
<label class="col-sm-2 control-label"><span ng-bind="'project.MILESTONE_COMPLETION_DATE' | translate"></span></label>
<div class="col-sm-3">
<div class="input-group">
<input type="text" uib-datepicker-popup="MM/dd/yyyy" ng-model="counterValue.milestone_completion_date" is-open="dpOpened['milestone_completion_date_'+counterValue.countId]" ng-click="milestone_completion_date[counterValue.countId].open = true" max-date="maxDate" datepicker-options="dateOptions" close-text="Close" class="form-control"
min-date="milestone_completed_minDate" disabled>
<span class="input-group-addon" ng-click="open($event,'milestone_completion_date_{{counterValue.countId}}')"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><span ng-bind="'project.SELECT_EMPLOYEE' | translate"></span></label>
<div class="col-sm-10">
<select name="select_employee_{{counterValue.countId}}" ui-select2 ng-model="counterValue.selectEmployee" data-placeholder="Select Employee" ng-required="true" multiple>
<option ng-repeat="manager in managerList" value="{{manager.id}}">{{manager.username}}</option>
</select>
<div ng-if="frmProjectAdd.$submitted || frmProjectAdd['select_employee_'+counterValue.countId].$touched" ng-messages="frmProjectAdd['select_employee_'+counterValue.countId].$error" role="alert" class="help-block has-error">
<span ng-message="required" class="help-block has-error">Employee is required.</span>
</div>
</div>
</div>
<!-- Milestone sub section -->
</div>
</div>
</div>
<!-- Add Milestone End -->

Resources