Blocking navigation with preventDefault() doesn't work on angularjs $locationChangeStart - javascript

I am trying to block user to navigate to other pages when they have unsaved changes on the existing page.
I use $locationChangeStart and try to trigger a pop-up message to ask user if they really want to navigate without saving the changes.
However, the view changes before even my pop-up gets triggered.
Simply my event.preventDefault() doesn't work.
Not sure what I am doing wrong, but here is the code:
$rootScope.$on('$locationChangeStart', function (event) {
var path = $location.path();
if (self.editCableMode || self.editBinMode) {
SweetAlert.swal({
title: 'Still Editing',
text: 'You have unsaved changes. Are you sure you want to leave?',
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#F8BB86',
confirmButtonText: 'Yes'
}, function (isConfirm) {
if (isConfirm) {
console.log(isConfirm)
self.editCableMode = false;
self.editBinMode = false;
}else{
console.log(isConfirm)
event.preventDefault();
}
});
}
});

Related

Electron app close dialog with message box confirmation

I use Electron v13.0.1 from this repo
Need close confirmation, use this implementation:
win.on('close', function (e) {
require('electron').dialog.showMessageBox(this, {
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
}).then(function (data) {
if (data.response === 0) {
e.preventDefault();
}
});
});
But when I click on the close button dialog appeared on second and the application close without any confirmation or rejection. In other words, the dialog does not create conjunction for close.
What is the problem with my solution?
The problem is that you are calling an asynchronous method and the event function continues execution and eventually returns, before any user input is given.
One way to solve this is to use the showMessageBoxSync function for synchronous operation. This will wait until user selects an option before continuing execution. Like below:
const { dialog } = require('electron');
win.on('close', function (e) {
let response = dialog.showMessageBoxSync(this, {
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
});
if(response == 1) e.preventDefault();
});

Error when moving an item in a drag and drop list

I am working on a drag and drop list, I need that every time you try to move an item on the list ask if you really want to move it, if so, make the move, if not, return it to its initial position.
function handleDragEnd(e) {
swal({
title: "Are you sure?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#f8c286",
confirmButtonText: "Accept",
cancelButtonText: "Cancel",
html: true
},
function(isConfirm){
if (isConfirm) {
e.target.classList.remove('over');
var start = $("#"+e.target.id).prev().attr('id');
var end = $("#"+e.target.id).next().attr('id');
Calculate(start,e.target.id,end,data);
swal("Successfull","change made", "success");
} else {
this.ondragexit;
}
});
But I have errors in both cases, when it's affirmative, I get error in the remove
And when I don't want to move it, he lets me do it anyway.
How can it be corrected to work properly?
Could you help me, please?

Uncaught SweetAlert: Unexpected 2nd argument?

I have a problem with sweetalert, I would like to show the confirm box alert on button click but it's not working
This is my JS code:
$(document).ready(function(){
$('[data-confirm]').on('click', function(e){
e.preventDefault(); //cancel default action
//Recuperate href value
var href = $(this).attr('href');
var message = $(this).data('confirm');
//pop up
swal({
title: "Are you sure ??",
text: message,
type: "warning",
showCancelButton: true,
cancelButtonText: "Cancel",
confirmButtonText: "confirm",
confirmButtonColor: "#DD6B55"},
function(isConfirm){
if(isConfirm) {
//if user clicks on "confirm",
//redirect user on delete page
window.location.href = href;
}
});
});
});
HTML:
<a data-confirm='Are you sure you want to delete this post ?'
href="deletePost.php?id=<?= $Post->id ?>"><i class="fa fa-trash">
</i> Delete</a>
All required files are imported.
The code you are using is from prior the latest version 2. Please read up on Upgrading from 1.X.
You should use promise to keep track of user interaction.
Updated code
$(document).ready(function(){
$('[data-confirm]').on('click', function(e){
e.preventDefault(); //cancel default action
//Recuperate href value
var href = $(this).attr('href');
var message = $(this).data('confirm');
//pop up
swal({
title: "Are you sure ??",
text: message,
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
swal("Poof! Your imaginary file has been deleted!", {
icon: "success",
});
window.location.href = href;
} else {
swal("Your imaginary file is safe!");
}
});
});
});
Notes
type have been replaced with icon option.
Replaced showCancelButton, CancelbuttonText, confirmButtonText and confirmButtonColor with only buttons.
dangerMode: true to make the confirm button red.

Wait on SweetAlert response

I currently have a function that asks the user for confirmation when changing a value in a dropdown. This works fine using the standard JavaScript confirm(). Here's the fiddle.
var prev_val;
$('#dropdownId').focus(function () {
prev_val = $(this).val();
}).change(function () {
$(this).blur();
var success = confirm('Are you sure you want to change the Dropdown?');
if (success) {
// Proceed as normal.
} else {
// Reset the value & stop normal event
$(this).val(prev_val);
return false;
}
});
But when using SweetAlert, the change event always takes place before I'm able to confirm/cancel. Meaning, when I select a new value, and pressing "cancel", it does not stop the event and reset the previous value. Which it does with the regular JavaScript confirm dialog.
var prev_val;
$('#' + dropdownId).focus(function () {
prev_val = $(this).val();
}).change(function (e) {
$(this).blur();
return swal({
title: "Are you sure?",
text: "Do you want to change the dropdown?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes",
cancelButtonText: "No",
closeOnConfirm: true,
closeOnCancel: true
},
function (isConfirm) {
if (isConfirm) {
e.preventDefault();
return true;
} else {
$(this).val(prev_val);
return false;
}
});
});
It might also be interesting to note that this JavaScript might even be invalid (pretty new to JavaScript), e.g. returning from the confirm function and from the swal function not functioning.
However, after Googling around, I found people with similar issues.
how-to-use-confirm-using-sweet-alert
how-to-run-a-sweetalert-instead-of-default-javascript-confirm-method
But that seems a bit hacky since it's preventing any action, but when selecting confirm he re-creates the function that should have been called by default. Which seems like quite a hack for something so simple.
Any possibility of the SweetAlert just acting like a regular confirm dialog?
The value does not get set back because this in swal is not the select, but the sweet alert dialog. So in your change event you have to define a variable that holds the changed select element and use it to set the value back when the user clicks 'No'.
.change(function(e) {
var select = this; // save select element to variable
$(this).blur();
return swal({
title: "Are you sure?",
text: "Do you want to change the dropdown?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes",
cancelButtonText: "No",
closeOnConfirm: true,
closeOnCancel: true
},
function(isConfirm) {
if (isConfirm) {
e.preventDefault();
return true;
} else {
$(select).val(prev_val); // use select reference to reset value
return false;
}
});
});
You can find a working example in this fiddle.
var prev_val;
$('#' + dropdownId).focus(function() {
prev_val = $(this).val();
}).change(function(e) {
$(this).blur();
var self = this;
return swal({
title: "Are you sure?",
text: "Do you want to change the dropdown?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes",
cancelButtonText: "No",
closeOnConfirm: true,
closeOnCancel: true
},
function(isConfirm) {
if (isConfirm) {
// preventDefault is useless since change event has already happened
// if Confirm is true then do nothing else
// change with prev val
//e.preventDefault();
return true;
} else {
// this here does not refer the dom element
// it might be changed because it is called through the swal library code at a later time, use self which is declared out of the callback context.
$(self).val(prev_val);
return false;
}
});
});

Bootstrap 3 tabs preventDefault

I am trying to build what seems to be simple jquery script. Once form input has been changed and user wants to leave page without saving, he will be prompted to confirm leaving. Everything works ok on regular anchors, but I can't get event.preventDefault working on Bootstrap 3 tabs. Any ideas? Thank you.
My current (beta) script:
//Confirm on exit when form has changed
var show_exit_error = 1;
$("form.check-on-exit").one("change", ":input", function() {
show_exit_error = 1;
$(document).on('click', 'a', function(e) {
if (show_exit_error == 1) {
$link = $(this);
e.preventDefault();
swal({
title: "Do you really want to leave?",
text: "",
type: "warning",
showCancelButton: true,
cancelButtonText: "Leave",
confirmButtonColor: "#18a689",
confirmButtonText: "No",
closeOnConfirm: true,
closeOnCancel: true,
}, function(isConfirm){
if(!isConfirm) {
show_exit_error = 0;
window.location = $link.attr('href');
}
});
}
});
Demo: http://codepen.io/anon/pen/bdzyRy?editors=101
Try to edit one of inputs and then switch to tab2. It ignores prevetndefault and switch tab. I need script to switch tab only if user click on No.
Here is simple workaround:
//Confirm on exit when form has changed
var show_exit_error = 1;
$("form.check-on-exit").one("change", ":input", function() {
show_exit_error = 1;
$('.tabs-container').find('a[data-toggle="tab"]').attr('data-toggle', 'notab');
$(document).on('click', 'a', function(e) {
if (show_exit_error == 1) {
$link = $(this);
e.preventDefault();
swal({
title: "Do you really want to leave?",
text: "",
type: "warning",
showCancelButton: true,
cancelButtonText: "Leave",
confirmButtonColor: "#18a689",
confirmButtonText: "No",
closeOnConfirm: true,
closeOnCancel: true,
}, function(isConfirm){
if(!isConfirm) {
show_exit_error = 0;
if ($link.attr('data-toggle') == 'notab') {
$('.tabs-container').find('a[data-toggle="notab"]').attr('data-toggle', 'tab');
$link.trigger('click');
} else {
window.location = $link.attr('href');
}
}
});
}
});
I assume the tabs you're referring to are anchors to external documents. Since you leave the page at that moment, it would last to remove the Bootstrap click handler completely.
$(function() {
// remove the click.bs.tab.data-api handler from all tabs with class .external-tabs
$('.external-tabs').off('click.bs.tab.data-api');
});
As an alternate solution you could just remove the data-toggle="tab" attribute from the item, since this is the selector for adding the handler in Bootstrap.

Categories