How to add multiple fields dynamically so that all these values are stored in an array in a reactive form using Angular 6? - ngfor

I want to add multiple fields on the click of a button 'Add Answer' and all these values should be stored in an array.
So, each time on clicking this button 5 input fields should be generated and these values should be stored in an array as information about a single item.
I tried using formBuilder but it wasn't working then also tried a form group approach but couldn't implement it. I think it can be done using form group approach.
Content.component.ts:
export class ContentComponent implements OnInit {
questionForm: FormGroup;
aa = false;
ccc = true;
flag = 0;
constructor() { }
ngOnInit() {
this.questionForm = new FormGroup({
'course': new FormControl(null, Validators.required),
'topic': new FormControl(null),
'videos': new FormControl(null),
'quest': new FormControl(null, Validators.required),
'typee': new FormControl(null, Validators.required),
// name: new FormControl(),
// sName: new FormControl(),
'answerOptions': new FormArray([]),
'answerOptions2': new FormArray([]),
'answerOptions3': new FormArray([]),
'answerOptions4': new FormArray([]),
'answerOptions5': new FormArray([]),
'answerOptionsC': new FormArray([]),
'answerOptionsC2': new FormArray([]),
'answerOptionsC3': new FormArray([]),
'answerOptionsC4': new FormArray([]),
'answerOptionsC5': new FormArray([]),
'answerOptionsI': new FormArray([]),
});
this.questionForm.setValue({
'course': 'c1',
'topic': 't2',
'videos': 'v3',
'quest': '',
'typee': '',
'answerOptions': [],
'answerOptions2': [],
'answerOptions3': [],
'answerOptions4': [],
'answerOptions5': [],
'answerOptionsC': [],
'answerOptionsC2': [],
'answerOptionsC3': [],
'answerOptionsC4': [],
'answerOptionsC5': [],
'answerOptionsI': []
});}
onAddAns() {
if (this.flag === 1) {
const controlI = new FormControl(null, Validators.required);
(<FormArray>this.questionForm.get('answerOptionsI')).push(controlI);
} else if (this.flag === 2) {
// (<FormArray>this.questionForm.get('answerOptions')).push(
// new FormGroup({
// 'name': new FormControl(null),
// 'sName': new FormControl(null)
// })
// );
} else if (this.flag === 3) {
const controlC = new FormControl(null, Validators.required);
(<FormArray>this.questionForm.get('answerOptionsC')).push(controlC);
(<FormArray>this.questionForm.get('answerOptionsC2')).push(controlC);
(<FormArray>this.questionForm.get('answerOptionsC3')).push(controlC);
(<FormArray>this.questionForm.get('answerOptionsC4')).push(controlC);
(<FormArray>this.questionForm.get('answerOptionsC5')).push(controlC);
}}
dropChanged(val: any) {
this.questionForm.get('typee').disable();
console.log(val);
this.ccc = false;
if (val === 'text') {
this.flag = 1;
} else if (val === 'radio') {
this.flag = 2;
} else if (val === 'check') {
this.flag = 3;
} }
onSubmit() {
console.log(this.questionForm);}}
Content.component.html:
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
<form [formGroup]="questionForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="type1">Select Course:</label>
<select
id="type1"
formControlName="course"
class="form-control">
<option value="c1">Data Handling</option>
<option value="c2">Data Processing</option>
<option value="c3">Data Manipulation</option>
</select>
</div>
<div class="form-group">
<label for="type2">Select Topic:</label>
<select
id="type2"
formControlName="topic"
class="form-control">
<option value="t1">Topic 1</option>
<option value="t2">Topic 2</option>
<option value="t3">Topic 3</option>
</select>
</div>
<div class="form-group">
<label for="type2">Select Video:</label>
<select
id="type2"
formControlName="videos"
class="form-control">
<option value="v1">Video 1</option>
<option value="v2">Video 2</option>
<option value="v3">Video 3</option>
</select>
</div>
<div class="form-group">
<label for= "questio">Question:
</label>
<input
type="text"
id= "questio"
formControlName="quest"
class="form-control">
<span
*ngIf="!questionForm.get('quest').valid && questionForm.get('quest').touched"
class="help-block">
<span *ngIf="questionForm.get('quest').errors['required']">This field is required!</span>
</span>
</div>
<div class="form-group">
<label for="type">Type of question</label>
<select
[disabled]="aa"
id="type"
formControlName="typee"
(change)="dropChanged($event.target.value)"
class="form-control">
<option value="text">Input type</option>
<option value="radio">Radio Button</option>
<option value="check">Checkbox</option>
</select>
</div>
<h4>Answers</h4>
<button
class="btn btn-default"
type="button"
(click)="onAddAns()">Add Answers</button>
<div class="form-group" id="ip1">
<!--*ngFor="let answerOptionControl of questionForm.get('answerOptions').controls; let i = index"-->
<!--formGroupName="i">-->
<!--Solution:<input type="text" class="form-control" [formControlName]='name'>-->
<!--Hint:<input type="text" class="form-control" [formControlName]="sName">-->
<hr>
</div>
<div class="form-group" id="ip2"
*ngFor="let answerOptionControlC of questionForm.get('answerOptionsC').controls; let a = index
let answerOptionControlC2 of questionForm.get('answerOptionsC2').controls; let b = index
let answerOptionControlC3 of questionForm.get('answerOptionsC3').controls; let c = index
let answerOptionControlC4 of questionForm.get('answerOptionsC4').controls; let d = index
let answerOptionControlC5 of questionForm.get('answerOptionsC4').controls; let e = index">
Solution:<input type="text" class="form-control" [formControlName]="a">
Hint:<input type="text" class="form-control" [formControlName]="b">
Status:<input type="text" class="form-control" [formControlName]="c">
link:<input type="text" class="form-control" [formControlName]="d">
Message:<input type="text" class="form-control" [formControlName]="e">
<hr>
</div>
<div class="form-group" id="ip3"
*ngFor="let answerOptionControlI of questionForm.get('answerOptionsI').controls; let f = index">
Keyword:<input type="text" class="form-control" formControlName="f">
<hr>
</div>
<hr>
<button class="btn btn-primary" type="submit" [disabled]="ccc" (click)="onSubmit()">Submit</button>
</form>
</div>
So, right now only for the option checkbox the application is working but some error is there of controls.
I know this approach is wrong that is why I want to do it using form-group.
This is the result of this code and the error along with it.

Your issue is that you forgot the [] around formControlName in the following code (I added it below):
<div class="form-group" id="ip3"
*ngFor="let answerOptionControlI of questionForm.get('answerOptionsI').controls; let f = index">
Keyword:<input type="text" class="form-control" [formControlName]="f">
<hr>
</div>
Therefore, instead of looking for the control at the index f, it is looking for a control named 'f', which does not exist.

Related

How to Pass JSON data inside HTML attributes

I have created a form using HTML and trying to pass the value of a JSON object in the HTML attribute. I have used fetch to get the data from the api and used it to create options in my page that is made using vueJS. The problem is, the value that gets logged in the database is {{item}} instead of the value in the item.
How to resolve this issue?
AddLog.vue code:
<template>
<h1 style="margin-top: 107px; text-align: center;color: ;">Log the values into the tracker</h1>
<form #submit.prevent="submit" style="margin-right: 522px;margin-top: 29px; margin-left: 519px" method="POST">
<div class="form-group">
<label for="exampleInputEmail1" required style="color: ;">Note</label>
<input type="name" class="form-control" v-model="data.note" id="exampleInputEmail1" aria-describedby="emailHelp" name="Note" placeholder="Note" style="border-radius: 20px;">
</div>
<div class="form-group" v-if="this.trackertype==='Numerical'" >
<label for="exampleInputPassword1" required style="color: ;">Enter the Value</label>
<input type="value" class="form-control" v-model="data.value" id="exampleInputPassword1" name="value" placeholder="Value" style="border-radius: 20px;" required>
</div>
<div class="multiple-choice" v-else>
<label for="value" style="color: ;">Check the value</label>
<div class="form-check">
<div v-for="item,index in this.trackersettings" :key="index">
<input type="radio" name="value" v-model="data.value" value="{{item}}" required>
<label>{{item}}</label>
</div>
</div>
</div>
<button type="submit" class="btn btn-outline-dark" style="border-radius: 15px;">submit</button>
</form>
</template>
<script>
import { reactive } from 'vue';
import axios from 'axios';
export default {
Name: 'AddLog',
data(){
return{
uid : this.$route.params.uid,
tid : this.$route.params.tid,
items : [],
trackertype: '',
trackersettings: []
}
},
mounted() {
localStorage.setItem('uid',this.uid)
localStorage.setItem('tid',this.tid)
axios.get('http://localhost:5000/addLog/'+this.uid+'/'+this.tid)
.then((resp ) => {
this.items = resp.data
this.trackertype = this.items[0]['data']['trackertype']
this.trackersettings =this.items[1]['tracker_settings']
console.log(this.trackertype,this.trackersettings)
})
.catch((err) => {
console.log(err.resp)
})
},
setup() {
const data = reactive({
note: '',
value: ''
})
const submit = async () => {
await fetch("http://localhost:5000/addLog/"+localStorage['uid']+'/'+localStorage['tid'],{
method: 'POST',
headers: {'Content-Type' : 'application/json','Access-Control-Allow-Origin': '*'},
body: JSON.stringify(data)
}).then(resp => resp.json())
.then(data => {console.log(data);})
.catch(error => { console.log(error)
})
}
return {
data,
submit,
}
}
}
</script>
<style>
</style>
API code:
#app.route('/addLog/<int:uid>/<int:tid>', methods=['GET', 'POST'])
def log(uid,tid):
cell = tracker.query.filter_by(u_id=uid,tracker_id=tid).first()
l = cell.tracker_settings.split(',')
d = {
'userid' : cell.u_id,
'trackerid' : cell.tracker_id,
'trackername' : cell.tracker_name,
'trackerdesc' : cell.tracker_description,
'trackertype' : cell.tracker_type,
'tracker_settings' : cell.tracker_settings,
'datecreated' : cell.date_created
}
if request.method=='POST':
data = request.json
val = data['value']
note = data['note']
cell = logtable(user_id=uid,t_id=tid,Note=note,value=val)
db.session.add(cell)
db.session.commit()
return jsonify({'message':'success'})
else:
return jsonify({'data':d},{'tracker_settings' : l })
I want the values in the options to be logged in the db.
Instead of the "{{item}}" in the value , I need the string "Gloomy". Can Anybody help me on doing this?
Here is the correct way to assign the value :
Try :value="item" instead of value="{{item}}"
Demo :
var app = new Vue({
el: '#app',
data: {
selected: '',
item1: 'Male',
item2: 'Female'
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Binding Radio</h2>
<input type="radio" id="one" :value="item1" v-model="selected">
<label for="one">Male</label>
<br>
<input type="radio" id="two" :value="item2" v-model="selected">
<label for="two">Female</label>
<br>
<span>Picked: {{ selected }}</span>
</div>

How to apply validations in formarray in angular 8

I am using formArray to display dynamic data in table and its working as expected, but I am unable to apply the required field validation. I want to validate this table so that no null entry can be save.
In template:
<form *ngIf="userForm" [formGroup]="userForm">
<table>
<tbody formArrayName="order">
<ng-container *ngFor="let orderLine of properties; let i=index" [formGroupName]="i">
<tr>
<td class="fieldspacing">
<input class="form-control" formControlName="propertyName"
[readOnly]="orderLine.IsReadOnly" type="text">
<ng-container *ngIf="order.get('propertyName').hasError('required')">
<span class="errorMsg">Property name cannot be null</span>
</ng-container>
</td>
<td class="fieldspacing">
<select class="form-control selectwidth" formControlName="propertyType" type="text"
(change)="valueChange(i)">
<option *ngFor="let type of propertyTypes" value="{{type.Id}}">{{type.TypeName}}
</option>
</select>
</td>
<div *ngIf="orderLine.PropertyTypeId == 4">
<td class="fieldspacing">
<input type="checkbox" formControlName="readOnly" (change)="handleSelected($event,i)"><label> Has
Parent</label>
</td>
<td class="fieldspacing" *ngIf="orderLine.IsReadOnly || contentEditable">
<select class="form-control selectwidth" formControlName="parentProperty" type="text">
<option *ngFor="let parent of properties" [value]="parent.ParentHierarchyPropertyId">
{{parent.ParentHierarchyPropertyName}}
</option>
</select>
</td>
</div>
</tbody>
</table>
<button (click)="saveUserAdditionalProperties()" type="submit"
class="mt-4 btn btn-primary">Save</button>
</form>
In controller
public properties: any = [
{
"Id": "0012",
"PropertyType": null,
"PropertyTypeId": 4,
"IsReadOnly": true,
"DisplayOrder": 0,
"PropertyName": "Gender",
"ParentHierarchyPropertyId": null,
"ParentHierarchyPropertyName": null,
},
{
"Id": "1234",
"PropertyType": null,
"PropertyTypeId": 4,
"IsReadOnly": false,
"DisplayOrder": 1,
"PropertyName": "save",
"ParentHierarchyPropertyId": null,
"ParentHierarchyPropertyName": null,
},
];
loadUserProperties() {
this.userForm = this.getForm();
}
getForm(): FormGroup {
return new FormGroup({
order: new FormArray(this.properties.map(this.getFormGroupForUserProperty)),
});
}
getFormGroupForUserProperty(userProperty: any) {
let formGroup: FormGroup = new FormGroup({
propertyName: new FormControl(userProperty.PropertyName,Validators.required),
propertyType: new FormControl(userProperty.PropertyTypeId),
parentProperty: new FormControl(userProperty.ParentHierarchyPropertyId),
readOnly: new FormControl(userProperty.IsReadOnly)
});
You need to use it for formArray
formArray: FormArray;
constructor(
private _formBuilder: FormBuilder
) {}
this.formArray = this._formBuilder.array([]);
new Array(LENGTH_NUMBER).fill(1).forEach(() => {
this.formArray.push(this._formBuilder.group({
FORMCONTROLNAME_ONE: ["", Validators.required],
FORMCONTROLNAME_TWO: ["", Validators.required],
FORMCONTROLNAME_THREE: ["", Validators.required]
}))
});
HTML side
<ng-container *ngFor="let formGroup of formArray.controls;">
<div [formGroup]="formGroup">
<input formControlName="FORMCONTROLNAME_ONE">
<input formControlName="FORMCONTROLNAME_TWO">
<input formControlName="FORMCONTROLNAME_THREE">
</div>
</ng-container>
Obviously you can apply a filter on the userForm that
if(userForm.value.order.length!==0){
// submit
}else{
// not submit
}

In Angular, how do I manipulate what shows in the option tag based on a previous selection?

I'm struggling to find a second solution to how I have this implemented. First I will show you how it's implemented then explain how it needs to be changed.
html:
<div class="input-group">
<h4>Session: </h4>
<select class="custom-select form-control-sm" id="inputGroupSelect01"
(change)="sessionDataChange($event)" [(ngModel)]="sessionReportFilter.sessionName">
<option value="null">Select session...</option>
<option *ngFor="let session of sessionData; index as i;"
[value]="i">
{{session.sessionName}}
</option>
</select>
</div>
<div class="input-group">
<h4>Report Date: </h4>
<select class="custom-select form-control-sm" id="inputGroupSelect01"[(ngModel)]="sessionReportFilter.fileName">
<option value="">Select report date...</option>
<option *ngFor="let report of reports"
[value]="report">
{{report}}
</option>
</select>
</div>
<div>
<button type="button" class="btn btn-primary" (click) ="orderExceptionReportData()">Retrieve</button>
</div>
</div>
component.ts:
export class OrderExceptionReportComponent implements OnInit {
public sessionData: ExceptionReportSessionData[] = [];
public sessionReportData: ExceptionReportData;
public sessionReportFilter: ExceptionReportFilter = {
sessionName: "Washington",
fileName: "EXCEPTION20130211060056882.csv"
}
reports = [];
cols = [
{ header: 'ItemId' },
{ header: 'AltItemId' },
{ header: 'GenName' },
{ header: 'StationName' },
{ header: 'HospitalCode' },
{ header: 'Facility' },
{ header: 'Reason' }
];
constructor(private orderExceptionReportService: OrderExceptionReportService) {
}
public async getExceptionReportSessionData(): Promise<void> {
return this.orderExceptionReportService.GetExceptionReportSessionData()
.then(
data => {
this.sessionData = data;
});
}
public async orderExceptionReportData(): Promise<void> {
return this.orderExceptionReportService.OrderExceptionReport(this.sessionReportFilter)
.then(
data => {
this.sessionReportData = data;
console.log(this.sessionReportData)
});
}
async ngOnInit() {
await this.getExceptionReportSessionData();
}
sessionDataChange(evt) {
const value = evt.target.value;
if (isNaN(Number(value))) {
this.reports = [];
} else {
this.reports = this.sessionData[Number(value)].reportFiles;
}
console.log(this.reports);
}
}
Right now as you can see in my first drop down the [value] is set to i and that's so the function I have called on (change) can get the correct data show in the second drop down. Well I need [value] to be set to session.sessionName because I am using two way databinding so that when the user clicks the retrieve button the correct data is being sent to the function. How can I change the implementation so that based on which Session the user selects in the drop downs only the ReportDates associated with the Session are correct so that I can use two way data binding to make the function call on the button Retrieve?
One simple way is to update the sessionData of the report select when change event occurs on session select. You have several way of doing this I will propose you a simple one,
component.ts
sessions: ExceptionReportSessionData[] = []; // the list obtained from service
reports: string[] = []; // the reports list
sessionChange(evt) {
const value = evt.target.value;
console.log(`session index: ${value}`);
if (isNaN(Number(value))) {
this.reports = [];
} else {
this.reports = this.sessions[Number(value)].ReportFiles;
}
console.log(`reports: ${this.reports}`);
}
component.html
<div class="input-group">
<h4>Session: </h4>
<select class="custom-select form-control-sm"
(change)="sessionChange($event.target.value)">
<option value="null">Select session...</option>
<option *ngFor="let session of sessions; index as i;"
value="{{i}}">{{session.SessionName}}</option>
</select>
</div>
<div class="input-group">
<h4>Report Date: </h4>
<select class="custom-select form-control-sm">
<option value="null">Select report date...</option>
<option *ngFor="let report of reports"
value="report">{{report}}</option>
</select>
</div>
Pretty straight forward implementation of the above idea. Like I mention there are several ways to do this.
Working Blitz
Change your html to :-
<div class="input-group">
<h4>Session: </h4>
<select class="custom-select form-control-sm" id="inputGroupSelect01"
(change)="sessionDataChange($event)" [(ngModel)]="sessionReportFilter.sessionName">
<option value="null">Select session...</option>
<option *ngFor="let session of sessionData; index as i;"
[value]="session.sessionName">
{{session.sessionName}}
</option>
</select>
</div>
<div class="input-group">
<h4>Report Date: </h4>
<select class="custom-select form-control-sm" id="inputGroupSelect01"[(ngModel)]="sessionReportFilter.fileName">
<option value="">Select report date...</option>
<option *ngFor="let report of reports"
[value]="report">
{{report}}
</option>
</select>
</div>
<div>
<button type="button" class="btn btn-primary" (click) ="orderExceptionReportData()">Retrieve</button>
</div>
</div>
Change your typescript method to :-
sessionDataChange(evt) {
const sessionName= evt.target.value;
if (!sessionName || sessionName.length === 0) {
this.reports = [];
} else {
this.reports = this.sessionData.find((session) => session.sessionName === sessionName).reportFiles;
}
console.log(this.reports);
}

How to send data from datalist in Angular to Rest api

I have a frontend project in Angular where I have a Html file with a datalist and another backend project Restful API
How do I get the selected option from the datalist in Angular and send the value to my rest server. I use Glassfish. I want to read it in JSON format.
Here is some code I already have and tried to use.
export class OrganizeComponent implements OnInit {
#ViewChild('f') form: NgForm;
restaurant = {
naam: '',
adres: ''
};
constructor(private router: Router, private http: HttpClient) { }
ngOnInit() {
}
onOrganize(form: NgForm) {
this.restaurant.naam = this.form.value.naam;
this.restaurant.adres = this.form.value.adres;
this.http.post('http://localhost:8080/testproject/resources/restaurant', {
naam: this.restaurant.naam,
adres: this.restaurant.adres})
.subscribe(
res => {
console.log(res);
},
err => {
console.log('Error occured');
}
);
}
btnClick1= function () {
this.router.navigateByUrl('/menu');
};
<div class="form-group">
<div class="card-body">
<form
(ngSubmit)="onOrganize(f)"
#f="ngForm">
<label for="restaurants">Choose a restaurant:</label>
<input list="restaurantList" id="restaurants" ngModel name="naam"/>
<datalist id="restaurantList" name="naam">
<option id="mcdonalds" name="naam" type="text">Mcdonalds</option>
<option id="kentuckyfriedchicken" name="naam">Kentucky Fried Chicken</option>
<option id="burgerking" name="naam">Burger King</option>
<option id="dominospizza" name="naam">Domino's pizza</option>
</datalist>
<div class="form-group">
<label>Address</label>
<input
type="text"
class="form-control form-control-lg rounded-0"
ngModel
name="adres"
required
address>
</div>
<button type="submit"
class="btn btn-primary btn-lg float-right"
[disabled]="!f.valid" (click)="btnClick1();">Make
</button>
</form>
</div>

Angular directives stop working halfway down the page

I have an Angular Reactive Form on a page, and some Angular functions stop working after a br about halfway down the page. My mat-card-title no longer shows up, and an *ngFor loop no longer displays data. If I move the *ngFor loop up the page (anywhere before the mat-card that's after the br) it works just fine.
I've tried putting a simple li *ngFor=.... in every section below the br and it doesn't work anywhere. I have several arrays to loop through - none of them work. The only error I get in the console is "Cannot read property 'includes' of undefined" - because the first ngFor loop (factionGAs) does not get populated. I actually see that it reserves four slots (there are four items in the array), but doesn't put the data in.
HTML:
<div id="uploader" class="uploader">
<div [hidden]="submitted" class="card-body">
<mat-card id="heading" ([ngModel])="playerSub">
<h3>Entering Results as:</h3>
<h4>{{player.username}}</h4>
</mat-card>
<br>
<mat-card>
<mat-card-title>Find opponent:</mat-card-title>
<form [formGroup]="searchForm" (ngSubmit)="findPlayers()">
<div class="form-group">
<select placeholder="Search by:" class="form-control"
formControlName="searchBy">
<option [value]="null">Search by:</option>
<option value="playerId">Player ID</option>
<option value="email">Email address</option>
<option value="username">Username</option>
</select>
<input *ngIf="searchQuery.includes('playerId')" class="form-
control" type="text"
placeholder="Enter Player ID" formControlName="playerId" />
<input *ngIf="searchQuery.includes('email')" class="form-control"
type="text"
placeholder="Enter Email" formControlName="email" />
<input *ngIf="searchQuery.includes('username')" class="form-
control" type="text" placeholder="Enter Username"
formControlName="username"/>
</div>
<mat-card-actions>
<button class="btn btn-primary" type="submit">Search</button>
</mat-card-actions>
</form>
<mat-card-footer *ngIf="playerList" ([ngModel])="playerList">
{{playerList.username}}</mat-card-footer>
</mat-card>
<br>
<mat-card *ngIf="playerFound" style="text-align: center">
<mat-card-title>Enter your results: </mat-card-title>
<form [formGroup]="uploadForm" (ngSubmit)="submitGame()">
<mat-card-content>
<div class="card-group" style="margin: auto 10% auto 10%">
<mat-card>
<mat-card-title>{{player.username}}'s Results:</mat-card-title>
<div class="form-group">
<select class="form-control" formControlName="P1GA">
<option [ngValue]="null" disabled>Select Grand Alliance:
</option>
<option *ngFor="let ga of factionGAs" value="ga.value">
{{ga.name}}</option>
</select>
<select *ngIf="P1GA.name.includes('Order')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of orderFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P1GA.name.includes('Destruction')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of desFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P1GA.name.includes('Chaos')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of chaosFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P1GA.name.includes('Death')"
formControlName="playerOneFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of deathFactions" [value]="sf">{{sf}}
</option>
</select>
<select class="form-control" formControlName="playerOneResult"
required>
<option [ngValue]="null">Select your result:</option>
<option *ngFor="let result of results" [value]="result">
{{result}}</option>
</select>
</div>
</mat-card>
<mat-card ([ngModel])="playerList">
<mat-card-title>{{playerList.username}}'s Results:</mat-card-title>
<div class="form-group">
<select placeholder="Select Grand Alliance" class="form-control"
formControlName="P2GA">
<option [ngValue]="null">Select Grand Alliance:</option>
<option *ngFor="let ga of factionGAs" [value]="ga">{{ga.name}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Order')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of orderFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Destruction')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of desFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Chaos')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of chaosFactions" [value]="sf">{{sf}}
</option>
</select>
<select *ngIf="P2GA.name.includes('Death')"
formControlName="playerTwoFaction" class="form-control">
<option [ngValue]="null">Select Faction:</option>
<option *ngFor="let sf of deathFactions" [value]="sf">{{sf}}
</option>
</select>
<select class="form-control" formControlName="playerTwoResult"
required>
<option [ngValue]="null">Select your result:</option>
<option *ngFor="let result of results" [value]="result">
{{result}}</option>
</select>
</div>
</mat-card>
</div>
<mat-card style="align-content: center" width="60%">
<div class="form-group">
<select formControlName="battlePlan" class="form-control"
required>
<option [value]="null">Select Battleplan:</option>
<option *ngFor="let plan of battleplans" [value]="plan">
{{plan}}</option>
</select>
<select class="form-control" formControlName="pointsLevel"
required>
<option [value]="null">Select points level:</option>
<option value="1000">1000</option>
<option value="2000">2000</option>
</select>
</div>
</mat-card>
</mat-card-content>
<br>
<mat-card-actions>
<button type="submit" class="button">Submit</button>
<button class="button" (click)="toggleEditForm()">{{ editBtnText }}
</button>
<input type="button" name="Review" value="History">
</mat-card-actions>
</form>
</mat-card>
</div>
<br>
<mat-card *ngIf="submitted" ([ngModel])="formSub">
<mat-card-title>You submitted the following:</mat-card-title>
<div class="row">
<div class="col-xs-3">Faction: </div>
<div class="col-xs-9">{{formSub.playerOneFaction}}</div>
</div>
<div class="row">
<div class="col-xs-3">Battleplan: </div>
<div class="col-xs-9">{{formSub.battlePlan}}</div>
</div>
<div class="row">
<div class="col-xs-3">Result: </div>
<div class="col-xs-9">{{formSub.playerOneResult}}</div>
</div>
<br>
<mat-card-actions>
<button class="button" (click)="submitted=false">Edit</button>
</mat-card-actions>
</mat-card>
</div>
ts file:
import { Component, OnInit, OnDestroy, Input } from '#angular/core';
import { AuthService } from '#/_services/authentication.service';
import { FormBuilder, Validators, FormGroup, FormControl } from
'#angular/forms';
import { Router, ActivatedRoute } from '#angular/router'
import { Games } from '#/_services/games.service';
import { Rank } from '#/_services/rank.service';
import { Game } from '#/_models/games';
import { Player } from '#/_models/players';
import { Subscription, Observable } from 'rxjs';
import { FilterSortService } from '#/_services/filter-sort.service';
import { OrderFactions, DesFactions,
ChaosFactions, DeathFactions, BattlePlans } from '#/_models/data-
arrays';
#Component({
selector: 'app-upload',
templateUrl: './upload.component.html',
styleUrls: ['./upload.component.css']
})
export class UploadComponent implements OnInit, OnDestroy {
#Input() gameId: number;
showEditForm = false;
editBtnText: string;
playerGame: Game;
gamesSub: Subscription;
loggedInSub: Subscription;
routeSub: Subscription;
playerSub: Subscription;
games: Game[];
id: number;
playerOne: number;
playerTwo: number;
player: Player = new Player;
gameCheck: Game = new Game;
playerListSub: Subscription
searchQuery: string[] = [];
playerList: Player = new Player;
playerFound = true;
filteredPlayers: Player[];
factionGAs = [
{ name: 'Chaos', value: 'chaosRank' },
{ name: 'Death', value: 'deathRank' },
{ name: 'Destruction', value: 'desRank' },
{ name: 'Order', value: 'orderRank' }
]
P1GA: string[] = [];
P2GA: string[] = [];
orderFactions = OrderFactions;
chaosFactions = ChaosFactions;
desFactions = DesFactions;
deathFactions = DeathFactions;
battleplans = BattlePlans;
results = [
'Major Victory', 'Minor Victory',
'Minor Loss', 'Major Loss', 'Draw'
]
players: Player[];
loading: boolean;
error: boolean;
query: '';
submitted = false;
searchForm: FormGroup;
uploadForm: FormGroup;
formSub: Subscription;
message: string;
constructor(private router: Router, public auth: AuthService, public game:
Games,
private rank: Rank, public fs: FilterSortService, private
route: ActivatedRoute,
private formBuilder: FormBuilder) { }
ngOnInit() {
this._getGames();
this.toggleEditForm(false);
this._getPlayerList();
this.loggedInSub = this.auth.currentUser.subscribe(loggedIn => {
this.loading = true;
if (loggedIn) {
this._routeSubs();
}
});
this.searchForm = this.formBuilder.group({
searchBy: null,
playerId: null,
email: null,
username: null
});
this.uploadForm = this.formBuilder.group({
playerOne: null,
playerTwo: null,
playerOneResult: [null, Validators.required],
playerTwoResult: [null, Validators.required],
battlePlan: [null, Validators.required],
pointsLevel: [null, Validators.required],
P1GA: null,
P2GA: null,
playerOneFaction: [null, Validators.required],
playerTwoFaction: [null, Validators.required],
playerOneList: [null, Validators.required],
playerTwoList: [null, Validators.required]
});
this.uploadForm.get('P1GA').valueChanges.subscribe(value => {
this.P1GA = [];
this.P1GA.push(value);
});
this.uploadForm.get('P2GA').valueChanges.subscribe(value => {
this.P2GA = [];
this.P2GA.push(value);
});
this.searchForm.get('searchBy').valueChanges.subscribe(value => {
this.searchQuery = [];
this.searchQuery.push(value);
})
}
private _routeSubs() {
// set playerId from route params and subscribe
this.routeSub = this.route.params.subscribe(params => {
this.id = params['playerId'];
this._getPlayer();
});
}
private _getPlayer() {
this.loading = true;
// Get player by playerID
this.playerSub = this.rank.getPlayer(this.id).subscribe(res =>{
this.player = res;
this.loading = false;
},
err => {
console.error(err);
this.loading = false;
this.error = true;
});
}
toggleEditForm(setVal?: boolean) {
this.showEditForm = setVal !== undefined ? setVal : !this.showEditForm;
this.editBtnText = this.showEditForm ? 'Cancel Edit' : 'Edit Last Game';
}
private _getGames() {
this.loading = true;
this.gamesSub = this.game.getGame(this.gameId)
.subscribe(res => {
this.games = res;
this.loading = false;
},
err => {
console.error(err);
this.loading = false;
this.error = true;
});
}
private _getPlayerList() {
this.loading = true;
// Get future, public events
this.playerListSub = this.rank
.getPlayers()
.subscribe(
res => {
this.playerList = res;
this.filteredPlayers = res;
this.loading = false;
},
err => {
console.error(err);
this.loading = false;
this.error = true;
}
);
}
get s() {return this.searchForm.controls;}
findPlayers() {
if (this.searchForm.invalid) {
return;
}
let formValue = this.searchForm.value;
for (let prop in formValue) {
if (!formValue[prop]) {
delete formValue[prop];
}
if (formValue.searchBy) {
delete formValue.searchBy;
}
if (Array.isArray(formValue[prop])) {
let resultArray = formValue[prop].filter((item: any) => item);
if (resultArray.length > 0 ) {
formValue[prop] = resultArray;
}
}
}
this.rank.findPlayer(formValue)
.subscribe(
result => {
this.playerList = result;
console.log(result);
this.playerFound = true;
},
error => {
console.log("Error", error);
});
}
submitGame() {
this.uploadForm.controls['playerOne'].setValue(this.player.playerId);
this.uploadForm.controls['playerTwo'].setValue(this.playerList.playerId);
//console.log(this.uploadForm.value);
this.game.upload(this.uploadForm.value)
.subscribe();
this.submitted = true;
this.formSub = this.uploadForm.value;
}
onSubmitGame(e: any) {
if (e.game) {
this.playerGame = e.game;
this.toggleEditForm(false);
}}
ngOnDestroy() {
this.playerListSub.unsubscribe();
this.gamesSub.unsubscribe();
this.playerSub.unsubscribe();
}
}