How to subscribe unsubscribe in angular from one button click? - html

I have a button for subscribe/unsubscribe. In case of subscribtion it calls userSubscribtions() function but what i want is when the user clicks on unsubscibe after that. It should run the delSubscription function defined in my component. And selected tab is the tab which I am viewing on my front-end.
Is there any way to do so? Below is my html code and I have those two functions in the component.
<button matRipple type="button" class="btn btn-outline-success my-sm-0 mx-2 d-flex shadow-none"
(click)="userSubscribtions(selectedTab)" [disabled]="this.loading">
<ng-container *ngIf="User.subscriptions.indexOf(selectedTab) == -1">
<span class="material-icons">notifications</span>
Subscribe
</ng-container>
<ng-container *ngIf="User.subscriptions.indexOf(selectedTab) != -1">
<span class="material-icons">notifications_off</span>
Unsubscribe
</ng-container>
</button>

You need to have a container function that should decide what to call. Modify you html like this:
<button matRipple type="button" class="btn btn-outline-success my-sm-0 mx-2 d-flex shadow-none"
(click)="handleSubscriptions(selectedTab, User.subscriptions.indexOf(selectedTab) == -1)" [disabled]="this.loading">
<ng-container *ngIf="User.subscriptions.indexOf(selectedTab) == -1">
<span class="material-icons">notifications</span>
Subscribe
</ng-container>
<ng-container *ngIf="User.subscriptions.indexOf(selectedTab) != -1">
<span class="material-icons">notifications_off</span>
Unsubscribe
</ng-container>
</button>
And then in your component file:
handleSubscriptions(selectedTab: number, isSubscribe: boolean) {
if(isSubscribe) {
// Call userSubscribtions method
} else {
// call delSubscription method
}
}

Related

Click listener on mat card with button disables button

my problem is, that i want to route to a new page as soon as i click on the grey card. But the problem is that my button on the right does not work anymore if i put the click listener on the mat-card-content, because it will also trigger getRecipe(). And if i put it into the span it only works if i have a title. How can i fix this?
<section class="recipe" *ngFor="let recipe of cookbook">
<mat-card class="recipe__card" >
<mat-card-content class="recipe__card-content" >
<span class="recipe__title" (click)="getRecipe(recipe.id)">{{recipe.title}}</span>
<button mat-icon-button [matMenuTriggerFor]="menu" class="recipe__more-btn">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>
<span>Edit</span>
</button>
<button mat-menu-item (click)="deleteRecipe(recipe.id)">
<span>Delete</span>
</button>
</mat-menu>
</mat-card-content>
</mat-card>
</section>
you can avoid this by stopping the event propagation:
<button mat-menu-item (click)="deleteRecipe(recipe.id); $event.stopPropagation()">
<span>Delete</span>
</button>
Source: Stop mouse event propagation

How to enable Item on click in Angular

I have a list of subsections in my dialog container. I'm trying make all of them disabled when the dialog is open and only enabled selected subsection when the pencil icon is click for that subsection.
For example....
when user click subsection 1 pencil icon
Subsection 1 enabled
Subsection 2 disabled
Subsection 3 disabled. ....
and process will be the same for subsection 2 and 3. Any suggestion or help will be really appreciated.
<p class="substyle">Subsections</p>
<div class="substyle" *ngFor="let subsection of section.subSections">
<mat-form-field appearance="fill">
<input matInput(ngModelChange)="nameChanged({newValue: $event,
isSection: false, id: subsection.id}
[(ngModel)]="subsection.sectionName">
</mat-form-field>
<button mat-icon-button color="primary"
(click)="editDoc(subsection)"> <mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="openConfirmDialog(subsection, false)"
*ngIf="isSubsection"><mat-icon>delete</mat-icon>
</button>
TS
// THis is called when pencil icon is click
editDoc(value) {
this.subsectionToEdit = value;
this.refreshEditor = false;
}
// Delete Subsections
this.HelpService.deleteHelpSubsection(sec.id).subscribe(() => {
const index = this.mappedSections.findIndex((value) => value.id == sec.parentId);
if (~index) {
this.mappedSections[index].subSections = this.mappedSections[index].subSections.filter((subsection) => subsection.id != sec.id)
}
})
You can try something like this
In the input bind the [disabled] attribute to a boolean, like I have below:
<p class="substyle">Subsections</p>
<div class="substyle" *ngFor="let subsection of section.subSections">
<mat-form-field appearance="fill">
<input [disabled] = "subsection.id !== selectedId" matInput style="width: 200px; height: 15px;" type="text"
(ngModelChange)="nameChanged({newValue: $event, isSection: false, id: subsection.id})"
[(ngModel)]="subsection.sectionName">
</mat-form-field>
<button mat-icon-button color="primary" matTooltip="Edit documents for this Subsection"
style="bottom: 10px;" (click)="editDoc(subsection)"> <mat-icon>edit</mat-icon>
</button>
<button mat-icon-button color="primary" matTooltip="Delete this
Subsection" (click)="openConfirmDialog(subsection, false)"
style="bottom: 10px;" *ngIf="isSubsection"><mat-icon>delete</mat-icon>
</button>
Then in your editDoc function, do the following:
editDoc(value) {
// make sure you make selectedId a property before doing this
this.selectedId = value.id // set the selectedId property to the selected value id
this.subsectionToEdit = value;
this.refreshEditor = false;
}
So what will happen is, whenever the selectedId is set, it will set all the inputs that don't belong to the selected subsection to disable automatically.

How to add validation to ngbDropdownMenu in Angular?

I have a form with couple of dropdowns which looks like this:
<form #f="ngForm" (ngSubmit)="onSubmit(f)" novalidate>
<button type="button" class="btn btn-outline-primary w-100 dropdown-toggle" id="operatorDropdown"
ngbDropdownToggle>{{operator.name ? operator.name : 'Select your operator' | translate}}</button>
<div ngbDropdownMenu aria-labelledby="dropdownExample" class="w-100 mb-3" #dropdownmenu >
<button type="button" *ngFor="let option of operators" class="dropdown-item" (click)="operator = option"
[ngClass]="{'active':operator.name === option.name}">{{option.name}}</button>
</div>
</form>
I'm having a tough time adding a simple validation to this dropdown. I want to display an error if no option is selected after pressing Submit button. Tried various validation examples on angular but none of them seems working with this kind of dropdown(without <input> etc.)
Also tried something like this, but I believe it is far from working properly.
<div *ngIf="f.controls.operatorDropdown?.errors">Error message goes here. </div>
I've managed to create the solution myself. I made that before submitting, my component would check if the operator.name is undefined(not selected). If it was, it would unhide the error message, if not it would just proceed and submit the form.
Also added the validation to (click) button event, so after the error is shown if the user chooses the operator it would validate that the operator.name is not undefined anymore and would hide the error message.
I'll share my final version, feel free to comment.
component.html
<form name="form" #f="ngForm" (ngSubmit)="onSubmit(f)" novalidate>
<div ngbDropdown [className]="!isOperatorEmpty ? 'u-mw-300p u-mw-xs-100' : 'u-mw-300p u-mw-xs-100 is-invalid'">
<button type="button" class="btn btn-outline-primary w-100 dropdown-toggle" id="operatorDropdown"
ngbDropdownToggle>{{operator.name ? operator.name : 'Select your operator' | translate}}</button>
<div ngbDropdownMenu aria-labelledby="dropdownExample" class="w-100 mb-3">
<button type="button" *ngFor="let option of operators" class="dropdown-item" (click)="operator = option;validateOperatorDropdown()"
[ngClass]="{'active':operator.name === option.name}">{{option.name}}</button>
</div>
</div>
<div class="invalid-feedback u-mw-300p u-mw-xs-100" [hidden]="!isOperatorEmpty">{{"Please select operator." | translate}}</div>
</form>
component.ts
validateOperatorDropdown() {
if (this.operator.name === undefined) {
this.isOperatorEmpty = true;
} else {
this.isOperatorEmpty = false;
}
}
onSubmit(f: FormsModule) {
this.validateOperatorDropdown()
if (!this.isOperatorEmpty) {
//continue
}
}

Don't render if array is empty - Angular *ngFor

I'm building up a Frontend with JSON Data.
I have to go trough a lot of arrays to check if a value exists inside. If the Value doesn't exist, then my complete HTML shouldn't render.
<ng-container *ngIf="document161['_source']['161_Events']">
<div class="row">
<span class="col-md-auto meta-object text-muted"><span>Begräbnistag:</span></span>
<span class="col">
<span *ngFor="let event of document161['_source']['161_Events']">
<span *ngFor="let sub of event.peventsub">
<ng-container *ngIf="sub.content === 'Begräbnis'">
<span *ngFor="let geburtsort of event.pstdatetypesub">
{{geburtsort.content}}
</span>
</ng-container>
</span>
</span>
</span>
</div>
<mat-divider class="my-2"></mat-divider>
</ng-container>
What i have already tried is:
<ng-template #thenBlock>
<ng-container *ngIf="document161['_source']['161_Events']">
<div class="row">
<span class="col-md-auto meta-object text-muted"><span>Begräbnistag:</span></span>
<span class="col">
<span *ngFor="let event of document161['_source']['161_Events']">
<span *ngFor="let sub of event.peventsub">
<ng-container *ngIf="sub.content === 'Begräbnis'">
<span *ngFor="let geburtsort of event.pstdatetypesub">
<ng-container ngIf="*ngIf="geburtsort.content; then thenBlock else elseBlock">
{{geburtsort.content}}
</ng-container>
</span>
</ng-container>
</span>
</span>
</span>
</div>
<mat-divider class="my-2"></mat-divider>
</ng-container>
</ng-template>
<ng-template #elseBlock>
</ng-template>
But as you can see there are multiple problems. Maybe Ii can't reach the ngIf condition if the value doesn't exist. And the then else logic doesn't work inside a ng-container template.
What should be the best solution?
try this
*ngIf="document161?._source?.161_Events?.length > 0"
If array having values it will show that element else will hide same.

Editable field saved to database

I've got this editable field. I need it to save the new data and store it in the database.
HTML:
<ng-container *ngIf="groupedVolumes">
<ng-container *ngFor="let model of groupKeys() | slice:-3" >
<tr>
<th class="model">{{ carValues(model)[0].model }}</th>
<ng-container *ngFor="let value of carValues(model)">
<td contenteditable='true' class="data">
{{ value.scheduledVolume }}
</td>
</ng-container>
</tr>
</ng-container>
</ng-container>
The HTML data shows the editable field.
This is the button to save with:
<div class="row">
<div class="col-auto">
<button
type="submit"
class="btn btn-success mx-1"
onclick="saveData()">Save
</button>
</div>
</div>
This is not a good approach.
Use input (probably type="text") for input using the angular form api, then you can store the new values in database on completion.