How do I get an interaction between 2 buttons (Angular)? - html

I have two buttons that when activated
show the content of "shouldTrianglePropertyBeShown" or "shouldShapeBeShown". When I click a button, the color of the respective button also changes. Unfortunately, it is currently so that if one button is activated and I also activate the other button that both contents are displayed to me. Of course I would prefer if one is activated then the other should be deactivated.
I have tried several things but unfortunately I have not managed to create an interaction between the two buttons.
Does anyone have a tip for me how to disable another button and its content ?
Here is my code:
MY PAGE.TS
selectTriangleProperty(shownPropertiesNumber: number) {
this.arePropertiesOfTriangleVisible[shownPropertiesNumber] = !this.arePropertiesOfTriangleVisible[shownPropertiesNumber];
this.getStatusOfButtonDetailsActivation(shownPropertiesNumber);
}
shouldTrianglePropertyBeShown(shownPropertiesNumber: number) {
this.getStatusOfButtonDetailsActivation(shownPropertiesNumber);
return this.arePropertiesOfTriangleVisible[shownPropertiesNumber];
}
selectShapeInformation(shownShapeNumber: number) {
this.areShapeInformationVisible[shownShapeNumber] = !this.areShapeInformationVisible[shownShapeNumber];
this.getStatusOfButtonShapeActivation(shownShapeNumber);
}
shouldShapeBeShown(shownShapeNumber: number) {
this.getStatusOfButtonShapeActivation(shownShapeNumber);
return this.areShapeInformationVisible[shownShapeNumber];
}
getStatusOfButtonDetailsActivation(shownPropertiesNumber: number)
{
const propertyButtonActivated = document.getElementById('structure-properties-button');
const informationButtonActivated = document.getElementById('shape-information-button');
if(this.arePropertiesOfTriangleVisible[shownPropertiesNumber])
{
propertyButtonActivated.style.backgroundColor = '#9AD2C9';
}
else if(!this.arePropertiesOfTriangleVisible[shownPropertiesNumber])
{
propertyButtonActivated.style.backgroundColor = '#FFFFFF';
}
}
getStatusOfButtonShapeActivation(shownShapeNumber: number)
{
const informationButtonActivated = document.getElementById('shape-information-button');
if(this.areShapeInformationVisible[shownShapeNumber])
{
informationButtonActivated.style.backgroundColor = '#9AD2C9';}
else if(!this.areShapeInformationVisible[shownShapeNumber])
{
informationButtonActivated.style.backgroundColor = '#FFFFFF';
}
}
MY HTML
<ion-buttons>
<ion-button id="triangle-properties-button" class="table-button-green"
(click)="selectTriangleProperty(j)">
Details
</ion-button>
</ion-buttons>
<ion-buttons>
<ion-button id="shape-information-button" class="table-button-white" (click)="selectBridgeInformation(j)">
Brückeninformationen
</ion-button>
</ion-buttons>
<ion-row *ngIf="shouldTrianglePropertyBeShown(j)" size="12" class="content-subrow" id="triangle-properties" >
<ion-col size="4" *ngFor="let property of triangle.triangleProperties" style="margin-top: 8px; background-color:#f9efef; ">
<div class="detailView__label">{{property.propertyName}}</div>
<div class="detailView__text"> {{property.propertyValue}}</div>
</ion-col>
</ion-row>
<ion-row *ngIf="shouldShapeBeShown(j)" size="12" class="content-subrow" id="triangle-properties" >
<ion-row>

Does this work for you:
HTML:
<ion-buttons>
<ion-button
[disabled]="activateShape"
id="triangle-properties-button"
class="table-button-green"
(click)="selectTriangleProperty(j); activateShape=!activateShape;activateTriangle= false;">
Details
</ion-button>
</ion-buttons>
<ion-buttons>
<ion-button
[disabled]="activateTriangle"
id="shape-information-button"
class="table-button-white"
(click)="selectBridgeInformation(j); activateTriangle=!activateTriangle; activateShape=false;">
Brückeninformationen
</ion-button>
</ion-buttons>
TS (as attributes of your Class):
activateShape = false;
activateTriangle = false;
NOTE: If that works fine, you can move all the logic of the "clicks" to functions in the ts.

Related

Property 'type' does not exist on type 'unknown'

I am receiving various errors like this after I do
ionic build --prod --release
src/app/pages/top-media/top-media.page.ts:18:16
18 templateUrl: './top-media.page.html',
~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component TopMediaPage.
Error: src/app/pages/top-media/top-media.page.html:106:36 - error TS2339: Property 'type' does not exist on type 'unknown'.
106 <ng-container *ngIf="media?.type==='T'">
html
<ion-refresher slot="fixed" (ionRefresh)="topMediaSet($event)">
<ion-refresher-content pullingIcon="circles" refreshingSpinner="crescent" refreshingText="Refreshing...">
</ion-refresher-content>
</ion-refresher>
<ion-row>
<ion-col class="ion-text-center">
<ion-button class="media-btn" mode="ios" color="danger" (click)="filter('V')">
<ion-icon slot="icon-only" name="videocam-outline"></ion-icon>
</ion-button>
</ion-col>
<ion-col class="ion-text-center">
<ion-button class="media-btn" mode="ios" color="success" (click)="filter('A')">
<ion-icon slot="icon-only" name="volume-high-outline"></ion-icon>
</ion-button>
</ion-col>
<ion-col class="ion-text-center">
<ion-button class="media-btn" mode="ios" color="tertiary" (click)="filter('T')">
<ion-icon slot="icon-only" name="document-outline"></ion-icon>
</ion-button>
</ion-col>
<ion-col class="ion-text-center">
<ion-button class="media-btn" mode="ios" color="warning" (click)="filter('P')">
<ion-icon slot="icon-only" name="camera-outline"></ion-icon>
</ion-button>
</ion-col>
</ion-row>
<ion-row *ngFor="let media of topMedia | filterByType: mediaType | slice:1; let i = index">
<ng-container *ngIf="media?.type==='T'">
{{media?.message | slice:0:2000}}
</p>
The problems occurs when i use the filter I created | filterByType: mediaType
ts
topMedia:any =[];
mediaType:string = '';
constructor(
...
) {
this.topMediaSet();
}
topMediaSet(refresher?:any) {
this.offset = 0;
if (typeof refresher == 'undefined') {
this.loading = true;
}
this.userData.topMedias(this.offset).pipe(
map((data: any) => {
if (data.success) {
this.topMedia = data.topMedia;
}
if (typeof refresher != 'undefined') {
refresher.target.complete();
}
this.loading = false;
})
).subscribe()
}
filter(mediaType: string) {
this.mediaType = mediaType;
console.log(mediaType);
}
filter pipe
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'filterByType',
})
export class FilterByTypePipe implements PipeTransform {
/**
* Takes a value and makes it lowercase.
*/
transform(items: any[], type: any): any {
if (!items) return [];
if (!type) return items;
type = type.toLowerCase();
console.log('type', type);
return items.filter(it => {
if (it.type) {
return it.type.toLowerCase().includes(type);
}
});
}
}
I am getting this error if i put
filterByType: mediaType |
If I REMOVE THIS LINE FOR THE NGFOR I AM NOT GETTING ANY ERRORS BUT I NEED THE FILTER. Any hint?
Thanks
Production flags invoke stricter compilers.
Null means it doesn't exist.
You are trying to send null to a pipe, hence the error message.
Without a working stackblitz reproducing your error, it is challenging to provide an accurate answer, but try adding ngIf to your P tag like so.
This will first test for existence, with null evaluating to false.
<p class="ion-text-wrap" *ngIf="media?.message">
{{media?.message | slice:0:2000}}
</p>
change
topMedia:any =[];
to
topMedia: Array<any> =[];
this should probably solve your problem. but if you know what are you going to put inside the topMedia array, I suggest you define a Media interface and define the array like this:
export interface Media{
message: string;
...
}
...
topMedia: Array<Media> =[];
And if you are worried about message being null you should check it with *ngIf in the container of the message or above that (e.g. like the way E. Maggini said)
I got it to show no errors but it doesnt seem to be the correct thing to do. Just a workaround
I replaced
media.type
to
media['type']
If someone has a better answer please share. But it did deleted all the errors i was getting after ionic build --prod --release

How to change the button layout when the Lottie Animation ends in angular?

One of the requirements of our application is to use Lottie to add animation for the onboarding part of the app. The scenario will be, if the Lottie animation has ended, the Skip to Homepage button should change to the Home button. I am having a hard time on how I will implement it with my app. I've been stuck here for almost a week but still, I can't apply to my app. I am quite confused if I applied it correctly. Hope you can help me. I will be adding my codes below for reference. Thank you
.ts
// LOTTIE
animationCreated(animationItem: AnimationItem): void {
this.animationItem = animationItem;
this.animationItem.autoplay = true;
this.animationItem.loop = false;
if (this.animationItem.loop === false) {
this.onLoopComplete();
this.showHomeButton = true;
}
}
onLoopComplete(): void {
this.ngZone.runOutsideAngular(() => {
this.animationItem.addEventListener('loopComplete', () => {});
console.log(
this.animationItem.addEventListener('loopComplete', () => {})
);
});
}
.html
<div class="demo">
<ng-lottie
*ngIf="shown"
containerClass="centerLottie"
width="520px"
height="420px"
[options]="options"
(animationCreated)="animationCreated($event)"
></ng-lottie>
</div>
<ion-row>
<ion-col size="4"></ion-col>
<ion-col size="4">
<div class="ion-text-center ion-no-padding" *ngIf="this.pageInddex_d==1">
<ion-button *ngIf="!showHomeButton" fill="clear" routerLink="/home" size="large" shape="round" color="primary">
Skip to homepage
</ion-button>
<ion-button *ngIf="showHomeButton" expand="full" routerLink="/home" size="large" shape="round" color="primary">
Home
</ion-button>
</div>

Change Ionic button color for a specific button not for all of them

I have this code for multi buttons inside Ngfor and I want just the clicked button to change its color not all of them, how can I do it please?
.html:
<ion-col size="6" *ngFor="let data of dataArray" >
<ion-card>
<ion-card-header>
<ion-button class="fav-icon2" ion-button [color]="ionicNamedColor (click)="changecolor()" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
</ion-card>
</ion-col>
.ts:
public ionicNamedColor: string = 'warning';
changecolor() {
if(this.ionicNamedColor === 'warning') {
this.ionicNamedColor = 'primary'
} else {
this.ionicNamedColor = 'warning'
}
}
here you are using the array named dataArray for showing the buttons on the screen.
Add one more property called clicked in the object used in the dataArray.
So whenever you call the method for changeColor, you just check the property clicked and decide whether to change the color or not.
So your file should be updated with the following code:
<ion-col size="6" *ngFor="let data of dataArray" >
<ion-card>
<ion-card-header>
<ion-button class="fav-icon2" ion-button [color]="data.isClicked?'warning':'primary" (click)="data.isClicked = !data.isClicked" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
Here there is not need to add anything in your typescript file.
You are iterating over an array through an ngFor loop, means many button elements could get created, but you have only one single variable for the color attribute, thats why changing for one button, shall change colors for all.
Having said that, you'll have to devise a mechanism so that each rendered button elements through ngFor should get its own reference of color variable. Seeing your code, you should either have the color variable inside the dataArray array, or maintain a separate array of string equal in length to dataArray. Something like this..
public colorArr:string[]= [];
//initially I've populated dataArray with initial colors.
public ngOnInit(){
this.dataArray.forEach(x=>this.colorArr.push('warning'));
}
Your HTML would get modified, like this
<ion-col size="6" *ngFor="let data of dataArray; let i = index" >
<ion-card>
<ion-card-header>
<ion-button class="fav-icon2" ion-button [color]="colorArr[i]" (click)="changecolor(i)" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
</ion-card>
</ion-col>
And your changeColor mehtod would get modified like this
changecolor(index) {
if(this.colorArr[index] === 'warning') {
this.colorArr[index] = 'primary'
} else {
this.colorArr[index] = 'warning'
}
}
So in essence we are maintaing colors in separate array for each single button element, without affecting original dataArray.
Another approach could be you create a separate component only for button elements, and pass its relevant data through #input decorators. In that case your this approach of single variable would work.
Thanks.
Try this using button index..
<ion-col size="6" *ngFor="let data of dataArray; index as i;" >
<ion-card>
<ion-card-header>
<ion-button
class="fav-icon2"
ion-button [color]="activeIndex==i ? 'warning' : 'primary'
(click)="setIndex(i)" >
<ion-icon name="heart"></ion-icon>
</ion-button>
</ion-card-header>
</ion-card>
</ion-col>
activeIndex;
setIndex(index) {
this.activeIndex = index:
}
Note: you can change color as per the condition..

Updating a list in ionic modal updates original list ionic 5

I have a clarification, Basically i am passing a list from parent page to Ionic modal. In modal, i will iterating over a list. i am basically modifying a property of an object on click of ion-item.
Below is the html code in the modal.
<ion-card *ngFor="let item of items">
<ion-row>
<ion-col size="3">
<ion-img width="80" height="80" [src]="item.imagePath"></ion-img>
</ion-col>
<ion-col size="7" >
<ion-label class="item-name">item.name</ion-label>
<ion-label class="item-price">item.cost</ion-label>
<ion-label class="item-date">item.date</ion-label>
</ion-col>
<ion-col size="2">
<ion-icon class="select-icon" name="add-circle" (click)="updateObj(item)"></ion-icon>
</ion-col>
</ion-row>
</ion-card>
In modal.component.ts
ngOnInit() {
this.items = this.navParams.get("items");
}
dismissModal(){
this.modalCtrl.dismiss();
}
updateObj(object){
if(object){
object.status = true
}
}
i am using navParams to get the list from parent page to the modal. When i click on ion-item i will be calling updateObj method where i am updating the status of object to true. Everything works fine.
But when i update the object in the modal, the original list sent to the modal also gets updated.
Could anyone explain why updating the list in the modal updates the original list. Is it bcoz of using navParams as it referers to the list?
In Parent.component.ts
async openSearchModal(){
const modal = await this.modalCtrl.create({
component: CouponSearchPage,
componentProps: { items: this.itemListData,
}
});
This is how i am passing the list to the modal from parent screen.
When you pass this.itemListData to modal, you are passing the reference of the object.
If you don't want to modify the actual object, you can pass a new object.
Try this:
const modal = await this.modalCtrl.create({
component: CouponSearchPage,
componentProps: { items: { ...this.itemListData},
}
});

change "add" icon to "add-circle" icon when users click on it

I'm new to coding and I need the "add" Icon to be replaced with "add-circle" icon when users click on it. please help me. Below is the addToCart method in my ts file, what do I have to add in here to replace properly? Please help me
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>
Courses
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item *ngFor="let item of courseList">
<ion-thumbnail slot="start">
<img [src]=item.picture>
</ion-thumbnail>
<ion-label>
<h2>{{item.title}}</h2>
<p> {{item.price | currency}}</p>
<ion-button size="small" id="adding" (click)=addToCart(item)>
<ion-icon slot="icon-only" name="add"></ion-icon>
</ion-button>
</ion-label>
</ion-item>
</ion-list>
</ion-content>
async addToCart(item: Course) {
this.cartService.add(item);
const toast = await this.toastController.create({
message: item.title + ' added to compare',
duration: 2000,
position: 'top',
color: 'secondary'
});
toast.present();
}
}
Declare a variable that has an icon name
public icon: string;
and initialize the icon variable in the constructor
constructor() {
this.icon = 'add';
});
}
and in the addToCart() method assign new add-circle icon
addToCart(item){
this.icon ="add-circle"
}
and finally in the html file
<ion-icon name="{{icon}}"></ion-icon>
Live Demo
Html file
<ion-icon [name]="addCircleIcon" (click)='addCircle()'></ion-icon>
Declare a variable an icon name:
addCircleIcon: string = 'add-icon';
click() function:
addCircle() {
this.addCircleIcon = this.addCircleIcon === 'add-icon' ? 'add-icon-circle' : 'add-icon';
}