Simple question.
I have a login template - a form for username and password:
<template>
<section>
<h2>${heading}</h2>
<form role="form" submit.delegate="login()">
<div class="form-group">
<label for="userName">User Name</label>
<input type="text" value.bind="userName" class="form-control" id="userName" placeholder="User Name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" value.bind="password" class="form-control" id="password" placeholder="Password">
</div>
<button type="button" click.delegate="submitLogin()" class="btn btn-default">Login</button>
</form>
<hr>
<div class="alert alert-danger" if.bind="loginError">${loginError}</div>
</section>
I have looked around to find out how I can access these variables in my login.ts file.
In particular I want to eventually send them to the api once the button login has been pressed.
I have a submitLogin() function but I dont know how you access the variables username and password.
Can someone show me how these variable are accessed.
I get a red underscore for username and password..
import { HttpClient } from "aurelia-fetch-client";
import { autoinject } from "aurelia-framework";
import { TokenService } from "../tokenService";
#autoinject
export class Login {
http: HttpClient;
tokenService: TokenService;
heading = "Login";
constructor(tokenService: TokenService, http: HttpClient, ) {
this.tokenService = tokenService;
this.http = http;
}
public submitLogin(): void {
console.log("userName, Password", this. userName, this.password);
}
}
form submit logic can be bound to <form> itself having given the button type submit
<form role="form" submit.delegate="submitLogin()">
<div class="form-group">
<label for="username">User Name</label>
<input type="text" value.bind="username" class="form-control" id="username" placeholder="User Name">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" value.bind="password" class="form-control" id="password" placeholder="Password">
</div>
<button type="submit" class="btn btn-default">Login</button>
</form>
you can make your class fields accessible from the view or otherwise as below
import { HttpClient } from "aurelia-fetch-client"
import { autoinject } from "aurelia-framework"
import { TokenService } from "../tokenService"
#autoinject
export class Login {
heading: string = "Login"
username: string = ''
password: string = '' // these are pubic fields available in your view unless you add 'private' in front of them
constructor(private tokenService: TokenService, private http: HttpClient) { // this way you can keep them private since they are not needed in the view
}
submitLogin() {
const { username, password } = this
if (!!username && !!password) { // or your validations
this.tokenService.login({ username, password })
}
}
}
Related
I'm new to angular and I can't get this code to work.
I have hospital management system and I'm trying to create an appointment using my doctor and patient classes. I am successfully able to fetch the doctors and patients into my drop down menus but once I submit all other fields save apart from them?
They are the only fields that are foreign keys I think I may have to use my doctor and patient service in angular in my appointment service to save it but I'm not sure how.
The error I get is this
core.mjs:6485 ERROR TypeError: Cannot read properties of null (reading 'firstName')
I get this twice.
This is my current code:
<div class="col-md-6 offset-md-3">
<h3> Create Appointment</h3>
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label>Date of Appointment</label>
<input type="date" class="form-control" id="appDate" [(ngModel)]="appointment.appDate" name="appDate">
</div>
<div class="form-group">
<label>Appointment Time</label>
<input type="time" class="form-control" id="lastName" [(ngModel)]="appointment.appTime" name="appTime">
</div>
<div class="form-group">
<label>Room Number</label>
<input type="number" class="form-control" id="roomNum" [(ngModel)]="appointment.roomNum" name="roomNum">
</div>
<div class="form-group">
<select name="Doctor" (change)="ChangeDoctor($event)" class="form-control">
<option>--Select--</option>
<option [value]="doc.id" *ngFor="let doc of DoctorList">
{{doc.firstName}} {{doc.lastName}}
</option>
</select>
</div>
<div class="form-group">
<select name="Patient" change="ChangePatient($event)" class="form-control">
<option>--Select--</option>
<option [value]="pat.id" *ngFor="let pat of PatientList">
{{pat.firstName}} {{pat.lastName}}
</option>
</select>
</div>
<button mat-raised-button type="submit" style="margin-bottom: 30px;">Submit</button>
</form>
</div>
Create-Appointment.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Appointment } from '../appointment';
import { AppointmentService } from '../appointment.service';
import { DoctorService } from '../doctor.service';
import { PatientService } from '../patient.service';
#Component({
selector: 'app-create-appointment',
templateUrl: './create-appointment.component.html',
styleUrls: ['./create-appointment.component.css']
})
export class CreateAppointmentComponent implements OnInit {
appointment: Appointment = new Appointment();
PatientList: any;
DoctorList: any;
ChangeDoctor(e:any){
console.log(e.target.value)
}
ChangePatient(e:any){
console.log(e.target.value)
}
constructor(private appointmentService: AppointmentService, private doctorservice: DoctorService, private patientservice: PatientService, private router: Router ) { }
ngOnInit(): void {
this.doctorservice.getDoctorsList().subscribe((data:any)=> {
this.DoctorList=data;
})
this.patientservice.getPatientsList().subscribe((data:any)=> {
this.PatientList=data;
})
}
saveAppointment() {
this.appointmentService.createAppointment(this.appointment).subscribe( data => {
console.log(data);
this.goToAppointmentList();
},
error => console.log(error));
}
goToAppointmentList(){
this.router.navigate(['/appointments']);
}
onSubmit(){
console.log(this.appointment)
this.saveAppointment();
}
}
I am making registration form in nuxt js, it takes data from api, I have installed axios and auth module, I wrote base url in nuxt.config.js file. It shows TypeError: Cannot read property 'post' of undefined
```template>
<div>
<section class="content">
<div class="register_form m-auto text-center form-group">
<form method="post" #submit.prevent="register" >
<h1 class ="register_title">REGISTER</h1>
<h2 class="register_text">PLEASE REGISTER TO USE THIS WEBSITE</h2>
<input class="form-control" type="text" placeholder = 'USERNAME' v-model="username" name="username" required>
<input class="form-control" type="password" placeholder = 'PASSWORD' v-model="password" name="password" required>
<button type="submit" to="#" class="register_btn">
REGISTER
</button>
</form>
</div>
</section>
</div>
</template>
<script>
export default {
layout: 'loginLayout',
data(){
return {
username: '',
password: ''
}
},
methods: {
async register() {
try {
await this.$axios.post('register', {
username: this.username,
password: this.password
})
this.$router.push('/')
}
catch (e) {
console.log(e)
}
}
}
}
</script>```
try to use
await this.$axios.$post instead of await this.$axios.$post
I am new to Aurelia and need help accessing values from custom element in another view.
I have a scenario where I would like to share input file for attachment in multiple forms. One of the approach I am taking is to create custom element for input files that can be shared with multiple forms in web application.
Below is my code:
Custom element called FilePicker which will be shared between multiple forms. In my Request paged I inserted the custom element called:
<file-picker router.bind="router" accept="image/*" multiple="true" ></file-picker>
My requirement is to access property called validFiles which is an array. I would like to use values from validFiles to custom object in Request view model called formData['attachment']
TS:
import { customElement, useView, bindable, bindingMode } from 'aurelia-framework';
#customElement('file-picker')
#useView('./file-picker.html')
export class FilePicker {
#bindable accept = '';
#bindable multiple = false;
#bindable({ defaultBindingMode: bindingMode.twoWay }) files: FileList;
validFiles = [];
input: HTMLInputElement;
// Validate function for on change event to input file.
public filesChanged() {
if (!this.files) {
this.clearSelection();
}
if (this.files) {
this.processFiles();
}
}
// Trigger on button click
public triggerInputClick() {
this.input.click();
}
// Find value in array of object
private findValinArrObj(arr, key, val) {
return arr.map(function (v) { return v[key] }).indexOf(val);
}
// Process file for each new files uploaded via browser
private processFiles() {
if (this.files) {
for (let i = 0; i < this.files.length; i++) {
let findFile = this.findValinArrObj(this.validFiles, 'name', this.files.item(i).name);
if (findFile === -1) {
this.validFiles.push(this.files.item(i));
}
}
this.clearSelection();
}
}
// Remove file from fileNames and validFiles array
public removeByFileName(fileName) {
if (this.validFiles) {
for (let i = 0; i < this.validFiles.length; i++) {
if (this.validFiles[i].name === fileName) {
this.validFiles.splice(i, 1);
}
}
}
}
// Clear input file in DOM
private clearSelection() {
this.input.type = '';
this.input.type = 'file';
}
}
HTML:
<template>
<input type="file" accept.bind="accept" multiple.bind="multiple"
files.bind="files" ref="input"
style="visibility: hidden; width: 0; height: 0;">
<button class="btn btn-primary" click.delegate="triggerInputClick()">
<slot>Browse...</slot>
</button>
<ul class="list-group" if.bind="validFiles">
<li class="list-group-item" repeat.for="file of validFiles" style="padding: 0; border:none;">
${file.name} <span class="glyphicon glyphicon-remove text-danger" style="cursor: pointer;" click.delegate="removeByFileName(file.name)"></span>
</li>
</ul>
</template>
Parent View Model:
TS:
export class Request {
pageTitle: string = "Request Page";
title: string = '';
description: string = '';
businessValue: string = '';
emails: string = '';
formData: object = {};
public postData() {
this.formData['title'] = this.title;
this.formData['description'] = this.description;
this.formData['businessValue'] = this.businessValue;
this.formData['emails'] = this.emails;
this.formData['attachment'] = [];
console.log(this.formData);
}
}
HTML:
<template>
<require from="./request.css"></require>
<require from="../../resources/elements/file-picker"></require>
<div class="panel panel-primary">
<div class="panel-heading">${pageTitle}</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="text" value.two-way="title" class="form-control" id="title" placeholder="Brief one-line summary of the request">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">Description</label>
<div class="col-sm-10">
<input type="text" value.two-way="description" class="form-control" id="description" placeholder="Detailed description of the request">
</div>
</div>
<div class="form-group">
<label for="description" class="col-sm-2 control-label">Business Value</label>
<div class="col-sm-10">
<input type="text" value.two-way="businessValue" class="form-control" id="description" placeholder="Description of how this offers business value">
</div>
</div>
<div class="form-group">
<label for="emails" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="text" value.two-way="emails" class="form-control" id="emails" placeholder="Provide email address">
</div>
</div>
<div class="form-group">
<label for="exampleInputFile" class="col-sm-2 control-label">Attachment(s)</label>
<div class="col-sm-10">
<file-picker router.bind="router" accept="image/*" multiple="true" ></file-picker>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<button type="submit" class="btn btn-default pull-right" click.trigger="postData()">Submit</button>
</div>
</div>
</form>
</div>
</div>
</template>
Any help is really appreciated. :)
You can set up two-way-binding on your Request view, to bind the validFiles in your child view (file-picker) to a variable in your parent view (Request):
request.html:
<file-picker valid-files.two-way="validFiles"></file-picker>
request.ts:
public validFiles: File[];
file-picker.ts:
#bindable
public validFiles: File[];
This way any changes made to the validFiles object in either the child or the parent will update the object in both viewmodels.
I have the following passwordvalidator which I don't know how to attach into the html. The way I am invoking it now it's not working loginForm.controls.password.errors.passwordValidator
See below in the actual code.
import { FormControl } from "#angular/forms";
export class PasswordValidator {
static getPasswordValidator() {
return function passwordValidator(control: FormControl): { [s: string]: boolean } {
// Write code here..
if (!control.value.match(/^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,})/)) {
return { invalidPassword: true };
}
return null;
}
}
}
Then this is how I am using it in login.ts
ngOnInit() {
this.loginForm = this.fb.group({
username: ['', [Validators.required, Validators.email]],
password: ['',
Validators.compose([
Validators.required,
PasswordValidator.getPasswordValidator()
]
)]
});
}
But can't find out how to add it to the formcontrol in login.html
<mat-form-field class="example-full-width">
<input id="password" formControlName="password" matInput placeholder="Password">
</mat-form-field>
<br>
<div *ngIf="loginForm.controls.password.invalid && (loginForm.controls.password.dirty || loginForm.controls.password.touched)"
class="alert alert-danger">
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.required">
You must fill out your password
</div>
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.passwordValidator && !loginForm.controls.password.errors.required">
Invalid email password
</div>
You should check if the key invalidPassword exist in errors of that controls or not like that
<mat-form-field class="example-full-width">
<input id="password" formControlName="password" matInput placeholder="Password">
</mat-form-field>
<br>
<div *ngIf="loginForm.controls.password.invalid && (loginForm.controls.password.dirty || loginForm.controls.password.touched)"
class="alert alert-danger">
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.required">
You must fill out your password
</div>
<div class="error mat-body-2" *ngIf="loginForm.controls.password.errors.invalidPassword && !loginForm.controls.password.errors.required">
Invalid email password
</div>
I am new for angular 2. I have a page where we can edit details of customer profile. How to enable save button if any property of has been changed. I know it is possible in angular1 by using $watch.
It is simple. dirty check your form if you are using #angular/forms.
create form
export class HeroDetailComponent4 {
heroForm: FormGroup;
states = states;
constructor(private fb: FormBuilder) {
this.createForm();
}
createForm() {
this.heroForm = this.fb.group({
name: ['', Validators.required ],
street: '',
city: '',
state: '',
zip: '',
power: '',
sidekick: ''
});
}
}
HTML:
<h2>Hero Detail</h2>
<h3><i>A FormGroup with multiple FormControls</i></h3>
<form [formGroup]="heroForm" novalidate>
<button (click)="submit()" [disabled]="!heroForm.dirty" type="button">Submit</button>
<div class="form-group">
<label class="center-block">Name:
<input class="form-control" formControlName="name">
</label>
</div>
<div class="form-group">
<label class="center-block">Street:
<input class="form-control" formControlName="street">
</label>
</div>
<div class="form-group">
<label class="center-block">City:
<input class="form-control" formControlName="city">
</label>
</div>
<div class="form-group">
<label class="center-block">State:
<select class="form-control" formControlName="state">
<option *ngFor="let state of states" [value]="state">{{state}}</option>
</select>
</label>
</div>
<div class="form-group">
<label class="center-block">Zip Code:
<input class="form-control" formControlName="zip">
</label>
</div>
<div class="form-group radio">
<h4>Super power:</h4>
<label class="center-block"><input type="radio" formControlName="power" value="flight">Flight</label>
<label class="center-block"><input type="radio" formControlName="power" value="x-ray vision">X-ray vision</label>
<label class="center-block"><input type="radio" formControlName="power" value="strength">Strength</label>
</div>
<div class="checkbox">
<label class="center-block">
<input type="checkbox" formControlName="sidekick">I have a sidekick.
</label>
</div>
</form>
use heroForm.dirty to check whether form data is changed. it will set to true if any control inside heroForm has been changed.
<button (click)="submit()" [disabled]="!heroForm.dirty" type="button">Submit</button>
Refer angular docs for more info
you can use form control validation for it.
some thing like this in html template:
<form fxLayout="column" [formGroup]="form">
<mat-form-field class="mb-1">
<input matInput [(ngModel)]="userProfileChangeModel.firstName" placeholder="نام"
[formControl]="form1.controls['fname']">
<small *ngIf="form1.controls['fname'].hasError('required') && form1.controls['fname'].touched"
class="mat-text-warn">لطفا نام را وارد نمایید.
</small>
<small *ngIf="form1.controls['fname'].hasError('minlength') && form1.controls['fname'].touched"
class="mat-text-warn">نام باید حداقل 2 کاراکتر باشد.
</small>
<small *ngIf="form1.controls['fname'].hasError('pattern') && form1.controls['fname'].touched"
class="mat-text-warn">لطفا از حروف فارسی استفاده نمائید.
</small>
</mat-form-field>
<mat-card-actions>
<button mat-raised-button (click)="editUser()" color="primary" [disabled]="!form1.valid" type="submit">
ذخیره
</button>
</mat-card-actions>
</form>
and like this in ts file:
this.form = this.bf.group({
fname: [null, Validators.compose([
Validators.required,
Validators.minLength(2),
Validators.maxLength(20),
Validators.pattern('^[\u0600-\u06FF, \u0590-\u05FF]*$')])],
});
if:
[disabled]="!form1.valid"
is valid save button will be active
bast regards.
You can use disabled option like below :
<button [disabled]="isInvalid()" type="button" (click) = "searchClick()" class="button is-info">
<span class="icon is-small">
<i class="fa fa-search" aria-hidden="true"></i>
</span>
<span>Search</span>
</button>
you can create isInvalid() in your ts file and check if that property is empty or not and return that boolean value
and for hide button on a state you can use *ngIf in line directive.
This worked for me, pls try.
In your html,
<input type="text" [ngModel]="name" (ngModelChange)="changeVal()" >
<input type="text" [ngModel]="address" (ngModelChange)="changeVal()" >
<input type="text" [ngModel]="postcode" (ngModelChange)="changeVal()" >
<button [disabled]="noChangeYet" (click)="clicked()" >
<span>SUBMIT</span>
</button>
In your component
export class customer implements OnInit {
name: string;
address: string;
postcode: string;
noChangeYet:boolean = true;
constructor() {}
changeVal(){ // triggers on change of any field(s)
this.noChangeYet = false;
}
clicked(){
// your function data after click (if any)
}
}
Hope this is what you need.
Finally I resolved this issue.
import { Component, Input, Output, OnInit, AfterViewInit, EventEmitter, ViewChild } from '#angular/core';
#Component({
selector: 'subscribe-modification',
templateUrl: './subscribe.component.html'
})
export class SampleModifyComponent implements OnInit, AfterViewInit {
disableSaveSampleButton: boolean = true;
#ViewChild('sampleModifyForm') sampleForm;
ngAfterViewInit() {
setTimeout(() => {
this.sampleForm.control.valueChanges.subscribe(values => this.enableSaveSampleButton());
}, 1000);
}
enableSaveSampleButton() {
console.log('change');
this.disableSaveSampleButton = false;
}
}
HTML
<button id="btnSave" class="btn btn-primary" (click)="save()" />