Prevent Multiple Submissions with JQuery Prompt Save Button - javascript

I have a save button that triggers a jquery prompt (click the save button, and then I prompt the user: "Are you sure you want to save updates?" The problem is that a user can click the prompt multiple times, causing the same data to save multiple times. How can I disable the prompt save button on the first click?
I am using knockout js. Here is the code in my viewmodel:
$.prompt("Are you sure you want to save? You will not be able to change your decision after it's been saved.", {
title: "Save?",
buttons: { "Save": true, "Cancel": false },
submit: function (e, v, m, f) {
if (v) {
e.disabled = true;
response = saveUpdates(LoanDetails);
}
}
}
});

You can disable the button after saving data for the first time. You can use different jquery selector for your button.
$('button[type=submit], input[type=submit]').attr('disabled',true);

Try disabling the button itself when you do the save. Then the button
wont be clickable and you wont get the prompt.

If you want to disable a button using jQuery, you should have a look at $('#elem').prop(property,value), which will allow you to do something like this...
$("input").prop("disabled",true);

Related

Semantic-UI avoid form validation trigger for some button click events

So by default Semantic-ui doesn't have any way to prevent clicks which trigger the validation, once the form has been setup, as the validation is handled onsubmit directly. This is important if you have multiple buttons on the page and only want some to trigger the validation and the rest perhaps to be able to postback, or do other things minus triggering the form validation.
I checked some answers that talk about changing the input from a type=submit to a type=button, but you lose the design ability especially the ability to add an icon and is not the ideal solution.
Am posting this question, since my answer to this question, got deleted by the moderator, even though I have a working fiddle and a detailed answer on how to achieve this.
Reposting the entire answer here, incase anyone needs help on this.
I was able to implement this in a different way, as the button type=button control while ignoring the validations, did not submit, and if I did submit manually the default event handler of semanticui would intervene and show the validation errors.
My use case two buttons, one a save draft and the other a finalize (final save). The first one had to save the data as is, without triggering the validations, while the other would trigger validations and then save.
I am also implementing all the validators using data attributes that I custom implemented for this project, hence the form validator is inside a JS file.
In my form validation's failure method, I included a delegate function which I could set on my page and depending on which button clicked it, then be able to return true or false.
My form validator inside a JS file
$('.ui.form').form({
inline: true,
on: 'submit',
fields: formFields,
transition: 'fade',
keyboardShortcuts: false,
onFailure: function () {
var returnValue = false; //Default to false, since validations failed
//If the delegate is present, fire it to evaluate
if (typeof window.delegValidate == 'function') {
returnValue = window.delegValidate();
}
//Ignore the toast if the delegate evaluated to TRUE
if (!returnValue) {
$('body')
.toast({
title: 'Unable to save',
message: 'Please enter all required field data before saving.',
classProgress: 'red',
showProgress: 'top',
progressUp: true,
position: 'bottom right',
showIcon: 'red exclamation triangle'
});
}
return returnValue; // false is required if you don't want to let it submit
}
});
and on my page I attached a function to the window, since my form validation is inside a JS file.
Page function
//For all postback buttons, save the id value in a hidden field for use in the delegate
$('.postbackButton').bind('click', function (e) {
$('#ButtonClicked').val(this.id); // a hidden field on the page
});
//setting the delegate for use in the form validations
window.delegValidate = function () {
//For the save button, just ignore the validations and return true
//This in turn is invoked by the failure method of the form validation that is
//dynamically attached to the page, and hence this return value is respected
//over the false that is otherwise sent back for when we want to interrupt the page
//since there are errors normally.
if ($('#ButtonClicked').val() == 'Save')
return true;
else // if value is finalize, let it return false
return false;
}
For other pages where I don't want this functionality, I can simply not write the delegate method and the default validation fires as expected on the submit button.
Also posted here Ignore SemanticUI validation on some buttons
Hope this helps anyone looking for a better way of handling this scenario.

All buttons trigger form validation semantic ui

In my semantic UI form (<div class="ui form">) it appears every button triggers the form validation, even if it is not a submit button.
Two different kind of buttons below:
<button class="ui blue right labeled icon primary submit button">
<i class="right arrow icon"></i>
Submit
</button>
and
<button class="ui blue button">
Something Else
</button>
both of these are inside the semnatic UI form element. both trigger my validation rules (standard setup rules) :
$('.ui.form')
.form({
fields: {
example:: {
identifier: 'example',
rules: [
{
type : 'empty',
prompt : 'Please enter at least one thing'
}
]
}
}
}
)
;
Only "Solution" I could find online was creating a button like this:
<input type="button" class="ui blue button">
Test
</input>
but this doesn't put the text ("test") inside the button, also couldnt get the size of the button to be same as other ones.
Is there a way to get it to not trigger my validation? Pretty stumped on why a non submit button is doing it.
Simply define the type of the button. Default type is submit:
<Button type="button" />
Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Attributes
I was able to implement this in a different way, as the button type=button control while ignoring the validations, did not submit, and if I did submit manually the default event handler of semanticui would intervene and show the validation errors.
My use case two buttons, one a save draft and the other a finalize (final save). The first one had to save the data as is, without triggering the validations, while the other would trigger validations and then save.
I am also implementing all the validators using data attributes that I custom implemented for this project, hence the form validator is inside a JS file.
In my form validation's failure method, I included a delegate function which I could set on my page and depending on which button clicked it, then be able to return true or false.
My form validator inside a JS file
$('.ui.form').form({
inline: true,
on: 'submit',
fields: formFields,
transition: 'fade',
keyboardShortcuts: false,
onFailure: function () {
var returnValue = false; //Default to false, since validations failed
//If the delegate is present, fire it to evaluate
if (typeof window.delegValidate == 'function') {
returnValue = window.delegValidate();
}
//Ignore the toast if the delegate evaluated to TRUE
if (!returnValue) {
$('body')
.toast({
title: 'Unable to save',
message: 'Please enter all required field data before saving.',
classProgress: 'red',
showProgress: 'top',
progressUp: true,
position: 'bottom right',
showIcon: 'red exclamation triangle'
});
}
return returnValue; // false is required if you don't want to let it submit
}
});
and on my page I attached a function to the window, since my form validation is inside a JS file.
Page function
//For all postback buttons, save the id value in a hidden field for use in the delegate
$('.postbackButton').bind('click', function (e) {
$('#ButtonClicked').val(this.id); // a hidden field on the page
});
//setting the delegate for use in the form validations
window.delegValidate = function () {
//For the save button, just ignore the validations and return true
//This in turn is invoked by the failure method of the form validation that is
//dynamically attached to the page, and hence this return value is respected
//over the false that is otherwise sent back for when we want to interrupt the page
//since there are errors normally.
if ($('#ButtonClicked').val() == 'Save')
return true;
else // if value is finalize, let it return false
return false;
}
For other pages where I don't want this functionality, I can simply not write the delegate method and the default validation fires as expected on the submit button.
Hope this helps someone still looking for a way to do this. :)

How to pass button into Jquery function?

I'm using a third party jQuery library called jQquery.confirm. It provides dialogs in jQuery. Upon clicking a button of a particular class I want to use the confirm() function in order to bring up the confirmation:
$(".btn-danger").click(function(event) {
//Prevent the button from being clicked.
event.preventDefault();
$.confirm({
text: "Are you sure you want to delete that comment?",
confirm: function() {
//Code in here for button to be pressed
}
});
});
The issue I'm having is with the confirm: function(). I'd like to simply simulate clicking the button here. I've tried this but it doesn't seem to recognize the button that I need to click:
$(this).trigger("click");
I'm guessing I need to pass it as an argument somewhere?
Within the confirm handler function the scope of this will not refer to the button that was clicked. To fix this you need to store a reference to the clicked button in a variable outside of the confirm handler.
Note however that the logic you're creating will end up in a loop; you're clicking the button, showing the confirm then clicking the button again programmatically which will just show the confirm again and so on ad infinitum. I'd suggest you call a function to do what's needed in the confirm action, like this:
Try this:
$(".btn-danger").click(function(e) {
e.preventDefault();
$.confirm({
text: "Are you sure you want to delete that comment?",
confirm: function() {
actionWasConfirmed();
}
});
});
var actionWasConfirmed = function() {
console.log('do something here...');
};
HTML Code for your button:
<button class="btn-danger" >Delete</button>
And
Javascript function
$(".btn-danger").click(function(){
if(confirm("Are you sure you want to delete that comment?")){
//Code in here for button to be pressed
}
});
Every event callback function receives a reference to the event that triggered it. You are already set up to get that reference with your event argument. Through that object, you can reference the object that triggered the event (which would the button in your case). So, you could just do this:
$(".btn-danger").click(function(event) {
//Prevent the button from being clicked.
event.preventDefault();
$.confirm({
text: "Are you sure you want to delete that comment?",
confirm: function() {
event.target.trigger("click")"
}
});
});
But, as has been pointed out, a click of the button would cause another click of the button upon confirmation.
Since you just want to delete something upon confirmation, the better approach would be to just delete the entry. In other words, separate your logic. The button click should trigger the confirm and the confirmation should delete the entry, not click the button again.
$(".btn-danger").click(function(event) {
//Prevent the button from being clicked.
event.preventDefault();
$.confirm({
text: "Are you sure you want to delete that comment?",
confirm: function() {
// Delete the comment here, don't click more buttons.
}
});
});
This is an example that uses SweetAlert, which is a replacement for Javascript built-in alert popup. If you have not checked out SweetAlert before, I highly recommend you do. It also integrates very well with Bootstrap.
Here is a working example (you may want to go full-screen for the full effect). Unfortunately, you will not be able to see the actual submit working, but the code should work once you add a real action.
$("form.confirm").find("[type=submit]").click(function(e) {
var $this;
e.preventDefault();
$this = $(this);
return sweetAlert({
title: "Are you sure?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Confirm Delete",
closeOnConfirm: false
}, function() {
return $this.closest("form").submit();
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="confirm" method="POST" action"">
<button type="submit">Submit</button>
</form>
When you use $(this) you have to make sure you use it in the correct object. You can't use $(this) inside $(confirm) and expect to reference your $(".btn-danger"). Instead it will reference to $(confirm) instead of your targeted button.
Take a look at the working example bellow and ask if anything unclear.
$(".btn-danger").click(function(e) {
e.preventDefault();
// Here $(this) references the object you need clicked
var currentButton = $(this);
$.confirm({
text: "Are you sure you want to delete that comment?",
confirm: function() {
// If you used $(this) here you referenced to your $(confirm) object
// Instead of a false $(this), use the button that actually triggered this code.
currentButton.trigger('click');
}
});
});
I am not sure if this is what you wanted to do, but please consider the code above is kind of an infinite loop, because when the click is triggered, this whole code will be called again.
Therefore if you wanted to press a different button, use the full selector of it, or assign him an unique ID and select it, as bellow:
HTML code of targeted button:
<input type="button" value="Button To Be Clicked after Confirm" name="myButton" id="uniqueID_onWholePage" />
Updated jQuery code that presses on this button
$(".btn-danger").click(function(e) {
e.preventDefault();
$.confirm({
text: "Are you sure you want to delete that comment?",
confirm: function() {
$('#uniqueID_onWholePage').trigger('click');
}
});
});

How can I set a value in a jquery dialog that is defined the first time the dialog closes?

I'm simply trying to find a way to create a confirm dialog in jquery to use in place of the default confirm function in javascript. I have a confirm dialog that's used to decide if I want to proceed without a given value in a form. The whole program is here:
http://nowlin.com/testpop.php
The button code that's giving me a headache looks like this, but it may not be the button code. I'm just learning jquery:
buttons: {
'Yes': function() {
document.getElementById("clicked").value = "true";
creturn = true;
$(this).dialog('close');
},
'No': function() {
document.getElementById("clicked").value = "false";
creturn = false;
$(this).dialog('close');
}
}
This program works fine except for the confirm dialog. I've tried setting a variable that has a global scope (creturn), and a DOM element from a hidden input (clicked.value), so that when the dialog closes I can tell which button was chosen. The values both get set, but not until after the form Send button, where the onclick event is located, is hit a second time:
<button type=submit name=clicked value=true onclick='return chkreq("cfbform")'>Send</button>
The behavior is, if you enter an email address and no name, and hit the Send button, the confirm dialog pops up. If you select Yes the dialog closes, but the form isn't submitted. If you click the Send button a second time, the dialog pops up again, immediately closes on its own, and the form is submitted. Clearly I'm missing something.
Thanks for any insights.
I would switch the button from type=submit to type=button (we can also drop the return)
<button type=button name=clicked value=true onclick='chkreq("cfbform")'>Send</button>
and then use jQuery to submit the form when it passed validation.
function chkreq(fid) {
// both values are set return true
if (document.getElementById(fid).elements.namedItem("name").value.length > 0 &&
document.getElementById(fid).elements.namedItem("email").value.length > 0) {
document.getElementById("clicked").value = "true";
$('#' + fid).submit();
}
...
}
And
buttons: {
'Yes': function() {
document.getElementById("clicked").value = "true";
$('#' + fid).submit();
$(this).dialog('close');
},
'No': function() {
document.getElementById("clicked").value = "false";
creturn = false;
$(this).dialog('close');
}
}
For more info see https://api.jquery.com/submit/
The other option used on that page is binding to the submit event. With your override-able validation via the popup, I think the above code will be easier to implement.
using Submit buttons and binding click events to them and handling the click in jQuery could cause issues like your jquery gets called then the post pack gets called because of the submit.
I suggest change the type of the button from "submit" to "button" and give it a try.

JQuery JEditable - How to Add A Visible Edit Me Button?

i love this plugin but the reality is that most people won't realize at first that they can click on the text to edit.
Ideally, it would be nice to add a Button next to the text or a simple [Edit] link that the user clearly sees but never gets submitted via ajax.
Any ideas?
Just add a event to the button which clicks on the jEditable field:
<span class="jeditable">jEditable field</span>
<input type="button" class="jeditable-activate" value="Edit me!" />
And in jQuery:
$('.jeditable-activate').click(function() {
$(this).prev().click();
});
That should do it. After all, that's the same thing as the user clicking on the element.
Sam3k's comment is useful, but not perfect. It causes the edit button to reshow prior to hiding editable field/buttons. To solve this, I instead added a custom onCancel event.
First added a default to $.fn.editable.defaults for the new event (ie onCancel: {})
Then I added the following code in 2 places in jquery.jeditable.js: (1) when hitting escape, and (2) pressing cancel button.
if ($.isFunction(settings.oncancel)) { settings.oncancel.apply(self); }
That's it.
$("#emailRow span").editable(url, {
type: 'text',
cancel: 'Cancel',
submit: 'OK',
onCancel: function() {
$("#emailEditLink").show();
}
});
For "Edit" link, you can use
<a href="#" onclick="$('.editable_textarea').trigger('click');>edit</a>
You can add options to jeditable to show the submit button,
$('#editable_field).editable(url...,
{//options
type: 'text',
width: 230, /*input field width*/
style: 'display: inline-block;width:260px', /*form width including input*/
submit: '<span class="inlineEditSave"><img src="/beta/resource/images/icon/icon_save_check.png"/</span>',
...
the submit span with save icon will be appended in the jeditable form
In Jeditable 1.6.0 onblur can be a function :
} else if ($.isFunction(settings.onblur)) {
input.blur(function(e) {
settings.onblur.apply(self, [input.val(), settings]);
});
} else {
So you if you want to hide the edit when the user either clicks out of the edit area set that function as a callback, if you want to hide it only when the user presses cancel then set the onreset setting with a callback.

Categories