Block and unblock the label to edit by clicking: Ionic - html

I want something like as above shown image. When I click on the edit button then I should able to edit the label( A little about you label ) how can I do it.
<ion-item-divider>
<ion-label>Summary</ion-label>
<button ion-button clear item-end style="font-size:11px;color: #3BABE3;font-weight:bold;">Edit
<ion-icon name="ios-arrow-forward" class="arrow"></ion-icon>
</button>
</ion-item-divider>
<ion-item class="items">
<p style="color:grey;font-size:11px;">A little about you</p>
</ion-item>
The label should be blocked when I click on edit button it should be editable.
I'm assinging "A little about you" to a variable called summary.
<p style="color:grey;font-size:11px;">A little about you</p>
Actually this should be <textarea> instead of <p>

Try using the contenteditale atribute.
<ion-item class="items">
<p contenteditable="true" style="color:grey;font-size:11px;">A little about you</p>
</ion-item>
If you want to bind it to a variable you can do it like this:
<ion-item class="items">
<p [attr.contenteditable]="editable" style="color:grey;font-size:11px;">A little about you</p>
</ion-item>
Where editable is a boolean variable.

I had a similar need / code example and after a while I realized that asking users to edit your ion-label inline of the same view is basically a bad UX.
Consider making that button "edit" of yours to just spawn an alert controller which will contain input field. This is how I did it below and in my case I did not have a special "edit" button - users could click on a title to change its name. But I think you will get the way you can do it in your case
<ion-item *ngFor="let set of sets; index as i">
<button ion-button clear (click)="changeSetTitle( set.title, i)">
<h2>{{ set.title }}</h2>
</button>
<p>{{ set.length }} items</p>
<button ion-button icon-right clear item-end (click)="loadSetComponent(i)">
Manage
<ion-icon name="arrow-forward"></ion-icon>
</button>
</ion-item>
And in ts file:
changeSetTitle(currentTitle, index) {
this.alertOn = true;
let alert = this.alertCtrl.create({
title: 'Change name:',
message: 'current: "'+currentTitle+'"',
inputs: [
{
placeholder: 'type in a new name'
}
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
handler: data => {
console.log('Cancel clicked');
this.alertOn = false;
}
},
{
text: 'Confirm',
handler: data => {
if (data[0].length === 0) {
this.sets[index].title = currentTitle;
} else {
this.saveRequired = true;
this.sets[index].title = data[0];
}
this.alertOn = false;
}
}
]
});
// small trick to force focus onto alert (not working for iOS unfortunately.)
alert.present().then(() => {
const alertInput: any = document.querySelector('input.alert-input');
alertInput.focus();
return;
});
}

Related

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>

How to check if each form control changed their value in reactive forms?

What I want to achieve in the end is to see which form controls individually from my form have changed and to create a new object with them assigning a boolean of true if they were changed or false if not. Please see below what I achieved so far, but I don't think this the right approach as when I'll have more from controls my method will become gigantic. If you guys have any idea how I can approach this I would really appreciate it.
my Html
<form [formGroup]="editProfileForm">
<ion-row>
<ion-col>
<ion-input
*ngIf="profileData"
formControlName="firstName"
placeholder="First Name"
></ion-input>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<ion-input
*ngIf="profileData"
formControlName="lastName"
placeholder="Last Name"
></ion-input>
</ion-col>
</ion-row>
</form>
<ion-fab
vertical="bottom"
horizontal="center"
slot="fixed"
(click)="onSubmitEditedProfile()">
<ion-fab-button>
<ion-icon name="checkmark-outline"></ion-icon>
</ion-fab-button>
</ion-fab>
my TS
onSubmitEditedProfile() {
if (this.profileData !== null) {
let updatedFirstName = this.editProfileForm.get("firstName").value;
if (this.profileData.firstname !== updatedFirstName) {
}
console.log("it's the same");
} else {
console.log("it's different")
}
And as my approach means, I'll do the same for lastName and so on
Here is the example where you can iterate each form control and identify either its changed or not based on that populate new array of object.
onSubmitEditedProfile() {
const formValue = [];
// iterate over form controls no matter how many control you have.
Object.keys(this.form.controls).map((key) => {
// create a new parsed object
const parsedValue = {
[key]: this.form.get(key).value, // key is the actual form control name
changed: this.form.get(key).dirty // added changed key to identify value change
}
// push each parsed control to formValue array.
formValue.push(parsedValue)
})
console.log(formValue)
}
Here is the stackblitz working DEMO
Hope this address your requirements.
All you need is just to read dirty value on FormGroup or individual FormControl
https://angular.io/api/forms/AbstractControl#dirty
onSubmitEditedProfile() {
if (!this.editProfileForm.dirty) {
console.log("it's the same");
} else {
console.log("it's different")
}

ngClass active button function Angular

How can I change the style of each button once I click on it?
I have several buttons and I need to achieve something similar to an active state, but in reality what you execute is a function.
I tried the following but I do not achieve an active state [ngClass]=" { 'btn-primary':categoria.nombre }
component.ts
ngOnInit() {
this.eventos = this.fs.getEventosAll();
this.categorias = this.fs.getCategorias();
}
filtrarEventos(categoria) {
this.eventos = this.fs.filterEventos(categoria);
}
component.html
<button class="btn btn-sm" *ngFor="let categoria of categorias | async" (click)="filtrarEventos(categoria.nombre)" [ngClass]=" { 'btn-primary':categoria.nombre } ">
{{ categoria.nombre }}
</button>
You can first, add a property, let's say, categoriaActiva to the component holding the buttons, add
this.categoriaActiva = categoria
to the filtrarEventos callback, and finally add
[class.btn-primary]="categoria.nombre === categoriaActiva"
to the button.
Here is the stackblitz of what you are trying to do
I called one method which sets the value of the clicked index
Template
<div *ngFor="let categoria of categorias; let i = index"
(click)="changeState(i)"
[ngClass]="clickedIndex === i ? 'primary' : 'secondary'">
{{categoria.nombre}}
</div>
Component
changeState(index) {
this.clickedIndex = index;
}

ionic how to identify clicked button in a *ngFor loop

I am creating a list of text and buttons.
I want to identify which button has been clicked in the clicked function.
HTML
<ion-list>
<ion-item ion-item *ngFor="let act of questions.test">
{{act.quote}}
<ion-item>
<button large ion-button item-right (click)="SelectClicked()">Select</button>
</ion-item>
</ion-item>
</ion-list>
TS
this.questions =
{
"test":[
{
"quote": "first row"
}, {
"quote": "second row"
}, {
"quote": "third row"
}, {
"quote": "fourth row"
}
]
}
SelectClicked(detail){
//please help
// which button was clicked ( 1 to 4 ) ?
console.log("SelectClicked" + detail);
}
I am guessing that you want the selected element, that can be done by passing on the event to the handler.
<button (click)="SelectClicked($event)"></button>
Which you can fetch the element from the event with using event.target, event.srcElement or event.currentTarget.
But if you mean to pass along the index or the item of your array, you can just pass on that act object or add an index to the loop...
<ion-item ion-item *ngFor="let act of questions.test; let i = index">
...and pass on the object...
<button (click)="SelectClicked(act)"></button>
...or the id
<button (click)="SelectClicked(i)"></button>
You can pass the "act" value as a parameter to the function like this
<button large ion-button item-right
(click)="SelectClicked(act)">Select
</button>

Ionic: Differentiate between clicking on the list-item and on a button in the list-item

I have created a list with items each containing a button in the right. I have written two different functions, one for handling click directly on the item and one for the button at right.
The problem is clicking on the button result in calling both of the functions.
How can I edit the .html (or if not possible, then .js) so that clicking on the item (excluding the button area) will call a function and clicking on the right button will call another function.
CodePen Link
HTML:
<ion-list>
<ion-item ng-repeat='item in list' class='list-group-item'
item="item"
ng-click="clicker(item)" >
<a class="item item-button-right">
<h2>Item {{item.id}}</h2>
<div class="buttons">
<button class="button button-assertive" ng-click="onRemoveClick(item)">
<i class="icon icon ion-close"></i>
</button>
</div>
</a>
</ion-item>
</ion-list>
AngularJS:
angular.module('ionicApp', ['ionic'])
.controller('list_controller', function($scope) {
$scope.clicker = function(item){
alert('Item Clicked: '+item.id)
};
$scope.onRemoveClick = function(item){
alert('Remove Clicked: '+item.id)
};
$scope.list = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 }
];
});
You can by using stopPropagation. Example below
View
ng-click="onRemoveClick(item, $event);"
Js
$scope.onRemoveClick = function (item, $event) {
$event.stopPropagation();
}