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?
Related
I am trying to create a sweetAlert2 function where I want to fire a loading screen. And during the loading screen, I want to execute some functions, which can take some time. Afterward I want to display a fire success or error, depending on what the return will be. I tried several methods:
Swal.fire({
title: 'Auto close alert!',
html: 'In progress',
timerProgressBar: true,
didOpen: () => {
try {
Swal.showLoading();
call other functions..
if success show
Swal.fire({
icon: 'success',
title: 'Success...',
html: message
});
or else fire error
catch(err){
etc.
}
}
)};
Now when I execute the function it waits a few seconds (executing functions) and then it shows the success or error fire, but it doesn't show the in-progress loading dialog first. Any idea how to get this?
Fixed it by using setTimouts and promises:
//Start
Swal.fire({
title: 'In progress',
html: 'Please wait while your action is being carried out.',
timerProgressBar: true,
didOpen: () => {
//here it will open the in progress box
Swal.showLoading();
//setTimeout with 1000 or more ms is needed in order to show the inprogress box
setTimeout(async () => {
let currentRecID = currentRecord.get().id;
//load complete record
currentRec = record.load({
type: record.Type.OPPORTUNITY,
id: currentRecID,
isDynamic: true
});
const promiseVar = () =>
new Promise((resolve, reject) => {
resolve(canCreateORD(currentRec));
});
canORDbeCreated = await promiseVar();
//Automatically close popup so it continues with willClose
Swal.close();
}, 1000);
},
willClose: () => {
//Show success / error box with Swal.fire
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');
}
})
}
)
I need to open SweetAlert with a loading, execute a JS function "myFunc()" and close SweetAlert.
I invoke SweetAlert with a loading:
Swal.fire ({
title: 'Wait ...',
onBeforeOpen: () => {
Swal.showLoading ()
}
})
Where should I put myFunc () in the code?
My thought would be that there isn't really any reason to include your function in the SweetAlertOptions object. Since you're only using SweetAlert2 to show a loading dialog while your function executes, and not getting any user input from it, you can just treat it in a procedural manner:
Swal.fire({
title: 'Wait ...',
onBeforeOpen () {
Swal.showLoading ()
},
onAfterClose () {
Swal.hideLoading()
},
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false
})
myFunc()
Swal.close()
If you're using async/await don't await the initial Swal.fire(). You don't care about the result anyway.
If myFunc() is asynchronous (which it should be in order to not lock the UI thread during loading), await it and then close, or close in the resolution of the promise
await myFunc()
Swal.close()
OR
myFunc().then(result => {
Swal.close()
})
Alternatively, you could call myFunc and Swal.close() in the OnOpen function:
Swal.fire({
...
onOpen () {
myFunc()
Swal.close()
}
...
})
Swal.fire({
...
async onOpen () {
await myFunc()
Swal.close()
},
...
})
Swal.fire({
...
onOpen () {
myFunc().then(result => {
Swal.close()
})
}
...
})
if you use the modal of steps, you can use willOpen option with arrow function
await Queue.fire({
title: titulo,
html : html,
willOpen:()=>{
operations///
}
})
},
currentProgressStep: 0,
// optional class to show fade-in backdrop animation which was disabled in Queue mixin
showClass: { backdrop: 'swal2-noanimation' },
})
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();
});
I have a SweetAlert2 that allows text input, and I give it a default value. I'd like this default value to be highlighted when the alert pops up, so that the user can immediately overwrite it if needed. Here's an example:
And here is the function that I call with the sweetAlert options:
window.sweetPrompt = function (title, message, callback, input, keepopen, allowOutsideClick, allowEscapeKey) {
sweetAlert({
title: title,
text: message,
input: 'text',
confirmButtonColor: "#428bca",
preConfirm: function(text) {
return new Promise(function(resolve) {
if (!keepopen) {
resolve();
} else {
callback(text);
}
});
},
inputValidator: function(text) {
return new Promise(function (resolve, reject) {
if (text) {
resolve();
} else {
reject('Cannot be empty!');
}
});
},
inputValue: input,
showCancelButton: true,
reverseButtons: true,
allowOutsideClick: allowOutsideClick,
allowEscapeKey: allowEscapeKey
}).then(callback, function(dismiss){});
};
How would I go about doing this (if it's possible) ? I thought about using jQuery but I'm not sure how to get the reference to the sweetAlert dialogue.
Any suggestions would be appreciated.
Here you go:
Swal.fire({
input: 'text',
inputValue: 'input value',
didOpen: () => {
Swal.getInput().select()
}
})
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#11"></script>
PS. Please note that SweetAlert2 and SweetAlert are two different projects with slight differences in API.
SweetAlert2 documentation: https://sweetalert2.github.io/