File
Implements
Index
Properties
|
|
Methods
|
|
Accessors
|
|
Methods
addingCents
|
addingCents()
|
|
|
decimalKeyDown
|
decimalKeyDown(event: KeyboardEvent)
|
|
Parameters :
Name |
Type |
Optional |
event |
KeyboardEvent
|
No
|
|
decreaseSize
|
decreaseSize()
|
|
|
deletedCents
|
deletedCents()
|
|
|
increaseSize
|
increaseSize(event: KeyboardEvent)
|
|
Parameters :
Name |
Type |
Optional |
event |
KeyboardEvent
|
No
|
|
isAmountNotValid
|
isAmountNotValid()
|
|
|
isAuthCheck
|
isAuthCheck()
|
|
|
isMissingAmount
|
isMissingAmount()
|
|
|
keyDown
|
keyDown(event: KeyboardEvent)
|
|
Parameters :
Name |
Type |
Optional |
event |
KeyboardEvent
|
No
|
|
ngOnDestroy
|
ngOnDestroy()
|
|
|
savePaymentInfo
|
savePaymentInfo()
|
|
|
submitPayment
|
submitPayment()
|
|
|
toggleAuthInput
|
toggleAuthInput()
|
|
|
toggleAuthMethod
|
toggleAuthMethod()
|
|
|
toggleAuthRepeat
|
toggleAuthRepeat()
|
|
|
toggleAuthRequest
|
toggleAuthRequest()
|
|
|
updateAmount
|
updateAmount(event?)
|
|
|
updateDecimal
|
updateDecimal(value)
|
|
|
updateIntegral
|
updateIntegral(value)
|
|
|
updateMemo
|
updateMemo(event?)
|
|
|
amount
|
Decorators :
@ViewChild('Amount')
|
|
authRequired
|
Default value : true
|
|
decimalAmount
|
Type : null
|
Default value : null
|
|
decimalinput
|
Type : ElementRef
|
Decorators :
@ViewChild('decimalInput')
|
|
defaultAccountSubscription
|
Type : any
|
|
hasPaymentFee
|
Default value : false
|
|
hasVerifyFee
|
Default value : false
|
|
input
|
Type : ElementRef
|
Decorators :
@ViewChild('integralInput')
|
|
inputCharacterWidth
|
Type : number
|
Default value : 39
|
|
integralAmount
|
Type : null
|
Default value : null
|
|
isCopied
|
Default value : false
|
|
isLoading
|
Default value : false
|
|
limitSubscription
|
Type : Subscription
|
|
loaderHeader
|
Type : string
|
Default value : ''
|
|
loadingLimits
|
Default value : false
|
|
maxInputLength
|
Type : number
|
Default value : 6
|
|
message
|
Type : string
|
Default value : ''
|
|
missingAmount
|
Default value : false
|
|
payment
|
Default value : new Payment()
|
|
selectedTemplateId
|
Type : string
|
|
showAuthInput
|
Default value : false
|
|
showAuthMethod
|
Default value : false
|
|
showAuthRepeat
|
Default value : false
|
|
showAuthRequest
|
Default value : false
|
|
showChangeAccount
|
Default value : false
|
|
showCredit
|
Default value : false
|
|
showDebit
|
Default value : false
|
|
templateTypes
|
Default value : TemplateType
|
|
Accessors
debitTemplateDisplayName
|
getdebitTemplateDisplayName()
|
|
creditTemplateDisplayName
|
getcreditTemplateDisplayName()
|
|
import { Location } from '@angular/common';
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { MultiFactorTypes } from '../../enums';
import { TemplateType } from '../../enums/template-type.enum';
import { BankAccount, Payment, Template } from '../../models';
import { MaskPipe } from '../../pipes';
import {
MaterialService,
PaymentService,
SessionStore,
TemplateService,
} from '../../providers';
import { AppStateStore } from '../../providers/stores/app-state.store';
import { filter, switchMap, tap } from '../../../../node_modules/rxjs/operators';
import { LimitsResult } from '../../models/limits-result.model';
import { Observable, Subscription } from 'rxjs';
import { GET_PAYMENTS_BY, ORDER_BYS, ORDER_BY_DIRECTIONS } from '../../app.constants';
@Component({
selector: 'app-sending-money',
templateUrl: './sending-money.component.html',
styleUrls: ['./sending-money.component.css'],
})
export class SendingMoneyComponent implements OnInit {
@ViewChild('integralInput')
input: ElementRef;
@ViewChild('decimalInput')
decimalinput: ElementRef;
@ViewChild('Amount')
amount;
maxInputLength = 6;
inputCharacterWidth = 39;
isCopied = false;
showChangeAccount = false;
showAuthRequest = false;
showAuthMethod = false;
showAuthRepeat = false;
showAuthInput = false;
integralAmount = null;
decimalAmount = null;
payment = new Payment();
account: BankAccount;
selectedTemplateId: string;
template: Template;
missingAmount = false;
loaderHeader = '';
message = '';
isLoading = false;
authRequired = true;
templateTypes = TemplateType;
showDebit = false;
showCredit = false;
creditTemplate: Template;
debitTemplate: Template;
memo: string;
hasPaymentFee = false;
feeAmount: number;
hasVerifyFee = false;
limitResult: LimitsResult;
limitSubscription: Subscription;
loadingLimits = false;
defaultAccountSubscription: any;
constructor(
public app: AppStateStore,
public sessionStore: SessionStore,
private route: ActivatedRoute,
private templateService: TemplateService,
private materialService: MaterialService,
private maskPipe: MaskPipe,
private router: Router,
private ref: ChangeDetectorRef,
private paymentService: PaymentService
) {}
ngOnInit() {
this.route.params.subscribe((params) => {
this.selectedTemplateId = params['id'];
});
this.app.state$.subscribe((state) => {
this.debitTemplate = state.debitTemplate;
this.creditTemplate = state.creditTemplate;
this.limitResult = state.limitsResult;
this.loadingLimits = state.loadingIsLimits;
});
this.app.acknowledgeDuplicate = false;
this.paymentService
.loadPayments(GET_PAYMENTS_BY.SCHEDULED, ORDER_BYS.PaymentDate, ORDER_BY_DIRECTIONS.ASC)
.subscribe((wasSuccess) =>
wasSuccess
? console.log('prefetch payments complete')
: console.log('prefetch payments failed')
);
console.log('app-user-form component loaded');
this.materialService.render();
this.templateService.fee$
.pipe(filter((fee) => fee !== null && fee !== undefined && fee > 0))
.subscribe((fee) => {
this.hasPaymentFee = true;
this.feeAmount = fee;
});
this.savePaymentInfo();
setTimeout(() => {
this.input.nativeElement.focus();
}, 0);
}
updateIntegral(value) {
if (!value) {
return;
}
const val = value.replace(/\D/g, '');
this.integralAmount = val;
this.input.nativeElement.value = val;
this.updateAmount();
}
updateDecimal(value) {
if (!value) {
return;
}
const val = value.replace(/\D/g, '');
this.decimalAmount = val;
this.decimalinput.nativeElement.value = val;
this.updateAmount();
}
updateAmount(event?) {
const amt = parseFloat(`${this.integralAmount}.${this.decimalAmount}`);
this.app.amount = amt;
console.log(this.payment);
this.ref.detectChanges();
}
updateMemo(event?) {
this.app.memo = event;
console.log(event);
this.ref.detectChanges();
}
isMissingAmount() {
this.missingAmount = true;
if (this.integralAmount > 0 || this.decimalAmount > 0) {
this.missingAmount = false;
}
}
toggleAuthRequest() {
this.showAuthRequest = !this.showAuthRequest;
}
toggleAuthMethod() {
this.showAuthMethod = !this.showAuthMethod;
}
toggleAuthRepeat() {
this.showAuthRepeat = !this.showAuthRepeat;
}
toggleAuthInput() {
this.showAuthInput = !this.showAuthInput;
}
isAuthCheck() {
if (!this.app.hasPassedMfa) {
this.input.nativeElement.blur();
event.preventDefault();
this.app.useMfaModal = true;
this.toggleAuthRequest();
} else {
return;
}
}
increaseSize(event: KeyboardEvent) {
const length = this.input.nativeElement.value.length;
if (length > 0 && length < this.maxInputLength + 1) {
this.input.nativeElement.style.width =
(this.input.nativeElement.value.length + 1) * this.inputCharacterWidth + 'px';
}
}
decreaseSize() {
if (this.input.nativeElement.value.length > 0) {
this.input.nativeElement.style.width =
(this.input.nativeElement.value.length - 1) * this.inputCharacterWidth + 'px';
}
}
addingCents() {
this.decimalinput.nativeElement.focus();
setTimeout(() => {
this.decimalinput.nativeElement.value = '';
}, 0);
}
deletedCents() {
if (this.decimalAmount) {
return;
}
this.input.nativeElement.focus();
this.decimalAmount = null;
}
resetForm() {
this.app.amount = 0;
this.input.nativeElement.value = '';
this.input.nativeElement.style.width = this.inputCharacterWidth + 'px';
this.decimalinput.nativeElement.value = '';
this.missingAmount = false;
this.app.debitTemplate = undefined;
this.app.creditTemplate = undefined;
this.memo = '';
this.app.acknowledgeDuplicate = false;
}
isAmountNotValid() {
return (
this.integralAmount > 0 ||
this.decimalAmount > 0 ||
this.amount.pristine ||
(this.amount.untouched && this.amount.invalid)
);
}
keyDown(event: KeyboardEvent) {
switch (event.key) {
case 'Backspace':
case 'Delete':
this.decreaseSize();
break;
case 'Dot':
case 'Decimal':
case '.':
this.addingCents();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'Unidentified':
this.increaseSize(event);
break;
}
}
decimalKeyDown(event: KeyboardEvent) {
switch (event.key) {
case 'Backspace':
case 'Delete':
this.deletedCents();
break;
}
}
submitPayment() {
this.router.navigate(['/payment/create']);
}
verifyFee() {
!this.hasVerifyFee ? (this.hasVerifyFee = true) : (this.hasVerifyFee = false);
}
get debitTemplateDisplayName() {
if (!this.debitTemplate) {
return '';
}
this.isMissingAmount();
const name = this.debitTemplate.displayName
? this.debitTemplate.displayName
: this.debitTemplate.name;
return `${name} - ${this.maskPipe.transform(this.debitTemplate.accountNumber)}`;
}
get creditTemplateDisplayName() {
if (!this.creditTemplate) {
return '';
}
this.isMissingAmount();
const name = this.creditTemplate.displayName
? this.creditTemplate.displayName
: this.creditTemplate.name;
return `${name} - ${this.maskPipe.transform(this.creditTemplate.accountNumber)}`;
}
savePaymentInfo() {
this.memo = this.app.memo;
if (!this.app.amount) {
return;
}
const result = `${this.app.amount}`.split('.');
this.integralAmount = result[0];
this.decimalAmount = result[1];
switch (this.integralAmount.length) {
case 1:
this.input.nativeElement.style.width = this.inputCharacterWidth + 'px';
break;
case 2:
this.input.nativeElement.style.width = this.inputCharacterWidth * 2 + 'px';
break;
case 3:
this.input.nativeElement.style.width = this.inputCharacterWidth * 3 + 'px';
break;
case 4:
this.input.nativeElement.style.width = this.inputCharacterWidth * 4 + 'px';
break;
case 5:
this.input.nativeElement.style.width = this.inputCharacterWidth * 5 + 'px';
break;
case 6:
this.input.nativeElement.style.width = this.inputCharacterWidth * 6 + 'px';
break;
}
}
ngOnDestroy(): void {
if (this.defaultAccountSubscription) {
this.defaultAccountSubscription.unsubscribe();
}
}
}
<div [hidden]="isLoading">
<div class="scroller" id="sendMoneyScroller">
<form #sendMoneyForm="ngForm" name="sendMoneyForm" (ngSubmit)="submitPayment()">
<div id="sendingMoneyFormCtn">
<!-- Amount To Send -->
<div class="amount-to-send-ctn">
<div id="amountLabel"><p class="para-dark">Amount to Transfer:</p></div>
<div id="settingUpAmount">
<div id="dollarSymbol"><p>$</p></div>
<div id="dollarAmount">
<input
#integralInput
#Amount="ngModel"
[ngModel]="integralAmount"
value="integralAmount"
(ngModelChange)="updateIntegral($event)"
id="amountSend"
type="tel"
[maxlength]="maxInputLength"
name="integralAmount"
tabindex="1"
placeholder="0"
value="app.amount"
autocomplete="off"
pattern="[0-9]{1,}"
(keydown)="keyDown($event)"
required
/>
<input
#decimalInput
[ngModel]="decimalAmount"
(ngModelChange)="updateDecimal($event)"
id="amountSendCent"
type="tel"
maxlength="2"
name="decimalAmount"
tabindex="2"
autocomplete="off"
placeholder="00"
(keydown)="decimalKeyDown($event)"
/>
</div>
</div>
<div id="amountNotValidLabel" [hidden]="isAmountNotValid()" class="alert alert-danger alert-amount">
Please enter an amount for this transfer
</div>
<div class="limit-alert-ctn" [ngClass]="{ show: loadingLimits }">
<div class="limit-alert-loader">
<app-loading-linear [loadingLinearMessage]="'Checking your limits'" *ngIf="loadingLimits"></app-loading-linear>
</div>
<div *ngIf="!loadingLimits && limitResult && !limitResult.isAllowed"
class="alert alert-danger alert-amount limit-alert">
{{ limitResult.errors[0].message }}
</div>
</div>
<div id="amountActionLabel">
<p class="para-medium" id="tt4">
<span class="is-mobile">Tap</span> <span class="is-desktop">Click</span> above to
change amount
</p>
<div class="mdl-tooltip" for="tt4">
You can change how much you want to send by
<span class="is-mobile">tapping</span>
<span class="is-desktop">clicking</span> on the amount above
</div>
</div>
</div>
<!-- Form -->
<div class="form-ctn">
<p class="first-label">From Account</p>
<div id="fromAccountContainer" class="input-select" (click)="showDebit = true">
<input
type="text"
name="debitTemplateInput"
[value]="debitTemplateDisplayName"
class="cursor-pointer"
placeholder="Select Account"
(focus)="showDebit = true"
tabindex="3"
required
minlength="1"
autocomplete="off"
disabled
id="fromAccountInput"
/>
<span class="select cursor-pointer">
<i class="material-icons"> arrow_drop_down </i>
</span>
</div>
<!-- To -->
<p>To Account</p>
<div id="toAccountContainer" class="input-select" (click)="showCredit = true">
<input
type="text"
name="creditTemplateInput"
[value]="creditTemplateDisplayName"
class="cursor-pointer"
placeholder="Select Account"
(focus)="showCredit = true"
required
minlength="1"
autocomplete="off"
disabled
id="toAccountInput"
/>
<span class="select cursor-pointer">
<i class="material-icons"> arrow_drop_down </i>
</span>
</div>
<!-- Memo -->
<p class="paying-again">Note</p>
<input
type="text"
#memoInput="ngModel"
(ngModelChange)="updateMemo($event)"
[(ngModel)]="memo"
id="memo"
name="note"
[value]="app.memo"
tabindex="3"
pattern="[A-Za-z0-9,\s!.'-]+"
/>
<span>
<div
[hidden]="memoInput.valid || memoInput.value.length == 0"
class="alert alert-danger text-align"
>
Please only use A-Z, a-z, 0-9, periods, commas, dashes, spaces, apostrophes, and
exclamation points
</div>
</span>
<p class="timeline-note">Funds transferred are usually available in the "transfer to" account within 1-3 business days.</p>
<div *ngIf="hasPaymentFee">
<!-- Fee Confirmation -->
<div class="fee-verification">
<p>Fee Verification</p>
<label class="cursor-pointer">
<input
ng-control="accountType"
type="checkbox"
name="accountType"
(click)="verifyFee()"
/>
<span class="custom-checkbox"> <i class="material-icons">check</i> </span>
<span class="fee-verify"
>I verify that there is a
{{ feeAmount | currency: 'USD':'symbol':'1.2-2' }} fee and I wish to
continue</span
>
</label>
</div>
</div>
<button
type="submit"
class="action-button cursor-pointer"
tabindex="5"
id="submitPaymentButton"
[disabled]="
sendMoneyForm.invalid ||
debitTemplateDisplayName.length < 1 ||
creditTemplateDisplayName.length < 1 ||
(!hasVerifyFee && hasPaymentFee) ||
loadingLimits ||
!limitResult ||
(!loadingLimits && limitResult && !limitResult.isAllowed)
"
>
<span class="button-inside">Transfer Money</span>
</button>
<div
[style.display]="missingAmount ? 'block' : 'none'"
[hidden]="integralAmount > 0"
class="alert alert-danger alert-missing-amount"
>
Don't forget to add an amount
</div>
</div>
<div class="two-action-ctn" *ngIf="!app.hasPassedMfa && authRequired">
<p class="para-dark">
<a id="iAlreadyHaveAuthButton" (click)="isAuthCheck()">
<i class="material-icons">lock_outline</i> I Already Have An Authentication
Code</a
>
</p>
<p id="transferAuthenticatedLabel" class="para-dark status-positive" *ngIf="app.hasPassedMfa">
<i class="material-icons">lock_open</i> This Transfer Is Authenticated
</p>
</div>
<div class="two-action-ctn">
<p id="cancelTransferButton" class="para-dark"><a (click)="resetForm()">Cancel Current Transfer</a></p>
</div>
</div>
</form>
</div>
</div>
<app-select-account
*ngIf="showDebit"
[type]="templateTypes.Debit"
(close)="showDebit = false"
></app-select-account>
<app-select-account
*ngIf="showCredit"
[type]="templateTypes.Credit"
(close)="showCredit = false"
></app-select-account>
<app-authenticate-request
*ngIf="showAuthRequest"
(closeAuthRequest)="toggleAuthRequest()"
(openAuthMethod)="toggleAuthMethod()"
(openAuthRepeat)="toggleAuthRepeat()"
></app-authenticate-request>
<app-authenticate-method
*ngIf="showAuthMethod"
(closeAuthMethod)="toggleAuthMethod()"
(openAuthInput)="toggleAuthInput()"
></app-authenticate-method>
<app-authenticate-repeat
*ngIf="showAuthRepeat"
(closeAuthRepeat)="toggleAuthRepeat()"
(openAuthInput)="toggleAuthInput()"
></app-authenticate-repeat>
<app-authenticate-input
*ngIf="showAuthInput"
(closeAuthInput)="toggleAuthInput()"
(openAuthMethod)="toggleAuthMethod()"
></app-authenticate-input>
<div *ngIf="isLoading">
<app-loader [header]="loaderHeader" [message]="message"></app-loader>
</div>
.is-hidden {
display: none;
}
/*----- Amount to Send -----*/
#amountLabel,
#amountActionLabel {
text-align: center;
}
#amountLabel p {
margin: 40px 0px 15px 0px;
}
#amountActionLabel p {
margin: 0px 0px 10px 0px;
cursor: default;
}
#changeAccount p {
cursor: pointer;
margin: 6px 0 0 0;
}
#changeAccount {
margin: 0px 0px 15px 0px;
}
#dollarSymbol,
#dollarAmount {
vertical-align: top;
display: inline-block;
margin-left: -5px;
}
#dollarSymbol p {
margin: 10px 5px 0px 0px;
padding: 0px;
font-size: 30px;
font-family: 'Open Sans', sans-serif;
color: #3393a1;
}
#settingUpAmount {
text-align: center;
}
/*----- Amount Input -----*/
#settingUpAmount input {
border: none;
}
#amountSend {
padding: 0px;
width: 39px;
min-width: 39px;
max-width: 234px;
font-size: 70px !important;
line-height: 84px;
margin-top: -8px;
color: #3393a1;
text-align: left;
vertical-align: top;
}
#amountSendCent {
padding: 0px;
width: 48px;
font-size: 40px !important;
line-height: 40px;
padding-bottom: 15px;
color: #3393a1;
text-align: left;
vertical-align: top;
margin-left: 2px;
}
#settingUpAmount input[type='number']::-webkit-inner-spin-button,
#settingUpAmount input[type='number']::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
#settingUpAmount ::-webkit-input-placeholder {
color: #3393a1;
}
#settingUpAmount :-moz-placeholder {
/* Firefox 18- */
color: #3393a1;
}
#settingUpAmount ::-moz-placeholder {
/* Firefox 19+ */
color: #3393a1;
}
#settingUpAmount :-ms-input-placeholder {
color: #3393a1;
}
/*----- Form -----*/
#toWhoCtn {
z-index: 999;
position: fixed;
width: 80%;
padding: 20px;
}
@media only screen and (min-width: 500px) {
.form-ctn {
padding: 25px;
max-width: 360px;
}
}
.items-list-action i.material-icons {
font-size: 14px;
}
.alert-amount {
margin: 0px 0px 0px 0px;
text-align: center;
}
.alert-missing-amount {
text-align: center;
}
.para-dark i {
font-size: 18px;
vertical-align: bottom;
margin-bottom: -1px;
}
.two-action-ctn:last-child {
margin-top: -5px;
}
.fee-verify {
display: inline-block;
vertical-align: top;
width: 75%;
line-height: 18px;
}
.fee-verification {
margin-top: 13px;
border-top: 1px solid #ccc;
}
.timeline-note {
line-height: 18px;
margin-bottom: 0px;
}
.limit-alert-ctn {
height: 30px;
vertical-align: middle;
}
.limit-alert-loader {
margin: -25px auto -5px auto;
height: 30px;
overflow: hidden;
}
.limit-alert {
margin-top: -15px;
}
Legend
Html element with directive