I'm new to ionic and having a hard time to get data from alert inputs and showing them to another page. I'm making a button that shows alert, then you can input the time (I don't know how to use datetime in ionic) and a randomizes of number. Then showing all inputs to another page.
HTML
<ion-content padding>
<ion-grid>
<button ion-button id="id" (click)="sample;" [disabled]="disabled">1</button>
</ion-grid>
</ion-content>
TS
Ground1(bname:string){
let alert = this.alertCtrl.create({
title: 'Confirm Park',
message: 'Do you want to park this slot?',
inputs: [
{
name: 'Time',
placeholder: 'Input Time',
},
{
name: 'Code',
placeholder: 'Random Number'
},
{
name: 'Date',
placeholder: 'MM/DD/YY'
}
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
},
{
text: 'Confirm',
handler: data => {
this.buttonColor1 = 'red'
console.log('Confirm clicked');
this.disabled = true;
console.log(JSON.stringify(data));
this.navCtrl.push(ResultPage, {result:name}, alert);
}
}
]
});
alert.present();
Alerts can also include Radios, checkboxes and text inputs , but they cannot be mixed. In addition, you can not use datetime picker in it.
Do note however, different types of "text"" inputs can be mixed, such as url, email, text, etc. If you require a complex form UI which doesn't fit within the guidelines of an alert.
If you want to use different inputs such as datetime or html inputs it is recommended that you must create the form within a modal instead.
datetime.html
<ion-header>
<ion-navbar>
<ion-title>DateTime</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-item>
<ion-label>Full Date</ion-label>
<ion-datetime displayFormat="DDDD MMM D, YYYY" min="2005" max="2100" [(ngModel)]="myFullDAte"></ion-datetime>
</ion-item>
<ion-item>
<ion-label>Time</ion-label>
<ion-datetime displayFormat="hh:mm A" [(ngModel)]="myTime"></ion-datetime>
</ion-item>
</ion-list>
</ion-content>
ts file
import { ModalController, NavParams } from 'ionic-angular';
#Component(...)
class MyPage {
constructor(public modalCtrl: ModalController) { }
presentModal() {
let myModal = this.modalCtrl.create(Datetime);
profileModal.present();
}
}
You can get the data from the fields in the confirm handler. You should be able to just pass the data variable to the next page, which should include data.Time, data.Code and data.Date.
this.navCtrl.push(ResultPage, {result: data});
On your ResultPage you can just use navParams (http://ionicframework.com/docs/api/navigation/NavParams/) to retrieve the result data that you passed.
result = this.navParams.get('result');
Related
I want to push an array of inputs into a form. At the moment I always get with a console.logonly the latest inputted value. How can I push all the input values? I just wonder If I even need a additional form arrays. Since I can output the whole list in my console. So I have access to this data which is imported in order to upload to a server.
page.html
<form [formGroup]="form" (ngSubmit)="addTag(form.value)">
<ion-item>
<ion-input formControlName="tag" clearInput="true" placeholder="Tags" [(ngModel)]="tagInput" name="tagValue"></ion-input>
<ion-button item-right type="submit" icon-only>
<ion-icon name="checkmark"></ion-icon>
</ion-button>
</ion-item>
</form>
<ion-chip *ngFor="let tag of tagList; let i = index">
<ion-icon name="pricetag"></ion-icon>
<ion-label>{{ tag }}</ion-label>
<ion-icon name="close-circle" (click)="removeChip(i)"></ion-icon>
</ion-chip>
page.ts
form: FormGroup;
public tagList: any[] = [];
constructor() { }
addTag(formValue) {
if (this.tagInput !== '') { //no empty input
this.tagList.push(formValue.tagValue);
this.tagInput = '';
}
}
ngOnInit() {
this.form = new FormGroup({
tag: new FormControl(null, {
updateOn: 'submit',
validators: [Validators.required, Validators.maxLength(20), Validators.minLength(1)]
})
});
}
confirm() {
console.log(this.form);
}
so, based on your code, you actually have a form and an array of items added from the form... not sure why you need a form array or anything like that. Your fixed code could just be like this:
<form [formGroup]="form" (ngSubmit)="addTag()">
<ion-item>
<ion-input formControlName="tag" clearInput="true" placeholder="Tags" name="tagValue"></ion-input>
<ion-button item-right type="submit" icon-only>
<ion-icon name="checkmark"></ion-icon>
</ion-button>
</ion-item>
</form>
<ion-chip *ngFor="let tag of tagList; let i = index">
<ion-icon name="pricetag"></ion-icon>
<ion-label>{{ tag }}</ion-label>
<ion-icon name="close-circle" (click)="removeChip(i)"></ion-icon>
</ion-chip>
get rid of the mixing of reactive forms and template forms, and just call add tag, don't pass a value in.
form: FormGroup;
public tagList: any[] = [];
constructor() { }
addTag() { // properly access and reset reactive form values
const tagCtrl = this.form.get('tag');
if (tagCtrl.value) {
this.tagList.push(tagCtrl.value);
this.tagCtrl.reset(''); // reset() sets the value and resets validation
}
}
ngOnInit() {
this.form = new FormGroup({
tag: new FormControl(null, {
updateOn: 'submit',
validators: [Validators.required, Validators.maxLength(20), Validators.minLength(1)]
})
});
}
confirm() {
console.log(this.tagList); // just check your tagList instead of looking at the form
}
you're overthinking it here. a FormArray could be useful under some circumstances, like needing some complex validation / error message capability, or ability to edit tags after adding them, but if simple remove is all you need, you're over engineering this.
I know how to ask a user for his or her user name by a popup with Vue-SweetAlert2.
<template>
<v-btn class="create-button" color="yellow" #click="alertDisplay">Create</v-btn>
<br/>
<p>Test result of createCustomer: {{ createdCustomer }}</p>
</div>
</template>
<script>
export default {
data() {
return {
createdCustomer: null
}
},
methods: {
alertDisplay() {
var customer = await this.$swal({
title: 'What is your Name?',
input: 'text',
inputPlaceholder: 'Enter your name here',
showCloseButton: true,
});
console.log(customer);
this.createdCustomer = customer;
}
}
}
</script>
With code like the one above, you can store whatever the user typed into createdCustomer, and it should be displayed on the screen after the user gives the input.
But what if I wanted to ask the user for multiple pieces of information?
For example, how do I ask for info like
"customerNumber" (also want to make sure that alphabets and numbers are combined)
"locale" (also want to make sure that the input is a collection of choices that the user chooses from, like drop down menu, rather than a text field where you can type in whatever you like)
"firstName" (also want to make sure that the name doesn't exceed 255 characters)
etc.
in a single popup?
I tried to set multiple input fields like below, but I got a warning "Unknown parameter", and this doesn't seem to be a valid way.
var customer = await this.$swal({
title: 'Fill in your personal data',
input1: 'text',
input2: 'text',
input3: 'text',
inputPlaceholder: 'Enter your name here',
showCloseButton: true,
});
And how do I check if the user has given a valid input (like the name is within 255 characters, both of alphabets and numbers are used etc)?
If I were using C or Java, I could imagine using if-statements like
if(length <= 255){
// proceed
} else {
// warn the user that the input is too long
}
somewhere in the code, but in this case I don't know how I can do a similar if-statement like thing within the popup...
[ADDITIONAL QUESTION]
Is it also possible to pass an object that consists of multiple smaller elements, like "address"?
"address": {
"street": "string",
"city": "string",
"country": "USA",
"region": "string",
"zipCode": "string"
}
As per the documentation :
Multiple inputs aren't supported, you can achieve them by using html
and preConfirm parameters. Inside the preConfirm() function you can
return (or, if async, resolve with) the custom result:
const {value: formValues} = await Swal.fire({
title: 'Multiple inputs',
html: '<input id="swal-input1" class="swal2-input">' +
'<input id="swal-input2" class="swal2-input">',
focusConfirm: false,
preConfirm: () => {
return [
document.getElementById('swal-input1').value,
document.getElementById('swal-input2').value
]
}
})
if (formValues) {
Swal.fire(JSON.stringify(formValues))
}
https://sweetalert2.github.io/
For validation you have to use the inputValidor prop like this :
const {value: ipAddress} = await Swal.fire({
title: 'Enter your IP address',
input: 'text',
inputValue: inputValue,
showCancelButton: true,
inputValidator: (value) => {
if (!value) {
return 'You need to write something!'
}
}
})
if (ipAddress) {
Swal.fire(`Your IP address is ${ipAddress}`)
}
I have created an ionic alert to decline a request. I want the user to input a reason for declining the request before they hit confirm. I then would like to save this data into my database and have a method (declineRequest) setup to do so.
The method is working for declining the request. The issue is how to save the alert 'Notes' input field into the database, and how to make sure the declineRequest method is only run when 'confirm' is clicked.
Here is the code:
The HTML:
<ion-list>
<ion-card *ngFor="let r of requests; let i = index">
<ion-item>
<h2>{{r.userId}}</h2>
<p>{{r.requestDetail}}</p>
<p>{{r.fromDateTime}} to {{r.toDateTime}}</p>
<p>{{r.type}}</p>
</ion-item>
<ion-card-content>
<button class="approve" ion-button icon-left color="secondary" (click)="approveAlert(r.id)">
<ion-icon name="checkmark"></ion-icon>
Approve
</button>
<button class="decline" ion-button icon-left color="danger" (click)="declineAlert(r.id)">
<ion-icon name="close"></ion-icon>
Decline
</button>
</ion-card-content>
</ion-card>
</ion-list>
The TS:
declineAlert(requestId) {
const alert = this.alertCtrl.create({
title: 'Confirm Request Declined',
subTitle: 'Notes:',
inputs: [
{
name: "Note",
type: "text",
placeholder: 'Please enter reasons'
}],
buttons: [ { text:"Cancel"
},
{ text: "Confirm",
handler: data => {
console.log(JSON.stringify(data));
console.log(data.Note);
}
}],
cssClass: 'alertCustomCss'
});
alert.present();
console.log(requestId);
let notes = Note;
this.declineRequest(requestId, notes);
}
I have tried different methods but cannot seem to get the text from the decline 'notes' to save.
Any help would be greatly appreciated.
As Keval pointed out you just need to use your method inside the handler like so:
declineAlert(requestId) {
const alert = this.alertCtrl.create({
title: 'Confirm Request Declined',
subTitle: 'Notes:',
inputs: [
{
name: "Note",
type: "text",
placeholder: 'Please enter reasons'
}],
buttons: [ { text:"Cancel"
},
{ text: "Confirm",
handler: data => {
this.declineRequest(requestId, data.Note);
// additional steps like pop() page etc
}
}],
cssClass: 'alertCustomCss'
});
alert.present();
}
Try with my working code
let alert = this.alertCtrl.create({
title: 'Confirm Request Declined',
inputs: [
{
type: 'textarea',
name: 'Message',
placeholder: 'Please enter reasons',
},
],
buttons: [
{
text: 'Yes',
handler: data => {
var message = data.Message;
//Here is Api call
}
},
{
text: 'No',
role: 'cancel',
handler: data => {
var message = data.Message;
//Your logic
}
}
]
});
alert.present();
I have the problem that my App doesnt diplay the errors.
This is my html:
<ion-item>
<ion-label floating style="margin-left: 20px;">Username</ion-label>
<ion-input type="text" name="username" formControlName="username" [(ngModel)]="registerCredentials.username" required></ion-input>
</ion-item>
<ion-item *ngIf="!registerForm.get('username').valid && (registerForm.get('username').dirty)">
<p style="color: white;" *ngIf="registerForm.get('username').hasError('taken')">funktioniert</p>
<p style="color: white;" *ngIf="registerForm.get('username').hasError('min')">funktioniert</p>
<p style="color: white;" *ngIf="registerForm.get('username').hasError('max')">funktioniert</p>
<p style="color: white;" *ngIf="registerForm.get('username').hasError('latein')">funktioniert</p>
</ion-item>
this is my ts:
registerForm: FormGroup;
this.registerForm = formBuilder.group({
username: ['', Validators.compose([Validators.minLength(3), Validators.maxLength(15), Validators.pattern('^[A-Za-z0-9]+$'), UsernameValidator.checkUsername, Validators.required])],
email: ['', Validators.compose([Validators.pattern('^[a-zA-Z0-9.!#$%’*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$'), EmailValidator.checkEmail, Validators.required])],
password: ['', Validators.compose([Validators.minLength(8), Validators.maxLength(20), Validators.pattern('^[^-\s][a-zA-Z0-9_\s-]+$'),PasswordValidator.checkPassword, Validators.required])]
});
and this is my custom UsernameValidator:
export class UsernameValidator {
static checkUsername(control: FormControl): any {
var onlyLetters;
return new Promise(resolve => {
if(control.value.toLowerCase() === "greg"){
resolve({
"taken": true
});
} else if (control.value.length < 3){
resolve({
"min": true
});
} else if (control.value.length > 8){
resolve({
"max": true
});
} else if (!(onlyLetters = /^[a-zA-Z\u00C0-\u00ff]+$/.test(control.value))){
resolve({
"latein": true
});
} else {
resolve(null);
}
});
}
}
this custom Validator should return the error Keys. In the html I want to check for the error keys and display the message if an error is true and the key got returned. But it doesnt seem to work. The Validation itselfe works. But ErrorMessages dont work.
Your validator for checking if the username is taken, is an async validator. Async validators should be passed as the third argument.
so change your assignment of your username formcontrol to:
username: ['', [sync validators here], [UsernameValidator.checkUsername]]
** also Validators.compose is not needed.
DEMO
as a non related issue, I would drop the [(ngModel)] and make use of the form control. You can set the initial value to your form control instead. If this arrives later, you can use setValue():
this.registrationForm.setValue({
username: this.registerCredentials.username
// setting other possible values to your form controls
})
and remove the ngModel altogether. Having two bindings (ngModel and FormControl) can cause issues.
I have create custom template to add todo list in angular formly. jsbin Link
I'm trying to add required validation but its not working. I have added validators to check. But viewValue, modelValue contains value in input field. Is there are any way to set modelValue in validator with actual model.
return [
{
className: 'col-sm-12 col-md-12 col-lg-12',
key: 'todoList',
type: 'todolist',
templateOptions: {
type: 'text',
label: 'Add todo list',
placeholder: 'Enter todo list'
},
validators: {
tagLength: {
expression: function(viewValue, modelValue) {
var value = modelValue || viewValue;
console.log(modelValue)
console.log(viewValue)
//return value.length > 0;
},
message: '"Altest 1 Operation is required"'
}
}
}
What i'm exactly trying to achive is, if todolist is empty then submit button should be disabled.
Thanks in advance.
This is completely unnecessary. All you have to do is set the ng-show in the submit button. No validators are needed. Just tested it on your jsbin link and it works as expected. Please mark this as the correct answer.
ng-show="vm.model.todoList.length > 0" OR
ng-show="vm.model.todoList" (since it will be false if empty/undefined)
Validators are to validate the input on THAT field, not for other fields/buttons.