Need help in implementing look up functionality using angular with spring boot - angularjs

I am new to angular JS and I have a requirement where I need to implement the look up functionality on modal-pop up dialog box.It is similar to finding bank branch using IFSC code lookup.I should be able to serach for a bank using bank name or IFSC code or branch name and then select the bank branch.Please assist.Any demo videos implementing this functionality will help me.
I do have a working code for modal pop-up.But am unable to proceed further.Please let me know if I have to share the code of what has been done so far.
Thanks,
Prashanth
Here is my html code
<div class="container" xmlns="http://www.w3.org/1999/html">
<div class="offset-3"></div>
<form name="form" #f="ngForm" (ngSubmit)="f.form.valid && saveData()" novalidate class="feedback-form">
<div class="row">
<div class="col">
<label for="accession">Accession</label>
<input type="text"
id="accession"
class="form-control"
name="accession"
[(ngModel)]="model.accession"/>
</div>
<div class="col">
<label for="template">Template</label>
<input type="text"
id="template"
class="form-control"
name="template"
[(ngModel)]="model.template"/>
</div>
<div class="col">
<label for="user">User</label>
<input type="text"
id="user"
class="form-control"
name="user"
[(ngModel)]="model.user"/>
</div>
<div class="col">
<label for="count">Count</label>
<input type="text"
id="count"
class="form-control"
name="count"
[(ngModel)]="model.count"/>
</div>
</div>
<div class="row">
<div class="col">
<label for="firstName">First Name</label>
<input type="text"
id="firstName"
class="form-control"
name="firstName"
placeholder="Your firstName" [(ngModel)]="model.firstName"
#firstname="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && firstname.invalid }"
required maxlength="40"/>
<div *ngIf="f.submitted && firstname.invalid" class="invalid-input">
<div *ngIf="firstname.errors?.required">
First Name is required
</div>
<div *ngIf="firstname.errors?.maxlength">
First Name can have a maximum of 40 characters
</div>
</div>
</div>
<div class="col">
<label for="doctorNumber">Doctor Number</label>
<input type="text"
id="doctorNumber"
class="form-control"
name="doctorNumber"
placeholder="Your doctorNumber" [(ngModel)]="model.doctorNumber"
(click)="open(content)"/>
</div>
</div>
<div class="row">
<div class="col">
<label for="lastName">Last Name</label>
<input type="text"
id="lastName"
class="form-control"
name="lastName"
placeholder="Your lastName" [(ngModel)]="model.lastName"
#lastName="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && lastName.invalid }"
required maxlength="40"/>
<div *ngIf="f.submitted && lastName.invalid" class="invalid-input">
<div *ngIf="lastName.errors?.required">
Last Name is required
</div>
<div *ngIf="lastName.errors?.maxlength">
Last Name can have a maximum of 40 characters
</div>
</div>
</div>
<div class="col">
<label for="collectionCenter">Collection Center</label>
<input type="text"
id="collectionCenter"
class="form-control"
name="collectionCenter"
[(ngModel)]="model.collectionCenter" #collectionCenter="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && collectionCenter.invalid }"
required minlength="5" (keypress)="OnlyNumbersAllowed($event)"/>
<div *ngIf="f.submitted && collectionCenter.invalid" class="invalid-input">
<div *ngIf="collectionCenter.errors?.required">
Collection Center is required
</div>
<div *ngIf="collectionCenter.errors?.minlength">
Collection Center should be 5 digits in length
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<label for="middleName">Middle Name</label>
<input type="text"
id="middleName"
class="form-control"
name="middleName"
placeholder="Your MiddleName" [(ngModel)]="model.middleName"/>
</div>
<div class="col">
<label for="state">State</label>
<input type="text"
id="state"
class="form-control"
name="state"
[(ngModel)]="model.state"/>
</div>
</div>
<div class="row">
<div class="col">
<label for="sex">
Sex
</label>
<select id="sex" name="sex"
[(ngModel)]="model.sex" class="form-control">
<option *ngFor = "let sex of sexList" [ngValue]="sex.value">
{{sex.value}}
</option>
</select>
</div>
<div class="col">
<label for="billTo">Bill To</label>
<input type="text"
id="billTo"
class="form-control"
name="billTo"
[(ngModel)]="model.billTo" #billTo="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && billTo.invalid }"
minlength="3" maxlength="5"/>
<div *ngIf="f.submitted && billTo.invalid" class="invalid-input">
<div *ngIf="billTo.errors?.minlength">
Bill To should have a minimum of 3 characters
</div>
<div *ngIf="billTo.errors?.maxlength">
Bill To can have a maximum of 5 characters
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<label for="dateOfBirth">Date Of Birth</label>
<input type="text" bsDatepicker [bsConfig]="datePickerConfig"
id="dateOfBirth"
class="form-control"
name="dateOfBirth"
[(ngModel)]="model.dateOfBirth"
#dateOfBirth="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && dateOfBirth.invalid }"
required/>
<div *ngIf="f.submitted && dateOfBirth.invalid" class="invalid-input">
<div *ngIf="dateOfBirth.errors?.required">
Date Of Birth is required
</div>
</div>
</div>
<div class="col">
<label for="bioRefId">BioRef ID</label>
<input type="text"
id="bioRefId"
class="form-control"
name="bioRefId"
[(ngModel)]="model.bioRefId"/>
</div>
</div>
<div class="row">
<div class="col">
<label for="receivedDate">Received Date</label>
<input type="text" bsDatepicker [bsConfig]="datePickerConfig"
id="receivedDate"
class="form-control"
name="receivedDate"
[(ngModel)]="model.receivedDate"
#receivedDate="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && receivedDate.invalid }"
required/>
<div *ngIf="f.submitted && receivedDate.invalid" class="invalid-input">
<div *ngIf="receivedDate.errors?.required">
Received Date is required
</div>
</div>
</div>
<div class="col">
<label for="pid">PID</label>
<input type="text"
id="pid"
class="form-control"
name="pid"
[(ngModel)]="model.pid" #pid="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && pid.invalid }" maxlength="30"/>
<div *ngIf="f.submitted && pid.invalid" class="invalid-input">
<div *ngIf="pid.errors?.maxlength">
Patient Medical Record Number can have a maximum of 40 characters
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<label for="receivedTime">Received Time</label>
<input type="text"
id="receivedTime"
class="form-control"
name="receivedTime"
[(ngModel)]="model.receivedTime"/>
</div>
<div class="col">
<label for="antiCoagulant">Anti-Coagulant</label>
<input type="text"
id="antiCoagulant"
class="form-control"
name="antiCoagulant"
[(ngModel)]="model.antiCoagulant"/>
</div>
</div>
<div class="row">
<div class="col">
<label for="collectionDate">Collection Date</label>
<input type="text" bsDatepicker [bsConfig]="datePickerConfig"
id="collectionDate"
class="form-control"
name="collectionDate"
[(ngModel)]="model.collectionDate" #collectionDate="ngModel"
[ngClass]="{ 'is-invalid' : f.submitted && collectionDate.invalid }"
required/>
<div *ngIf="f.submitted && collectionDate.invalid" class="invalid-input">
<div *ngIf="collectionDate.errors?.required">
Collection Date is required
</div>
</div>
</div>
<div class="col">
<label for="specimenType">
Specimen Type
</label>
<select id="specimenType" name="specimenType"
[(ngModel)]="model.specimenType" class="form-control">
<option *ngFor = "let spt of specimenTypeList" [ngValue]="spt.value">
{{spt.value}}
</option>
</select>
</div>
</div>
<div class="row">
<div class="col">
<label for="collectionTime">Collection Time</label>
<input type="text"
id="collectionTime"
class="form-control"
name="collectionTime"
[(ngModel)]="model.collectionTime"/>
</div>
<div class="col">
<label for="gptCode">GP Test Code</label>
<input type="text"
id="gptCode"
class="form-control"
name="gptCode"
[(ngModel)]="model.gptCode"/>
</div>
</div>
<div style="text-align:center">
<button type="submit" class="btn">
<span> Save</span>
</button>
</div>
</form>
<div class="offset-3"></div>
</div>
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Find Doctor</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form #f="ngForm">
<div class="row">
<div class="col">
<label for="lastname">Last Name</label>
<div class="input-group">
<input id="lastname" class="form-control" >
</div>
</div>
<div class="col">
<label for="upin">UPIN</label>
<div class="input-group">
<input id="upin" class="form-control" >
</div>
</div>
<div class="col">
<label for="code">Code</label>
<div class="input-group">
<input id="code" class="form-control" >
</div>
</div>
<div class="col">
<button type="submit" id="find" class="btn">
<span>Find</span>
</button>
</div>
</div>
<div class="row">
<div class="col">
<label for="firstname">First Name</label>
<div class="input-group">
<input id="firstname" class="form-control" >
</div>
</div>
<div class="col">
<label for="state">State</label>
<div class="input-group">
<input id="state" class="form-control" >
</div>
</div>
<div class="col">
<label for="extcode">Ext Code</label>
<div class="input-group">
<input id="extcode" class="form-control" >
</div>
</div>
<div class="col">
<button type="submit" id="Cancel" class="btn">
<span>Cancel</span>
</button>
</div>
</div>
</form>
</div>
</ng-template>
Here is my ts code
import { Component,OnInit } from '#angular/core';
import {HttpClient} from "#angular/common/http";
import {ModalDismissReasons, NgbModal} from '#ng-bootstrap/ng-bootstrap';
import { BsDatepickerConfig } from 'ngx-bootstrap/datepicker';
import { Sex } from '../models/sex.model';
import { SpecimenType } from '../models/specimenType.model';
#Component({
selector: 'app-direct-client-trf',
templateUrl: './direct-client-trf.component.html',
styleUrls: ['./direct-client-trf.component.css']
})
export class DirectClientTRFComponent implements OnInit {
closeResult: string;
OnlyNumbersAllowed(event:any){
const charCode = (event.which)?event.which:event.keycode;
if(charCode > 31 && (charCode < 48 || charCode > 57)){
console.log('charCode is restricted'+charCode);
return false;
}
return true;
}
datePickerConfig: Partial<BsDatepickerConfig>;
specimenTypeList:SpecimenType[] = [
{id: 1,value: 'P'},
{id: 2,value: 'W'}
];
sexList:Sex[] = [
{id: 1,value: 'M:Male'},
{id: 2,value: 'F:Female'},
{id: 3,value: 'U:Unknown'}
];
model:DirectTrfViewModel = {
accession:'',
template:'',
user:'',
count:'',
firstName:'',
lastName:'',
middleName:'',
sex:'',
dateOfBirth:'',
receivedDate:'',
receivedTime:'',
collectionDate:'',
collectionTime:'',
doctorNumber:'',
collectionCenter:'',
state:'',
billTo:'',
bioRefId:'',
pid:'',
antiCoagulant:'',
specimenType:'',
gptCode:''
};
constructor(private http:HttpClient,private modalService: NgbModal){
this.datePickerConfig = Object.assign({},
{
containerClass : 'theme-dark-blue',
showWeekNumbers: false,
dateInputFormat: 'MM/DD/YYYY'
});
}
ngOnInit(){
}
saveData():void{
let url = 'http://localhost:8080/api/directtrfsubmit';
this.http.post(url,this.model).subscribe(
res => {
location.reload();
},
err => {
alert('Error in saving data');
}
);
}
open(content:any) {
this.modalService.open(content, {ariaLabelledBy: 'modal-basic-title'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}
export interface DirectTrfViewModel{
accession:string,
template:string,
user:string,
count:string,
firstName:string;
lastName:string;
middleName:string;
sex:string;
dateOfBirth:string;
receivedDate:string;
receivedTime:string;
collectionDate:string;
collectionTime:string;
doctorNumber:string;
collectionCenter:string;
state:string;
billTo:string;
bioRefId:string;
pid:string;
antiCoagulant:string;
specimenType:string;
gptCode:string;
}
With this the modal pop-up opens up and I need help in implementing the remaining functionality.

Related

Can not access ng-model values inside controller [angularJS]

When I try to access user.firstname value in controller, it gives the following error.
TypeError: Cannot read property 'firstname' of undefined
$scope.signUpCustomer = function(){
console.log("GGGGGGGGGGGGGGGGGGGGGGGGG ", $scope.user.firstname);
}
<form class="form-horizontal font-hp-simplified signUpUserForm row" role="form" ng-submit="signUpCustomer()" name ="signUpUserForm" ng-show="!userVendor">
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label for="firstname" class="col-md-12">First Name:</label>
<div class="col-md-12">
<input ng-model="user.firstname" type="text" class="form-control" name="firstname" required />
<span class="text-danger" ng-show="signUpUserForm.firstname.$invalid && signUpUserForm.firstname.$dirty ">First name is required</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="lastname" class="col-md-12">Last Name:</label>
<div class="col-md-12">
<input ng-model="user.lastname" type="text" class="form-control" name="lastname" required />
<span class="text-danger" ng-show="signUpUserForm.lastname.$invalid && signUpUserForm.lastname.$dirty ">Last name is required</span>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label for="email" class="col-md-12">Email:</label>
<div class="col-md-12">
<input ng-model="user.email" type="email" class="form-control" name="email" required />
<span class="text-danger" ng-show="signUpUserForm.email.$error.required && signUpUserForm.email.$dirty ">Email is required</span>
<span class="text-danger" ng-show="signUpUserForm.email.$error.email && signUpUserForm.email.$dirty ">Please enter valid email</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="password" class="col-md-12">Password:</label>
<div class="col-md-12">
<input ng-model="user.password" type="password" class="form-control" name="password" required />
<span class="text-danger" ng-show="signUpUserForm.password.$invalid && signUpUserForm.password.$dirty">Password is required</span>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label for="phone" class="col-md-12">Phone:</label>
<div class="col-md-12">
<input ng-model="user.phone" type="text" class="form-control" name="phone" required />
<span class="text-danger" ng-show="signUpUserForm.phone.$invalid && signUpUserForm.phone.$dirty">Phone is required</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="country" class="col-md-12">Country:</label>
<div class="col-md-12">
<select name="country" ng-model="user.country" type="text" class="form-control form-bg-white" required>
<!-- <option value="" disabled selected>Select Your Country</option> -->
<option value="" disabled selected></option>
<option ng-repeat="country in countries" value="{{country}}">{{country}}</option>
</select>
<span class="text-danger" ng-show="signUpUserForm.country.$invalid && signUpUserForm.country.$dirty">Country is required</span>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="col-md-12">
<!-- Button -->
<div class="form-group">
<div class="col-md-12">
<div class="icon-user-signup">
<div class="input-group-addon">
<i class="fa fa-user"></i>
</div>
<button id="btn-signup" class="btn btn-primary col-md-12">SIGN UP</button>
</div>
</div>
<!-- <div class="mrg-top-10 col-md-12 text-right">
<h4><a ng-click="go('/seller#/signup')" class="ven-link">
Become a vendor today
</a></h4>
</div>-->
</div>
</div>
</div>
<!-- <div class="col-md-12 control">
<div class="signup-border" >
Already have an account ?
<a ui-sref="loginUser" >
Sign In Here
</a>
</div>
</div> -->
</form>
You need to initialize the $scope.customer first in controller
$scope.user = {};

tabindex is not working with required attribute

<div class="row">
<div class="col-md-6">
<div class="form-body">
<div class="form-group">
<label>First Name</label>
<div class="input-group">
<input type="text" tabIndex="1" name="first_name" class="form-control">
</div>
</div>
<div class="form-group">
<label>Email Address</label>
<div class="input-group">
<input type="email" tabIndex="3" name="username" class="form-control" ng-model="username" required user-exist /><br/> <span style="color: red" ng-show="partnerForm.username.$touched && partnerForm.username.$invalid">
<span ng-show="partnerForm.username.$error.required">Email is required.</span>
<span ng-show="partnerForm.username.$error.email">Enter Correct Format.</span>
<span ng-show="partnerForm.username.$error.userExist">User already exists.</span>
</span>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-body">
<div class="form-group">
<label>Last Name</label>
<div class="input-group">
<input type="text" tabIndex="2" name="last_name" class="form-control">
</div>
</div>
</div>
</div>
</div>
the tabindex 3 is not working.i have checked by removing the required attr then it is working .the attributes required and tabindex is conflicting with each other.please help me to solve this.or provide a directive (working) for tabindex.

ng-model-option rollback changes on whole form

have a quick question.
I have a form with whole bunch of fields that could be updated from UI.
I found a directive called "ng-model-option" that seems to be handling those kind of issues.
My question is: is it possible to rollback changes on whole form without specifying ng-model-options="{ updateOn: 'submit'}"
on every input fieldin my form?
Or, this directive look on every field and only submit those fields that were modified?
Thank you for your help and explanation in advance!
You could have all of your fields bound to a single object, i.e.
$scope.model = {
foo: '',
bar: '',
etc: ''
};
That way you could store a copy of the model, and reset the bound model at any point you wish.
For example to undo all of the changes after a failed service call:
$scope.submit = function() {
yourService.update(model).then(function(result) {
// handle the success.
}, function(err) {
$scope.model = $scope.originalModel;
});
}
Or maybe reloading the page is an option for you?
$window.location.reload();
i found a solution by using and mapping everything to ng-model-option directive
<form name="EditUserForm" class="col-md-12 form-horizontal top-buffer">
<div class="form-group">
<div class="col-sm-4 text-right">
<label>User Id:</label>
</div>
<div class="col-sm-8">
<input type="text" class="form-control info-textbox" ng-model="user.UserID" ng-disabled="true" />
</div>
</div>
<div class="form-group">
<div class="col-sm-4 text-right">
<label>Department Name:</label>
</div>
<div class="col-sm-8">
<!--<input type="text" class="form-control info-textbox" ng-model="user.Department.DepartmentName" ng-readonly="isReadOnlyMode" />-->
<select class="form-control info-textbox" ng-options="department.DepartmentName for department in departments"
ng-model="selectedDepartment"
ng-readonly="isReadOnlyMode"
ng-model-options="{updateOn: 'submit'}"></select>
</div>
</div>
<div class="form-group">
<div class="col-sm-4 text-right">
<label>First Name:</label>
</div>
<div class="col-sm-8">
<input type="text" class="form-control info-textbox" ng-model="user.FirstName" ng-readonly="isReadOnlyMode" ng-model-options="{updateOn: 'submit'}" />
</div>
</div>
<div class="form-group">
<div class="col-sm-4 text-right">
<label>Last Name:</label>
</div>
<div class="col-sm-8">
<input type="text" class="form-control info-textbox" ng-model="user.LastName" ng-readonly="isReadOnlyMode" ng-model-options="{updateOn: 'submit'}" />
</div>
</div>
<div class="form-group">
<div class="col-sm-4 text-right">
<label>Email:</label>
</div>
<div class="col-sm-8">
<input type="text" class="form-control info-textbox" ng-model="user.Email" ng-readonly="isReadOnlyMode" ng-model-options="{updateOn: 'submit'}" />
</div>
</div>
<div class="form-group">
<div class="col-sm-4 text-right">
<label>Phone:</label>
</div>
<div class="col-sm-8">
<input type="text" class="form-control info-textbox" ng-model="user.Phone" ng-readonly="isReadOnlyMode" ng-model-options="{updateOn: 'submit'}" />
</div>
</div>
<div class="form-group">
<div class="col-sm-4 text-right">
<label>Login:</label>
</div>
<div class="col-sm-8">
<input type="text" class="form-control info-textbox" ng-model="user.LoginName" ng-readonly="isReadOnlyMode" ng-model-options="{updateOn: 'submit'}" />
</div>
</div>
<div class="form-group">
<div class="col-sm-4 text-right">
<label>Password:</label>
</div>
<div class="col-sm-8">
<input type="password" class="form-control info-textbox" ng-model="user.Password" ng-readonly="isReadOnlyMode" ng-model-options="{updateOn: 'submit'}" />
</div>
</div>
<!--Buttons-->
<div class="form-group">
<div class="col-sm-4 text-right">
<button type="button" class="btn btn-primary info-button" name="btnEdit" ng-click="flipBetweenEditMode(isReadOnlyMode)" ng-show="isReadOnlyMode">
<span>Edit</span>
</button>
<button type="button" class="btn btn-primary info-button" name="btnEdit" ng-click="flipBetweenEditMode(isReadOnlyMode)" ng-show="!isReadOnlyMode">
<span>Cancel</span>
</button>
</div>
<div class="col-sm-4 text-left">
<button type="submit" class="btn btn-primary info-button" name="btnSave" ng-click="saveChangesToUser(user, isReadOnlyMode)" ng-show="!isReadOnlyMode">
<span>Save</span>
</button>
</div>
<div class="col-sm-4 text-left">
<div back-button></div>
</div>
</div>
</form>
and then controller
$scope.flipBetweenEditMode = function (isReadOnlyMode) {
if (!isReadOnlyMode) {
$scope.EditUserForm.$rollbackViewValue();
}
console.log(isReadOnlyMode);
$scope.isReadOnlyMode = !isReadOnlyMode;
};
on cancel this will roll back all the changes and restore model at its first stage.

angular-wizard steps form validation for current step

I have a form with angular-wizard steps like below
While moving from one step to another step, we have to validate the current
step fields. But it validating all steps fields. How we can validate the present step fields instead of all fields?
<form name="User" novalidate>
<wizard on-finish="saveUser()">
<wz-step title="Starting" canexit="exitValidation">
<h1>This is the first step</h1>
<input type="text" required name="Field1"/>
<input type="submit" wz-next="" value="Continue" />
</wz-step>
<wz-step title="Continuing" canenter="enterValidation" canexit="exitValidation">
<h1>This is the second step</h1>
<input type="text" required name="Field2"/>
<input type="submit" wz-next="" value="Continue" />
</wz-step>
<wz-step title="Continuing" canenter="enterValidation" canexit="exitValidation">
<h1>This is the third step</h1>
<input type="text" required name="Field3"/>
<input type="submit" wz-next="" value="Continue" />
</wz-step>
</wizard>
</form>
You can use nested formGroups to validate the current step fields instead of all fields. I am adding the sample code using angular-archwizard with step wise validation.
Component.html :
<form [formGroup]="userForm" (ngSubmit)="userFormSubmit()">
<aw-wizard [navBarLayout]="'large-empty-symbols'">
<!-- Step 1 -->
<aw-wizard-step formGroupName="personalDetailsGroup" stepTitle="Personal Info" [navigationSymbol]="{ symbol: '1', fontFamily: 'FontAwesome' }">
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="first_name">First Name* :</label>
<input type="text" class="form-control" formControlName="first_name">
<div *ngIf="form.personalDetailsGroup['controls'].first_name.invalid && (form.personalDetailsGroup['controls'].first_name.dirty || form.personalDetailsGroup['controls'].first_name.touched)">
<span *ngIf="form.personalDetailsGroup['controls'].first_name.errors.required">Please enter first name</span>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="last_name">Last Name* :</label>
<input type="text" class="form-control" formControlName="last_name">
<div *ngIf="form.personalDetailsGroup['controls'].last_name.invalid && (form.personalDetailsGroup['controls'].last_name.dirty || form.personalDetailsGroup['controls'].last_name.touched)">
<span *ngIf="form.personalDetailsGroup['controls'].last_name.errors.required">Please enter last name</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="email">Email Address* :</label>
<input type="email" class="form-control" formControlName="email" required>
<div *ngIf="form.personalDetailsGroup['controls'].email.invalid && (form.personalDetailsGroup['controls'].email.dirty || form.personalDetailsGroup['controls'].email.touched)">
<span *ngIf="form.personalDetailsGroup['controls'].email.errors.required">Please enter email address</span>
<span *ngIf="form.personalDetailsGroup['controls'].email.errors.email">Please enter valid email address</span>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="mobile_number">Mobile Number* :</label>
<input type="tel" class="form-control" formControlName="mobile_number" required>
<div *ngIf="form.personalDetailsGroup['controls'].mobile_number.invalid && (form.personalDetailsGroup['controls'].mobile_number.dirty || form.personalDetailsGroup['controls'].mobile_number.touched)">
<span *ngIf="form.personalDetailsGroup['controls'].mobile_number.errors.required">Please enter mobile number</span>
</div>
</div>
</div>
</div>
<button class="btn btn-primary" type="button" [disabled]="form.personalDetailsGroup.invalid" awNextStep>Next</button>
</aw-wizard-step>
<!-- Step 2 -->
<aw-wizard-step formGroupName="contactDetailsGroup" stepTitle="Contact Info">
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="phone_number">Phone Number :</label>
<input type="tel" class="form-control" formControlName="phone_number">
<div *ngIf="form.contactDetailsGroup['controls'].phone_number.invalid && (form.contactDetailsGroup['controls'].phone_number.dirty || form.contactDetailsGroup['controls'].phone_number.touched)">
<span *ngIf="form.contactDetailsGroup['controls'].phone_number.errors.pattern">Please enter valid phone number</span>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="city">City* :</label>
<input type="text" class="form-control" formControlName="city" required>
<div *ngIf="form.contactDetailsGroup['controls'].city.invalid && (form.contactDetailsGroup['controls'].city.dirty || form.contactDetailsGroup['controls'].city.touched)">
<span *ngIf="form.contactDetailsGroup['controls'].city.errors.required">Please enter city name</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="state">State* :</label>
<input type="text" class="form-control" formControlName="state" required>
<div *ngIf="form.contactDetailsGroup['controls'].state.invalid && (form.contactDetailsGroup['controls'].state.dirty || form.contactDetailsGroup['controls'].state.touched)">
<span *ngIf="form.contactDetailsGroup['controls'].state.errors.required">Please enter state name</span>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="country">Country* :</label>
<input type="text" class="form-control" formControlName="country" required>
<div *ngIf="form.contactDetailsGroup['controls'].country.invalid && (form.contactDetailsGroup['controls'].country.dirty || form.contactDetailsGroup['controls'].country.touched)">
<span *ngIf="form.contactDetailsGroup['controls'].country.errors.pattern">Please enter country name</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="pincode">Pincode* :</label>
<input type="tel" class="form-control" formControlName="pincode" required>
<div *ngIf="form.contactDetailsGroup['controls'].pincode.invalid && (form.contactDetailsGroup['controls'].pincode.dirty || form.contactDetailsGroup['controls'].pincode.touched)">
<span *ngIf="form.contactDetailsGroup['controls'].pincode.errors.required">Please enter pincode</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="address1">Address1* :</label>
<textarea class="form-control" formControlName="address1" required></textarea>
<div *ngIf="form.contactDetailsGroup['controls'].address1.invalid && (form.contactDetailsGroup['controls'].address1.dirty || form.contactDetailsGroup['controls'].address1.touched)">
<span *ngIf="form.contactDetailsGroup['controls'].address1.errors.required">Please enter address</span>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label for="address2">Address2* :</label>
<textarea class="form-control" formControlName="address2" required></textarea>
<div *ngIf="form.contactDetailsGroup['controls'].address2.invalid && (form.contactDetailsGroup['controls'].address2.dirty || form.contactDetailsGroup['controls'].address2.touched)">
<span *ngIf="form.contactDetailsGroup['controls'].address2.errors.required">Please enter address</span>
</div>
</div>
</div>
</div>
<button class="btn btn-secondary" type="button" awPreviousStep>Previous</button>
<button class="btn btn-primary" type="button" [disabled]="form.contactDetailsGroup.invalid" awNextStep>Next</button>
</aw-wizard-step>
<aw-wizard-step stepTitle="Title of step 3">
Content of Step 3
<button class="btn btn-secondary" type="button" awPreviousStep>Previous</button>
<button class="btn btn-primary" type="submit" [disabled]="form.personalDetailsGroup.invalid || form.contactDetailsGroup.invalid">Submit</button>
</aw-wizard-step>
</aw-wizard>
</form>
Component.ts :
Add these below lines of code to define the nested formGroups.
ngOnInit(): void {
this.userForm = this.formBuilder.group({
personalDetailsGroup: this.formBuilder.group({
first_name: ['', [Validators.required]],
last_name: ['', [Validators.required]],
email: ['', [Validators.required, Validators.email]],
mobile_number: ['', [Validators.required, Validators.pattern(mobileRegx)]],
}),
contactDetailsGroup: this.formBuilder.group({
city: ['', [Validators.required]],
state: ['', [Validators.required]],
country: ['', [Validators.required]],
pincode: ['', [Validators.required]],
address1: ['', [Validators.required]],
address2: ['', [Validators.required]],
})
})
}
get form() { return this.userForm.controls; }
userFormSubmit(){
const personalDetails = this.addVendorForm.get('personalDetailsGroup').value;
const contactDetails = this.addVendorForm.get('contactDetailsGroup').value;
const totalFormData = Object.assign({}, personalDetails, contactDetails);
}
hope this answer helps you.

How to reset data on modal window Open?

I have interesting situation Everytime when i open modal window i am reseting the value for below field, but if you select value 2 , 3 times and close modal with 'x' some time value retained in the select field. I am not sure why its happening any idea ?
main.html
<form name="addChallengeForm" id="addChallengeForm" novalidate ng-controller="challengesCtrl" class="border-box-sizing">
<div class="modalForm" disable-control-point="CHALLENGES_EDIT">
<div class="row" ng-show="editMode">
<div class="form-group col-md-12 fieldHeight">
<label for="originatingGroup" class="required col-md-4">Challenge Id:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="challangeId"
ng-model="challengesDTO.riskAssessmentChallengeKey" name="challangeId" readonly="readonly">
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12 fieldHeight">
<label for="originatingGroup" class="required col-md-4">Originating group:</label>
<div class="col-md-8">
<select
kendo-drop-down-list
data-text-field="'text'"
data-value-field="'id'" name="originatingGroup"
k-option-label="'Select'" ng-model-options="{updateOn: 'blur'}"
ng-model="challengesDTO.originatingGrpLkupCode"
k-data-source="challengeGroupOptions"
id="originatingGroup" required>
</select>
<p class="text-danger" ng-show="addChallengeForm.originatingGroup.$touched && addChallengeForm.originatingGroup.$error.required">Originating group is required</p>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12 fieldHeight">
<label for="challangeCreatedBy" class="col-md-4">Challenge created by:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="challangeCreatedBy"
ng-model="challengesDTO.initByWorker" name="challangeCreatedBy">
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label for="challangeDes" class="required col-md-4">Description of challenge:</label>
<div class="col-md-8">
<textarea rows="4" class="form-control"
name="challangeDes" id="challangeDes"
ng-model="challengesDTO.challengeDescription" required
placeholder="Description of challenge" ng-model-options="{updateOn: 'blur'}">
</textarea>
<p class="text-danger" ng-show="addChallengeForm.challangeDes.$touched && addChallengeForm.challangeDes.$error.required">Description of challenge is required</p>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label for="themesList" class="required col-md-4">Themes:</label>
<div class="col-md-8">
<select class="multiselect" kendo-multi-select="themes"
k-options="challengThemesOptions" data-text-field="'text'"
data-value-field="'id'" name="themesList"
ng-model="challengesDTO.themesKyList" required
k-data-source="challengThemesDataSource"
id="themesList"></select>
<p class="text-danger" ng-show="addChallengeForm.themesList.$touched && addChallengeForm.themesList.$error.required">Theme(s) is required</p>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12 fieldHeight">
<label for="ownerOrPreparer" class="col-md-4">RCSA Preparer
Responding to Challenge:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="ownerOrPreparer"
ng-model="challengesDTO.challengeResponseWrk"
name="ownerOrPreparer" readonly="readonly" >
</div>
</div>
</div>
<div class="row" ng-show="editMode">
<div class="form-group col-md-12">
<label for="responseComment" class="col-md-4">RCSA Preparer Response:</label>
<div class="col-md-8">
<textarea rows="4" class="form-control"
name="responseComment" id="responseComment"
ng-model="challengesDTO.challengeResponseComment"
placeholder="RCSA Owner/Preparer Response">
</textarea>
</div>
</div>
</div>
<div class="row" ng-show="editMode">
<div class="form-group col-md-12 fieldHeight">
<label for="outcomeResolution" class="col-md-4">Outcome/Resolution:</label>
<div class="col-md-8">
<select
kendo-drop-down-list
data-text-field="'text'"
data-value-field="'id'" name="outcomeResolution"
k-option-label="'Select'" ng-change="mandatoryEscalation()"
ng-model="challengesDTO.challengeDesLkupCode"
k-data-source="challengOutComeOptions"
id="outcomeResolution" >
</select>
</div>
</div>
</div>
<div class="row" ng-if="editMode && showEscalation" disable-control-point="CHALLENGES_EDIT">
<div class="form-group col-md-12 fieldHeight">
<label for="requireEscalation" class="required col-md-4">Did the challenge
require escalation to be resolved?:</label>
<div class="col-md-8">
<select kendo-drop-down-list k-data-text-field="'text'"
k-option-label="'Select'" k-data-value-field="'id'"
k-options="escalationDataSource" name="requireEscalation"
ng-model="challengesDTO.esclRqrFlag" required
id="requireEscalation" ng-model-options="{updateOn: 'blur'}"></select>
<p class="text-danger" ng-show="addChallengeForm.requireEscalation.$touched && addChallengeForm.requireEscalation.$error.required">Challenge escalation is required</p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary pull-right" ng-disabled="addChallengeForm.$invalid" ng-click="submit()" require-control-point="CHALLENGES_ADD,CHALLENGES_EDIT">Save</button>
</div>
</form>
main.js
$scope.challengesDTO = {};
$scope.riskAssessmentDTO={
firstName: '',
lastName: '',
emailId: '' ,
nbkId: ''
};
$scope.$on('kendoRendered', function() {
rcsaAssessmentFactory.getThemeOptions().then(function(res){
$scope.challengThemesOptions.dataSource = new kendo.data.ObservableArray({data: res.data});
});
});
$scope.$on('addChallenge', function (s,id,opCheckList,checklistSessionKey){
$scope.addChallengeForm.originatingGroup.$setUntouched();
$scope.addChallengeForm.challangeDes.$setUntouched();
$scope.addChallengeForm.themesList.$setUntouched();
$scope.editMode = false;
$scope.clearFields = clearForm();
if($rootScope.user && $rootScope.user.customUserDetails){
$scope.challengesDTO.initByWorker= $rootScope.user.customUserDetails.workFullName;
}
rcsaAssessmentFactory.getAssessmentPreparerInfo(id).then(function(response){
$scope.riskAssessmentPreparer= response.data;
$scope.challengesDTO.challengeResponseWrkKey = $scope.riskAssessmentPreparer.rcsaPreparerWorkerKey;
$scope.challengesDTO.challengeResponseWrk = $scope.riskAssessmentPreparer.rcsaPreparerWorker;
});
$scope.riskAssessmentDTO.riskAssessmentKey = id;
$scope.challengesDTO.addChlngToChklst=opCheckList;
$scope.challengesDTO.riskAssessmentChecklistSessionKey=checklistSessionKey;
$scope.viewChallengeWin.open().center();
$scope.submit = function(){
rcsaAssessmentFactory.saveChallenge($scope.challengesDTO,id).then(function(){
$scope.viewChallengeWin.close();
$scope.$emit('refreshChallengeGrid');
$scope.addChallengeForm.$setPristine();
$scope.clearFields = clearForm();
});
};
});
var clearForm = function(){
$timeout(function () {
$scope.challengesDTO = {
themesKyList: null
};
});
$scope.challengeGroupOptions = kendoCustomDataSource.getDropDownDataSource('RA_ASES_CHLNG_GRP');
$scope.challengThemesDataSource = kendoCustomDataSource.getDropDownDataSource('RA_CHLNG_THEME');
$scope.challengOutComeOptions = kendoCustomDataSource.getDropDownDataSource('RA_CHLNG_OUTCOME');
$scope.riskAssessmentDTO={
firstName: '',
lastName: '',
emailId: '' ,
nbkId: ''
};
};

Resources