I have a function that asks users for confirmation when selecting a value from a Select dropdown. When using the regular JavaScript confirm(), the change event does not get the newly selected value without clicking on confirm. This can be seen in this Fiddle.
When a value is selected, and the user clicks cancel, the same value is shown in an alert dialog. When the user clicks confirm, the newly selected value is displayed.
However, I'd like to use SweetAlert. When changing the value with SweetAlert, the change happens without even selecting confirm or cancel. As demonstrated in this Fiddle. When a value is selected, an alert dialog is displayed right after selection, unlike with the pure JS Confirm() which blocks the event somehow.
I'd like to achieve the same effect as the JS confirm(), where the change event is not triggered while the user has not clicked confirm or cancel, when using SweetAlert.
Aside from both Fiddles which demonstrate the problem, here's the code I'm using:
Some simple HTML select:
<select id="dropdownId">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
The JavaScript confirm() version (which does what it needs to do):
var prev_val;
$('#dropdownId').focus(function () {
prev_val = $(this).val();
}).change(function (e) {
var select = this;
$(this).blur();
var success = confirm('Are you sure you want to change the Dropdown?');
if (success) {
// Other changed code would be here...
} else {
$(this).val(prev_val);
return false;
}
});
$('#dropdownId').change(function (e) {
alert($(this).val());
});
And the SweetAlert version, where the change event should wait on the response of the SweetAlert dialog.
var prev_val;
$('#dropdownId').focus(function () {
prev_val = $(this).val();
}).change(function (e) {
var select = this;
$(this).blur();
return swal({
title: "Are you sure?",
text: "Change dropdown select?",
type: "warning",
showCancelButton: true,
confirmButtonText: "Yes!",
cancelButtonText: "No!",
closeOnConfirm: true,
closeOnCancel: true
},
function (isConfirm) {
if (isConfirm) {
return true;
} else {
$(select).val(prev_val);
return false;
}
});
});
$('#dropdownId').change(function (e) {
alert($(this).val());
});
Edit:
Moving the logic to the confirm handler of the dialog does not solve this issue. I'm using a framework (Apache Tapestry) which listens for a change event on the select. When using the solution as RRR stated, in this fiddle, the change event still happens. Which still causes it to fire an event to my backend, unlike with the JS confirm() which does not change the value until confirm was clicked.
Edit 2:
My problem doesn't really seem to be that clear. Here are the steps I undertake to try and show what the root of the problem is:
When using the JS confirm from this fiddle. The following happens:
I click on a value
It asks for confirmation
On confirm, it logs the new value. On cancel, it logs the original value.
When using the SweetAlert dialog, using this fiddle. The following happens:
I click on a value
It logs the newly selected value, before confirming/cancelling
On confirm/cancel I can execute logic.
When using the SweetAlert dialog, as edited by RRR in this fiddle. The following happens:
I click on a value
It logs the newly selected value, before confirming/cancelling
On confirm/cancel, it shows an alert
Both my and RRR's SweetAlert example have the same issue. Namely, step 2. Not the fact that it logs, but the fact that the value actually changes. Unlike in the first pure JS example, where the value does NOT change unless confirm is clicked.
Ok. Here is the issue.
You call 2 different actions at onchange event:
1- The big function...
2- A test alert.
Both occur at the same time. <-- Here lies the confusion!
This is why it appeared to you that swal doesn't "wait" to get an answer from the user.
Try this... And look at your console.log messages:
var prev_val;
$('#dropdownId').focus(function () {
prev_val = $(this).val();
console.log("On focus event value : "+prev_val); // ADDED
}).change(function (e) {
var select = this;
console.log("At the BEGINNING of the change event : "+$(select).val()); // ADDED
$(this).blur();
swal({ // REMOVED return in front of it
title: "Are you sure?",
text: "Change dropdown select?",
type: "warning",
showCancelButton: true,
confirmButtonText: "Yes!",
cancelButtonText: "No!",
closeOnConfirm: true, // These are default.. useless to specify
closeOnCancel: true // These are default.. useless to specify
},
function (isConfirm) {
if (isConfirm) {
//return true; // no need to return anything - commented out
console.log("swal YES");
console.log("At the END of the change event : "+$(select).val());
} else {
$(select).val(prev_val);
//return false; // no need to return anything - commented out
console.log("swal NO");
console.log("At the END of the change event : "+$(select).val());
}
// Here is a callback final test alert!
alert("Callback alert: "+$(select).val());
});
});
/*$('#dropdownId').change(function (e) { // This was a bad idea ! ;)
alert($(this).val());
});*/
In my case sweet alert 2 was blocking my binded event handlers:
Swal.fire( // Not works - Nothing will happen onclick
{html: `<button id="btn1" onclick="alert('clicked')">Delete</button>`,
)
So i binded the event handlers in javascript instead, on modal open:
Swal.fire(
{html: `<button id="btn1">Delete</button>`,
onOpen: () => {document.querySelector('#btn1').onclick = () => {alert('clicked')}
)
Related
My HTML/Javascript app uses a modal popup which I created using sweet Alert 2. Let's call this "Alert1".
Alert1 is using custom HTML and there is a button inside that HTML which I want to trigger another sweet alert 2 modal popup, we'll call this one "Alert2".
Alert2 has two options. "confirm" or "cancel" If the user clicks "cancel" I want to return to Alert1.
Here is the catch: The custom HTML for Alert1 is editable therefore, I can't just re-invoke the code that originally launched the alert, because this would show the old HTML.
This is what I have tried:
function clickButton(){ //This function will be attached to the button in Alert1
var currentSwal = document.getElementById('swal2-content').innerHTML;
swal({
title: "Confirm 'Remove Script Page'",
text:
"Are you sure you want to remove this page from the script?",
type: "warning",
showConfirmButton: true,
showCancelButton: true
}).then(function(dismiss) {
if (dismiss.dismiss == "cancel" || dismiss.dismiss == 'overlay') {
swal.close;
swal({
html: currentSwal,
showConfirmButton: false,
customClass: 'swal-extra-wide',
showCloseButton: true
});
} //end if
else {
//go ahead and delete the script page
} //end else
});
}//end function
My above solution does not work. It is a bit hard to explain, but basically, the HTML code gets broken and things just don't work properly.
TLDR/My question: Is there a way to have multiple SweetAlert2 alerts? (i.e. launch alert2 from alert1 and then close alert2, returning the view to alert1?
Yes you can ,
var modals = [];
modals.push({title: 'title Of Modal1', text: 'text1' });
modals.push({title: 'title Of Modal2', text: 'text2' });
swal.queue(modals);
References
Question 38085851 Answer 1
make a for loop for 3 and use toast not sweet alert and it will be works
I'm using an editing mechanism similar to the example Grid Batch Editing, but my buttons look at lot different.
Because of this difference it would make a lot of sense to have the save changes and cancel button disabled changes are made and then when you press the save or cancel button they should disable again. How do I achieve this?
Managed to answer my own question here.
Function for changing the buttons state:
function changeSaveAndCancelButtonState(enable) {
$(".k-grid-save-changes").kendoButton({ enable: false })
.data("kendoButton").enable(enable);
$(".k-grid-cancel-changes").kendoButton({ enable: false })
.data("kendoButton").enable(enable);
}
To enable buttons when you edit data (regular cell):
#(Html.Kendo().Grid<DeuarTestValue>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Sample).Editable("enabledRegularEdit");
})
// Insert code for data source etc etc
);
function enabledRegularEdit() {
changeSaveAndCancelButtonState(true);
// return true to indicate that this the cell can be edited
return true;
}
To disable the buttons by default and on click:
function disableSaveAndCancelButtonState() {
changeSaveAndCancelButtonState(false);
}
// Disable themselves on-click
var but = $(".k-grid-save-changes").kendoButton({ click: disableSaveAndCancelButtonState });
var but = $(".k-grid-cancel-changes").kendoButton({ click: disableSaveAndCancelButtonState });
// And Disable them by default.
changeSaveAndCancelButtonState(false);
Note: This doesn't take into consideration whether the cell was actually edited, simply that the cell was taken into edit mode. If anybody knows how to make it work only when edits are properly made?
Since the picture in the post has check boxes, they need to be handled a little bit differently because they aren't edited via the standard Editable function.
To enable buttons when you edit data (checkbox's):
columns.Bound(c => c.Approved)
.ClientTemplate("<input type='checkbox' #= Approved ? checked='checked' : '' # class='Approvedchkbx'/>")
.Editable("disableEdit");
function disableEdit() {
return false;
}
$("#grid .k-grid-content").on("change", ".Approvedchkbx", function (e) {
var grid = $("#grid").data("kendoGrid"),
dataItem = grid.dataItem($(e.target).closest("tr"));
changeSaveAndCancelButtonState(true);
dataItem.set("Approved", this.checked);
});
You can disable the button right after its click and make sure they get enabled back on when your job is done.
$('#your-button').on('click', function (e) {
e.preventDefault();
$(this).prop('disabled', true);
//Do your work
//Once everything is done
$(this).prop('disabled', false);
})
I'm using jQuery UI to present a dialogue box asking, "Do you really want to perform this action?" when a user clicks on a hyperlink or a form button.
If the user clicks "Confirm" then I want to perform the original default action.
Here is my code:
[html]
Click me
[jquery]
// Global variable keeps track of whether the user has clicked confirm
var confirmed = false;
$("a").on("click", function(e) {
var self = $(this);
var options = {
autoOpen: true,
modal: true,
title: "Confirmation Required",
buttons : {
"Confirm" : function() {
// The user has confirmed, so set global variable to true
confirmed = true;
// Re-trigger the click
self.trigger("click");
},
"Cancel" : function() {
$(this).dialog("close");
}
}
};
// If the user hasn't yet confirmed, display the dialogue box
if (confirmed == false) {
$("<div />").text("Are you sure you want to do this?").dialog(options);
// Prevent the default action
e.preventDefault();
}
// Otherwise the user has confirmed, so don't preventDefault and return true
else {
confirmed = false;
// Alert here to check we reached this point
alert("Returning true");
return true;
}
});
When first clicking the link, the default action is prevented and the dialogue box opens.
When clicking "Confirm" in the dialogue box, the click event is triggered again, and the alert box fires saying, "Returning true". All good so far, however the page doesn't load. So for some reason second time around the default event is still prevented and I can't for the life of me figure out why.
This is most likely due to the fact the dialog is still open. However even if you close it, you will not be able to click the a element like this.
trigger('click') only triggers the function which is bond to the click event in jQuery and if you would use $el.click(), I think it only supports format <a onclick="func()">Click here</a>
How I solved this; On the dialog confirmation I update the window location with jQuery based on the <a> elements href.
Please see working snippet below;
Click me
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var confirmed = false;
$("a").on("click", function(event) {
var $self = $(this);
if (!confirmed) {
event.preventDefault();
$("<div />").text("Are you sure you want to do this?").dialog({
autoOpen: true,
modal: true,
title: "Confirmation Required",
buttons : {
"Confirm" : function() {
window.location.href = $self.attr('href');
},
"Cancel" : function() {
$(this).dialog("close");
}
}
});
}
});
});
</script>
I have to allow only alphabets to the text box. I have validated through JavaScript on text box using "on blur". The alert from the JavaScript remains open even though I try to close.
Find the demo link and the JavaScript below.
Note: Type any non-alphabet in the text box 1 and press tab or click on somewhere else from the following link.
http://demo.acclary.com/test.aspx
The JavaScript I used is, below:
function checkalphabets(textbox) {
var pattern = /^[a-zA-Z\s]+$/;
if (!pattern.test(textbox.value)) {
modal({
type: 'warning',
title: 'Warning',
text: 'Only Alphabets allowed!',
center: false,
});
setTimeout(function () { textbox.focus(); }, 1);
exit;
return false;
}
return true;
}
$('.modal-btn').click(function() {
$('#modal-window').hide();
});
You just need to add following line of code in the modal function:
callback: function(){ $("#myTextBox").focus();}
So After change, it will be like
modal({
type: 'warning',
title: 'Warning',
text: 'Only Alphabets allowed!',
center: false,
callback: function(){ $("#myTextBox").focus();}
});
That's all.
I have created fiddle using the Modal plugin that you are using in the page.
http://jsfiddle.net/7kpsv1p4/1/
change on-blur to onchange
small changes in your code
function checkalphabets(textbox) {
var pattern = /^[a-zA-Z\s]+$/;
if (!pattern.test(textbox.value)) {
textbox.focus();
modal({
type: 'warning',
title: 'Warning',
text: 'Only Alphabets allowed!',
center: false,
});
return false;
}
return true;
}
I hope this will work.
If you use onblur and focus on the textbox together the alert box will always show in the screen, because after focusing the textbox you are closing the modal alert means that you are re-belurring the textbox.
So it's better to use :
the onchange event.
Or the onKeyup event.
Note: Using the onkeyup is a better approach to refocus the textbox safely.
And try to focus on the textbox right before showing the alert, so when you close the alert the textbox will be already focused.
EDIT:
Here's a DEMO Fiddle using the onkeyup event but a simple alert, and here's the code:
function checkalphabets(textbox) {
var pattern = /^[a-zA-Z\s]+$/;
if (!pattern.test(textbox.value)) {
setTimeout(function () { textbox.focus(); }, 1);
alert('This is wrong');
exit;
return false;
}
return true;
}
It fires whenever you type a wrong character and still focuses in teh textbox.
For some reason jQuery.off('click') doesn't seem to be working here. When the 'Yes' button is clicked in the model another model just pops up. What am I doing wrong?
code:
$(function(){
//If there are warnings on the page bind alert
if ($('.renewal-warning').length > 0){
(function (){
$('#signRentalContainer').on('click', '.renewal-warning', function(e){
var buttonHandle = this;
//Prevent submission
e.preventDefault();
//Show warning model
$.modal({
content: $('#renewalWarning').html(),
title: "Order Renewal Warning",
buttons: {
'Yes': function(win) { $(buttonHandle).off('click').click(); },
'No': function(win) { win.closeModal(); }
},
maxWidth: 250,
closeButton: false
});
});
})();
}
});
Pretty sure you're going to need to provide it the same element, as well as the same selector.
$('#signRentalContainer').off('click', '.renewal-warning');
In the .on() handler, this is the '.renewal-warning' element that was clicked, not the #signRentalContainer element.
If there are several of these '.renewal-warning' elements, and you only want to disable one at a time, the simplest way is to change its class so that it no longer matches the selector.
$(this).removeClass('renewal-warning')
.addClass('renewal-warning-disabled');
Because the this refer to the context of the handle function, not the function itself.
Try making it a named function, then refer to it when you call off:
$("body").off("click", '#signRentalContainer', buttonHandle);
BTW, any reason we can't use unbind directly here?
$("#signRentalContainer").unbind("click");