primeng confirmation service multiple calls - javascript

I am using PrimeNg with Angular 6 to generate a confirmation box on deleting an item from a form, and saving all changes made to the form. When
delete() {
this._confirmationService.confirm({
message: 'Delete Item?',
key: 'delete',
accept: () => {
// code to delete row
}
});
}
submit() {
this._confirmationService.confirm({
message: 'Save Changes',
key: 'submit',
accept: () => {
// code to save changes
}
});
}
html
<button pButton (click)="delete()"></button>
<button pButton (click)="submit()"></button>
<p-confirmDialog key="delete"></p-confirmDialog>
<p-confirmDialog key="submit"></p-confirmDialog>
When not using a key, both buttons call the submit confirm function. While using keys, the submit button calls the submit confirmation but gets stuck in a loop when accepted, and the delete function calls the submit confirmation then, if rejected, calls the delete confirmation.
What do I need to do so only the confirmation service specific to the function is called?

I had a similar issue when rejecting the confirmation dialog, I had to click like 10 times to exit the dialog.
It turns out that I was simply missing the confirmationService.close() on the reject event:
confirmDelete(index: number): void {
this.confirmationService.confirm({
message: 'Are you sure you want to delete the parameter?',
accept: () => {
this.deleteParameter(index);
},
reject: () => {
this.confirmationService.close();
}
});
}

Try this code :
HTML:
<button type="button" (click)="delete()" pButton icon="pi pi-check" label="Delete">
</button>
<button type="button" (click)="submit()" pButton icon="pi pi-times" label="Submit">
</button>
<p-confirmDialog ></p-confirmDialog>
TS:
submit() {
this.confirmationService.confirm({
message: 'Are you sure that you want to proceed?',
header: 'Confirmation',
icon: 'pi pi-exclamation-triangle',
accept: () => {
//message here
},
reject: () => {
//message here
}
});
}
delete() {
this.confirmationService.confirm({
message: 'Do you want to delete this record?',
header: 'Delete Confirmation',
icon: 'pi pi-info-circle',
accept: () => {
//message here
},
reject: () => {
//message here
}
});
}

Try this code:
HTML:
<p-confirmDialog id="deleteSelecteddomains" key="multiple" [style]="{width: '450px'}"></p-confirmDialog>
<p-confirmDialog id="deleteDomain" key="single" [style]="{width: '450px'}"></p-confirmDialog>
TS:
deleteDomain(domain: Domain) {
this.confirmationService.confirm({
message: 'Are you sure you want to delete ' + domain.name + '?',
header: 'Confirm',
icon: 'pi pi-exclamation-triangle',
key:'single',
accept: () => {
this.domains = this.domains.filter(val => val.id !== domain.id);
this.domain = {};
this.messageService.add({ severity: 'success', summary: 'Successful', detail: 'Domain Deleted', life: 3000 });
},
reject: () => {
this.confirmationService.close();
}
});
}
deleteSelectedDomains() {
this.confirmationService.confirm({
message: 'Are you sure you want to delete the selected domains?',
header: 'Confirm',
icon: 'pi pi-exclamation-triangle',
key:'multiple',
accept: () => {
this.domains = this.domains.filter(val => !this.selectedDomains.includes(val));
this.selectedDomains = null;
this.messageService.add({severity:'success', summary: 'Successful', detail: 'Domains Deleted', life: 3000});
},
reject: () => {
this.confirmationService.close();
this.messageService.add({severity:'error', summary: 'Error', detail: 'Domains Deleted Failed', life: 3000});
}
});

You should define the type on the buttons as "button" this will keep your browser from picking a type (IE generally picks the type of button, while others will pick submit). I would also suggest renaming your submit function as naming this submit may be overriding the default submit event that the submit buttons are tied to.

Related

Primeng confirm dialog show when it shouldn't

I have a method that checks if any property of object in array is equal to 'not ready'. If it is it should inform user about that and ask if he still wishes to continue. If no, there is return that breaks the method and if yes, method continues and there is one more confirm dialog
createOrder() {
if(this.orders.filter(e => e.statusName === 'not ready').length > 0){
this.confirmationService.confirm({
message: 'There is already ongoing order. Do you want start another?',
header: 'Order',
icon: 'fa fa-exclamation-triangle',
acceptLabel: 'Yes',
rejectLabel: 'No',
key: 'ongoin',
accept: () => {
},
reject: () => {
return
}
})
}
this.confirmationService.confirm({
message: 'Are you sure?',
header: 'Order',
icon: 'fa fa-exclamation-triangle',
acceptLabel: 'Yes',
rejectLabel: 'No',
key: 'confirm',
accept: () => {
*//add object code*
}
});
This how it looks like in html:
<button pButton tooltipPosition="left" (click)="createOrder()" icon="fa fa-plus-square"
class="ui-button-warning">
</button>
<p-confirmDialog key='ongoin'></p-confirmDialog>
<p-confirmDialog key='confirm'></p-confirmDialog>
My problem is that both confirm dialogs shows up at the same time. I guess it is because of using twice in html. But if i change that to
<p-confirmDialog></p-confirmDialog>
Only the first one works ('There is already ongoin...') and second one('Are you sure') after clicking yes doesn't show up. How do I make it work?
You should be calling the second dialog after the confirmation happens. Which happens in accept or reject callbacks. But you are immediately calling this.confirmationService.confirm again and it is causing both dialogs to be shown.
You should be having something like below :
createOrder() {
if(this.orders.filter(e => e.statusName === 'not ready').length > 0){
this.confirmationService.confirm({
message: 'There is already ongoing order. Do you want start another?',
header: 'Order',
icon: 'fa fa-exclamation-triangle',
acceptLabel: 'Yes',
rejectLabel: 'No',
key: 'ongoin',
accept: () => {
// do something here
this.showAnotherDialog();
},
reject: () => {
// if you want to show another dialog on reject you should call it here
return
}
})
} else {
this.showAnotherDialog();
}
}
showAnotherDialog() {
this.confirmationService.confirm({
message: 'Are you sure?',
header: 'Order',
icon: 'fa fa-exclamation-triangle',
acceptLabel: 'Yes',
rejectLabel: 'No',
key: 'confirm',
accept: () => {
*//add object code*
}
});
}

Rails ujs and remote form, How to stop form submission the programmatically submit form

I am using rails form_with as a remote form. Before submission I want to display a custom confirm box with a dynamic message. After the box is indeed confirmed I want to eventually submit the form.
I came up with 'ajax:beforeSend' event handler :
const form = document.getElementById('assign_sessions_to_employees')
form.addEventListener(
'ajax:beforeSend',
(event) => {
event.preventDefault();
swal.fire({
title: 'Are you sure ?',
text: `You are about to spend ${expectedExpenditure()} credits.`,
showCancelButton: true,
}).then((result) => {
if (result.isConfirmed) {
console.log('submitting')
Rails.fire(form, 'submit');
}
})
}
)
This works fine, however when I run Rails.fire(form, 'submit');, when I eventually want to submit the form this retriggers 'ajax:beforeSend' and I get stuck in the loop.
What would be the correct way to achieve this behavior with form_with and rails ujs ?
If you use a function declaration (aka a named function) you can remove the event handler with EventTarget.removeEventListener():
function handleConfirmation(event){
let form = event.target;
event.preventDefault();
swal.fire({
title: 'Are you sure ?',
text: `You are about to spend ${expectedExpenditure()} credits.`,
showCancelButton: true,
}).then((result) => {
if (result.isConfirmed) {
console.log('submitting');
form.removeEventListener('ajax:beforeSend', handleConfirmation);
Rails.fire(form, 'submit');
}
})
}
}
const form = document.getElementById('assign_sessions_to_employees')
form.addEventListener('ajax:beforeSend', handleConfirmation);
Another alternative is to just set a data attribute in your event handler:
const form = document.getElementById('assign_sessions_to_employees')
form.addEventListener(
'ajax:beforeSend',
(event) => {
if (event.target.dataset.confirmed) { return };
event.preventDefault();
swal.fire({
title: 'Are you sure ?',
text: `You are about to spend ${expectedExpenditure()} credits.`,
showCancelButton: true,
}).then((result) => {
if (result.isConfirmed) {
console.log('submitting');
form.dataset.confirmed = true;
Rails.fire(form, 'submit');
}
})
}
)

How to stop a function from being called when the page opens

So I have this Sweetalert2 function and it works great. Except it runs as soon as the page loads which is not what I want.
What I want is when I click on an element. I want it to be executed!
Also, I noticed that if the alert runs for the first time. It doesn't run when I click it because it ran on the first time
HTML
<i class="fas fa-search navigation__search-cart--icon"></i>
JS (SweetAlert file. From here I'm exporting the function that always gets called.)
export default sweetAlert = Swal.fire({
title: "Search...",
input: "text",
inputAttributes: {
autocapitalize: "off"
},
showCancelButton: true,
confirmButtonText: "Search",
showLoaderOnConfirm: true,
preConfirm: async val => {
try {
const response = await fetch(`//api.github.com/users/${val}`);
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
} catch (err) {
Swal.showValidationMessage(`Request failed: ${err}`);
}
},
allowOutsideClick: () => !Swal.isLoading()
}).then(result => {
if (result.value) {
Swal.fire({
title: `${result.value.login}'s avatar`,
imageUrl: result.value.avatar_url
});
}
});
JS (Where the actual click happens)
import sweetAlert from "./sweetAlert";
const search = document.querySelector(
".fas.fa-search.navigation__search-cart--icon"
);
search.addEventListener("click", sweetAlert);
What should I do to stop the function from running on page load? And how can I make it run whenever I click on the element?

Prevent going back when hardware back button is pressed in Ionic 4 App

this.platform.backButton.subscribe(()=> {
const alert = await this.alertController.create({
header: 'Confirm!',
message: 'Do you want to go back!!!',
buttons: [
{
text: 'Yes',
handler: () => {
// Previous page loaded
}
}, {
text: 'No',
handler: () => {
//Page should not go back.
//This is where i want to write code,if the user clicks
No and the back button function should be disabled.
//Only when the user presses Yes,the page will go to
previous.
}
}
]
});
})
I dont know how to handle when the user presses no,i.e.Disable the back button function or event.
Finally i solved the issue.As the event emitted from the backButton is an promise.If I dont need to go back,i just reject that promise.
this.platform.backButton.subscribe(()=> {
const alert = await this.alertController.create({
header: 'Confirm!',
message: 'Do you want to go back!!!',
buttons: [
{
text: 'Yes',
handler: () => {
// Previous page loaded
}
}, {
text: 'No',
handler: () => {
reject()
}
}
]
});
})
Try this way to prevent the back button
this.platform.backButton.subscribeWithPriority(9999, () => {
this.dismiss();
});

Stop alertCtrl auto triggering cancel in Ionic 2

I've got an alert controller that, when triggered, opens and then immediately closes without me doing anything.
let alert = this.alertCtrl.create({
title: 'Requires Login',
message: 'Please register or log in to add to cart.',
buttons: [
{
text: 'Cancel',
handler: () => {
console.log('Cancel clicked');
}
},
{
text: 'Login',
handler: () => {
this.logOut();
}
}
]
});
alert.present();
I can't find anything wrong and I'm wondering what is causing this issue? When I run the application through my phone I get the error, but when I run it through the browser, no error.
Here's a working example from my current project
logout() {
let confirm = this.alertCtrl.create({
title: 'Confirm',
message: 'Are you sure you want to logout?',
buttons: [
{
text: 'No',
handler: () => { }
},
{
text: 'Yes',
handler: () => {
this.removeNotificationRegistrationAndLogOut(LoginPage, true);
}
}
]
});
confirm.present();
}

Categories

Resources