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.
Related
I am using this jquery repeater.
I am using custom calculations on each addition of form, say multiplying one input with another, and then making a total of multiplication results.
Problem is when we click on delete, it just hides the row but don't delete values of the item,
When we delete one more item, then it will delete the first item which was hidden and my calculation is get updated.
I check the number of class on delete of item, it does not reduce on first delete, it always reduces on the second delete,
How to completely delete the row with its values?
var _CalTotal = function () {
console.log($(".billitem_quantity").length );
//Calculate total of quantity
var total_quantity = 0;
$(".billitem_quantity").each(function(){
total_quantity += parseFloat($(this).val());
});
$('#itemquantity_total').val(total_quantity.toFixed(2));
**//Calculate total of amount**
var total_amount = 0;
$(".billitem_total").each(function(){
total_amount += parseFloat($(this).val());
});
$('#bill_total').val(total_amount.toFixed(2));
console.log('test');
}
Below is code for hide,
hide: function(deleteElement) {
Swal.fire({
title: "Are you sure to cancel this order?",
text: "You will not able to revert this",
icon: "question",
showCancelButton: true,
confirmButtonText: "Yes, delete it!",
cancelButtonText: "No, revert it!",
reverseButtons: true,
}).then(function(result) {
if (result.value) {
$(this).slideUp(deleteElement);
//I guess something is missing here to delete that item with first delete fire.
_CalTotal(); //Here i am calling calltotal function.
} else if (result.dismiss === "cancel") {
}
});
},
After some debugging I found that setting a setTimeout() of 1 second removed your issue. This means some code is asynchronously processed in the background. Therefore you need a callback function or a promise.
You can do it like this by adding to the slideUp() callback function:
hide: function(deleteElement) {
Swal.fire({
title: "Are you sure to cancel this order?",
text: "You will not able to revert this",
icon: "question",
showCancelButton: true,
confirmButtonText: "Yes, delete it!",
cancelButtonText: "No, revert it!",
reverseButtons: true,
}).then(function(result) {
if (result.value) {
$(this).slideUp(function(){
deleteElement();
_CalTotal();
);
} else if (result.dismiss === "cancel") {
}
});
},
I got the solution from this question (not the accepted answer).
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();
}
});
}
});
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.
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;
}
});
});
I have a page with table of a number of records in it
Each row has button on it I want to add an onclick event so it fires a popup message, if they ok it the page diverts to another page passing the value found in the data attribute but I cant get it to work
Jquery looks like this:
var aFeatures = document.querySelectorAll(".sweet-roll");
for (var i = 0; i < aFeatures.length; i++) {
aFeatures[i].onclick = function() {
swal({
title: "Rollback To Selected Version?",
text: "Are you sure you want to rollback to the selected version?",
type: "warning",
showCancelButton: true,
confirmButtonClass: 'btn-danger',
confirmButtonText: 'Yes, Rollback',
closeOnConfirm: false,
//closeOnCancel: false
},
function(){
window.location.href="/cms/rollback.aspx?id="+$(this).data('uuid');
});
};
}
};
So that every button with the class 'sweet-roll' gets the onclick event.
Each html row looks like this:
<a class="btn btn-app sweet-roll" data-uuid="97aaa88c-ac9f-11e4-807b-0026b9ba6b95"><i class="fa fa-reply-all"></i>Rollback</a>
But it keeps saying the value is undefined as if it cant find the data-uuid value?
Your this is referencing SweetAlert caller, but not your element. What you need to do is to save it in some variable, let's say _this
var aFeatures = document.querySelectorAll(".sweet-roll");
for (var i = 0; i < aFeatures.length; i++) {
aFeatures[i].onclick = function() {
var _this = this
swal({
title: "Rollback To Selected Version?",
text: "Are you sure you want to rollback to the selected version?",
type: "warning",
showCancelButton: true,
confirmButtonClass: 'btn-danger',
confirmButtonText: 'Yes, Rollback',
closeOnConfirm: false,
//closeOnCancel: false
},
function(){
window.location.href="/cms/rollback.aspx?id="+$(_this).data('uuid');
});
};
}
};