How to validate dynamically added ion-input in Ionic - javascript

I am working with dynamic ion-input, there are two fields, which will be shown to the user and the user can add or remove fields.
The maximum is five fields and minimum is two. I have another input, which I can validate properly for required validation, but how can I validate dynamically added fields at runtime, which can be 2, 3, 4 or 5?
My code, for which I have done validation and the dynamic field are below. Can anyone please help me to resolve this?
single input field
<div text-center [formGroup]="pollQuesValid">
<ion-item>
<ion-input type="text" formControlName="questTxt" [(ngModel)]="question">
</ion-input>
</ion-item>
<ion-item *ngIf="!pollQuesValid.controls.questTxt.valid && submitAttemptQues" text-center text-wrap no-lines>
<p style="color: red">{{"quesValid" | translate }}</p>
</ion-item>
</div>
pollQuesValid: FormGroup;
submitAttemptQues: boolean = false;
this.pollQuesValid = formBuilder.group({
questTxt: ["", ([Validators.required])]
});
if (this.pollQuesValid.controls.questTxt.valid) {
this.submitAttemptQues = false;
console.log("question valid");
return true;
} else {
this.submitAttemptQues = true;
console.log('question invalid');
return false;
}
dynamic fields
<div>
<ion-item *ngFor="let choice of custOpts; let i = index;">
<ion-label color="primary" floating>{{choice.hint}} {{i+1}}</ion-label>
<ion-input type="text" [(ngModel)]="choice.ch"></ion-input>
<ion-icon class="remove" item-end name="md-remove" *ngIf="i>=2" (click)="removecustOpts()"></ion-icon>
</ion-item>
<div *ngIf="custOpts.length < 5" padding>
<button ion-button icon-only (click)="addNewChoice()">
<ion-icon name="md-add"></ion-icon>
</button>
</div>
</div>

You can use FomrArray to dynamically add and validate FormGroup or FormControl in a reactive form.FormArray become invalid if any one of the controls inside it is invalid (angular docs).
First, define the form and initial two fields
pollQuesValid: FormGroup;
customOptions: FormArray;
this.pollQuesValid = new FormGroup({
questTxt: new FormControl('question text', Validators.required),
options: new FormArray([
new FormControl('',Validators.required),
new FormControl('',Validators.required),
])
});
this.customOptions = this.pollQuesValid.get('options') as FormArray; //for iterating dynamic fields using *ngFor
Then change the html markup of dynamic fields like this
<div text-center [formGroup]="pollQuesValid">
...
<div formArrayName="options">
<ion-item *ngFor="let choice of customOptions.controls; let i = index;">
<ion-label color="primary" floating>Hint {{i+1}}</ion-label>
<ion-input type="text" [formControlName]="i"></ion-input>
<ion-icon class="remove" item-end name="md-remove" *ngIf="i>=2" (click)="removecustOpts(i)"></ion-icon>
</ion-item>
<div *ngIf="customOptions.controls.length < 5" padding>
<button ion-button icon-only (click)="addNewChoice()">
<ion-icon name="md-add"></ion-icon>
</button>
</div>
</div>
</div>
Here is a working StackBlitz example (pages/home).

Related

How to implement swiping ion-items in Ionic without clicking?

I am trying to implement an ion-list with ion-items that are swipable but don't have to be clicked on the side to trigger an event.
It should work like like the default contacts app on Samsung phones, where you can either swipe left to call or right to send a SMS.
The list in the parent page looks like this:
<ion-list *ngFor="let person of persons | filter:searchTerm">
<app-person-entry [person]="person" (click)="openModal(person)"></app-person-entry>
</ion-list>
The person-entry component looks like this:
<ion-item>
<ion-avatar slot="start">
<img src={{person.icon}}>
</ion-avatar>
<div>
<div class="container">
<ion-label>{{person.lastname}}</ion-label>
<ion-label>{{person.firstname}}</ion-label>
</div>
<div class="container">
<ion-label>{{person.postalCode}}</ion-label>
<ion-label>{{person.city}}</ion-label>
<ion-label>{{person.address}}</ion-label>
</div>
</div>
</ion-item>
you can use ion-item-sliding.
e.g:
<ion-list>
<ion-item-group #myItemsId>
<ion-item-sliding (ionSwipe)="swipeEvent($event, myItemsId)">
<ion-item-options side="start">
<ion-item-option>CALL</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option>SMS</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-item-group>
</ion-list>
.ts:
swipeEvent($event, item) {
console.log($event)
if ($event.detail.side == 'start') {
console.log('call now');
this.closeAllItems(item)
} else {
console.log('SMS now');
this.closeAllItems(item)
}
}
closeAllItems(item) {
let a = Array.prototype.slice.call(item.el.children)
a.map((val) => {
val.close();
})
}

How to disable a button depending on the length of a list

I want that the user can choose only one tag. So the button should be disabled after the user has pushed one tag to the list. So I made up the idea that if the list.length is bigger than 0, the button should be disabled. But somehow it doesn't work in my approach.
page.html
<ion-item>
<ion-input mode="md" formControlName="category" clearInput="true" placeholder="Tag" name="tagValue"></ion-input>
<ion-button [disabled]="!categoryForm.valid" [disabled]="tagList?.length > 1" item-right type="submit" icon-only>
<ion-icon name="checkmark"></ion-icon>
</ion-button>
</ion-item>
page.ts
public tagInput: string = '';
public tagList: any[] = [];
constructor() {}
...
addTag() { // properly access and reset reactive form values
const tagCtrl = this.categoryForm.get('category');
if (tagCtrl.value) {
this.tagList.push(tagCtrl.value);
this.tagInput = ''; // in order to have an empty input
}
}
You're using disable attribute twice:
<ion-item>
<ion-input mode="md" formControlName="category" clearInput="true" placeholder="Tag" name="tagValue"></ion-input>
<ion-button [disabled]="!categoryForm.valid || tagList?.length > 0" item-right type="submit" icon-only>
<ion-icon name="checkmark"></ion-icon>
</ion-button>
</ion-item>

assign a status to an element taken from a json

I'm doing an online bookstore project where you can also mark a book as booked. So I would like to assign a function to a button "mark as booked", once this button is pressed that item will have to have the parameter booked and disappear from the page and go to the "reserved books" page. my data I take from a local json and I do not know how to assign the parameter "booked" and make the item disappear if he had this parameter.
example of my page
html code:
<ion-content padding>
<ion-grid>
<ion-row>
<ion-col *ngFor="let libro of libri; let i =index;" >
<div>
<ion-card-header><h1>{{libro.title}}</h1></ion-card-header>
<ion-card-header (ngModelChange)="setYear($event)"><h3 >Autore:{{libro.author}}</h3></ion-card-header>
<ion-card-header><h4>Anno:{{libro.year}}</h4></ion-card-header>
<div id="immagine">
<img src="../assets/{{libro.imageLink}}">
</div>
<button ion-button (click)="modificaItem(libro)" color="">Modify</button>
<button ion-button (click)="remove(i);" color="danger" >Mark as booked</button>
<button ion-button color="{{libro.prenotato ? 'danger' : 'secondary'}}">Status</button>
</div>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
(click)="remove(i);" is a provvisory function

Ionic ngElse equal

I want to do a simple if else in Angular template. I'm using Ionic framework. What I want to do is something like
if (val != null){
document.write("No value");
}
else{
document.write("Has value");
}
What I have now is
<ion-grid *ngIf="devices">
<!-- Show if devices exist -->
<ion-row>
<ion-col>
<ion-list>
<ion-item>
device 1
</ion-item>
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
<ion-grid>
<!-- Show if devices DO NOT exist -->
<ion-row>
<ion-col>
<button text-center ion-button round col-6 offset-3> Odśwież urządznia </button>
</ion-col>
</ion-row>
</ion-grid>
I wanted to do something like *ngIf!=null or *ngElse but these two do not work.
So my question is how do I do that?
You have to use in following way -
<div *ngIf="condition; else elseBlock">
Truthy condition
</div>
<ng-template #elseBlock>
False condition
</ng-template>
hope this will help you, let me know in case any issue?

Remove ionic 2 ion-card div using Javascript in controller

I need to remove an ionic 2 card when someone clicks on the trash icon. The code I have so far gives a querySelector is null error when I run it.
The view html looks like this:
<ion-card *ngFor="#mediaItem of mediaItems" id="item{{mediaItem.id}}" class="media-item">
<ion-card-header class="title-header">
<div class="title-item">
{{mediaItem.title}}
</div>
<ion-icon name="trash" class="bookmark_trash_icon" (click)="removeItem(mediaItem.id)"></ion-icon>
</ion-card-header>
<ion-card-content class="outer-content" >
<img src='{{mediaItem.url}}'>
</ion-card-content>
<ion-item class="bookmark-media-item">
<!-- <button (click)="topup(mediaItem)" clear item-left> -->
<div style="float:left;">
<ion-icon name="heart"></ion-icon>
{{mediaItem.liked}}
<ion-icon name="close-circle"></ion-icon>
{{mediaItem.disliked}}
</div>
<a (click)="showUserProfile(mediaItem.owner, mediaItem.username)" style="float:left;">
{{mediaItem.username}}
</a>
<div style="float:right;">
<img src="img/tiny-v.png" class="bookmark-v-icon">
{{mediaItem.credits_left}}
</div>
</ion-item>
</ion-card>
My controller javascript code looks like this:
removeItem(theItemID) {
let cardToHide = '#item'+theItemID;
document.querySelector(cardToHide).style.display = 'none';
}
The error I get is
querySelector is null
You can send the object instead of the id by changing that part of the code:
(click)="removeItem(mediaItem)"
And then find that object in you mediaItems array and delete it from there. Then your view will be automatically updated.
First get the index of that object in the array, and then you can use the mediaItems.splice(index, 1) to delete it from the array:
removeItem(theItem) {
let index = this.mediaItems.indexOf(theItem);
this.mediaItems.splice(index,1);
}

Categories

Resources