Any idea why the once modifier doesn't work on form submitting in Svelte?
In the following example:
<form action="./" on:submit|preventDefault|once={() => alert('You submitted the form')}>
<button type="submit">Save</button>
</form>
when I submit the form first time - I see the alert, but after that, when I submit - the page refreshes - as a normal form submitting.
(I tried with the button on:click - on:click|preventDefault|once... - but got same result.)
Looks like the 'once' is working, but after running and being removed the default submit behaviour of the form seems to be active again.
Couldn't find any information if disabling this listener is possible any other way than by adding a submit listener with preventDefault.
But this way, when adding a second listener only preventing the default, you can see that 'once' is only executed once -> REPL
<script>
function submitOnce() {
console.log('this logs once')
// put logic here you want to execute once
}
function handleSubmit() {
// console.log('this logs with every submit')
// this prevents default submit behaviour
}
</script>
<form on:submit|preventDefault={handleSubmit} on:submit|once={submitOnce}>
<button>Submit</button>
</form>
can simply be replaced by on:submit|preventDefault={() => {}}
Related
Ayo,
I'm a bit struggling with functions in JS.
The idea is that after the user clicks submit button, it checks if all the required fields have been filled out and if yes, it will trigger the loading animation.
The loading animation is supposed to be a status indicator in the meanwhile of sending the form and redirection to the success page.
I tried to use the onsubmit function in the form HTML tag but that does not work. The important thing is that it will happen one if the required fields are filled out.
Thanks
JS
const submit_btn = document.querySelector('.submit-btn')
function loading() {
this.innerHTML = "<div class='loader'></div>"
}
HTML
<form
onsubmit="loading()"
action="https://formsubmit.co/2007080c2cf8bd2ebb68506e7aa98c5f"
method="POST"
enctype="multipart/form-data"
>
I tried to use the onsubmit function in the form HTML tag but that does not work.
In regards to validation:
You can use the Constrained Validation API (see MDN) to check if all fields have been filled. Usually you want to use it after the user has submitted the <form> but before the form is sent to the server.
This is achievable by using it inside an event handler that is called on submitting the form.
In regards to event handling:
To implement the mechanism described above, what you want to do is adding an event listener to the submit event of the form via .addEventListener() instead of the onsubmit attribute. This way you'll receive an event object as argument of the event handler function with which you can prevent the form submission.
Example:
const myForm = document.querySelector('form'); // or '#myform', etc...
// define the event handler function
function onFormSubmission(event) {
const fields = Array.from(event.target.elements);
const allValid = fields.every(field => field.reportValidity());
if (!allValid) {
event.preventDefault(); // stop form submission
return;
}
event.target.innerHTML = '<div class="loading"></div>';
}
// add an event listener that fires on submission
myForm.addEventListener('submit', onFormSubmission);
<form id="myform" action="path/to/backend/script.php" method="POST" enctype="multipart/formdata" novalidate>
<input type="text" name="foo" placeholder="I am required!" required>
<hr>
<button type="submit">Submit form</button>
</form>
EDIT
Sorry, I missed to add the part that displays the loading information/element. Added (although you won't really see it because if all required fields are filled, the form will be submitted which results in a page refresh. You'd need something like XHR or similiar but that's not the scope of the question).
Is it possible to keep the default HTML validation if submitting via Javascript?
What I mean is that, if I submit a form using this JS method:
document.getElementById("mc-embedded-subscribe-form").submit();
How do I keep the defualt error messages thrown by the browser?
One workaround I thought of is using this:
<form onSubmit="return somefunction()">
But because the API returns the success inside a closure function, I can't use this method.
HTML5 has also specified a JS API that you can use to interact with forms/elements in regard to their validation status: https://www.w3.org/TR/html5/forms.html#the-constraint-validation-api
So the easiest way to achieve this would be to call the checkValidity method of your form, and only submit it when this returns true.
Something like this:
function submitIfValid() {
var form = document.getElementById("mc-embedded-subscribe-form");
if(form.checkValidity()) {
form.submit();
}
else {
//
}
}
and then you would just call that function when you want to trigger form submission.
according to my understanding of your question, html validation is not enough to halt submission, you have to validate required inputs in javascript too before submitting.
e.g
if (!empty(username)) {
document.getElementById("mc-embedded-subscribe-form").submit();
}
You do not need to use form.submit() ever. Do it properly (onsubmit), or use click() on the submit button.
Doing it properly...
I can't think of a good reason to automatically submit a visible form. To submit data without user-interaction use XMLHttpRequest or WebSockets.
A form is submitted by user interaction (e.g. pressing its submit button), so there is no need to use JavaScript to submit a form. It is more likely that you need JavaScript to prevent a form submission, by returning false in the onsubmit event handler.
...or use click()
To programatically invoke HTML5 validation (and also any JavaScript onsubmit event handlers attached to the form), you can call the click() function of a submit button that belongs to the form.
If the form has no submit button, you can create a temporary one:
var form = document.getElementById("mc-embedded-subscribe-form");
var button = document.createElement('input');
button.type = 'submit';
button.style.display = 'none';
form.appendChild(button);
button.click();
Forms with multiple submit buttons should each have name attributes so the server can detect which button the user clicked. You can 'click' these buttons using form.buttonName.click().
form attribute
this solution avoids javascript, let's say that #my-btn is a button outside the form #mc-embedded-subscribe-form, you could just set on it
<button id="my-btn" type="submit" form="mc-embedded-subscribe-form">Go!</button>
requestSubmit()
with vanilla javascript you could call requestSubmit()
const form = document.getElementById('mc-embedded-subscribe-form');
form.requestSubmit();
the hackish solution
you could put an hidden submit button in the form and then trigger the click event on it
<form id="mc-embedded-subscribe-form">
<button id="real-btn" type="submit" style="visibility: hidden"></button>
</form>
<button id="my-btn">Go!</button>
const btn = document.getElementById('my-btn');
const btn_real = document.getElementById('real-btn');
btn.addEventListener('click', (e) => {
e.preventDefault();
btn_real.click();
});
Well, I spent hours on this problem and scanned the whole stackoverflow, but still do not know what to do. But what really gets me nuts is that such a trivial and the simplest in the world thing is not working. So, what I have now is a form with inputs and a button:
<form id="frm" action="/accent/login/enter/">
{% csrf_token %}
<div draggable="true" id="panel" class="panel" title="">
<input id="login" name="login" type="text" placeholder="" class="required" /> <br/>
<input id="pswd" name="pswd" type="password" placeholder="" class="required" /> <br/>
<button id="btn" value="">ENTER</button>
</div>
</form>
And I have this code which is supposed to send the form:
$('#btn').one("click",function(){ // prevent from multiple submits
$('#frm').validate({ // validate the form before submission
...general stuff: rules, messages, etc
submitHandler:function(form){
$('#frm').submit(function(e){ //submitted on the second click. why???
...prepare parameters for ajax call
$.ajax({
type:'POST',
...general stuff
});
e.preventDefault();
})
}
});
});
The problem is, when a user clicks on submit button for the first time, then the form is not submitted, if, however, he or she clicks it for the second time, then it is submitted ok. I can't understand the logic behind such behaviour implemented in jquery. Besides, I should say, that I have tried many other tricks, like:
form.submit(...
$('#frm')[0].submit(...
But they work not as expected, as if there is no callback function - I'm redirected to the url, but do not stay on the same page - just what I expect from e.preventDefault. I guess there is some sacred method or magic properties in jquery that I should use to make it work (like method one which prevents terrible multiple submits). But at this moment I do not know them.
EDIT
I also tried this trick:
jQuery('#frm').submit(...
but it works exactly like the first method - $('#frm').submit(...
EDIT
I found the third method which works like the previous one:
$('form').submit(...
To sum up, I have three different methods, but all of them work only when a user clicks on the button for the second time. And I have two methods that work in a standard manner and do not make it possible to use a callback function.
The problem is, you are registering for form submit after the form validation.
so,
1) On first click of button validation, the submit event is registered to a handler.
2) On second click of the button, the registered handler will be called. that is why it get submitted on second click. But note that you are registering again for the submit event. which means, on third click the form will be submitted twice, on fourth click the form will be submitted thrice..... and so on...
Solution
1) remove the $("#frm").submit() code from the submitHandler and put it outside.
2) use e.preventDefault(); in $("#frm").submit() so the default action is prevented and page doesn't get reloaded.
3) put the AJAX code directly in submitHandler
$('#btn').one("click",function(){ // prevent from multiple submits
$('#frm').validate({ // validate the form before submission
...general stuff: rules, messages, etc
submitHandler:function(form){
...prepare parameters for ajax call
$.ajax({
type:'POST',
...general stuff
});
}
});
});
$('#frm').submit(function (e) {
e.preventDefault();
});
I guess you are using the jqueryvalidation plugin. If it's true, then your using of $().validate() may be wrong.
The $().validate() function is to initialize the validation, it tells the script how to validate the form value and what to do if the validation is passed(the submitHandler property).
So maybe you should edit your code like this:
<form id='frm'>
...
</form>
$('#frm').validate({
//...general stuff: rules, messages, etc
submitHandler: function (form) {
//blahblah before doing the submitting...
form.submit();
}
});
$('#btn').one('click', function (){
$('#frm').submit();
});
But, actually there's still a problem with your $btn.one() event handler: if you click the button while the form values doesn't meet your validation rules, the one chance to fire the handler is consumed and even if you re-input the right value, the button will never response your clicking unless refreshing the page.
So maybe you should check your business logic again and redesign the form submitting flow, but that's not what this question is discussing, good luck ;)
<input type="submit" name="btnADD" id="btnADD" value="ADD"/>
when user click add button twice, from get submitted twice with same data into table.
So Please help me to restrict user to submit from twice.
Once the form is submitted, attach a handler with jQuery that hijacks and "disables" the submit handler:
var $myForm = $("#my_form");
$myForm.submit(function(){
$myForm.submit(function(){
return false;
});
});
Returning "false" from the submit handler will prevent the form from submitting. Disabling buttons can have weird effects on how the form is handled. This approach seems to basically lack side effects and works even on forms that have multiple submit buttons.
try out this code..
<input type="submit" name="btnADD" id="btnADD" value="ADD" onclick="this.disabled=true;this.value='Sending, please wait...';this.form.submit();" />
You can disable the button after clicking or hide it.
<input type="submit" name="btnADD" id="btnADD" value="ADD" onclick="disableButton(this)"/>
js :
function disableButton(button) {
button.disabled = true;
button.value = "submitting...."
button.form.submit();
}
If you are working with java server side scripting and also using struts 2 then you refer this link which talks about on using token.
http://www.xinotes.org/notes/note/369/
A token should be generated and kept in session for the initial page render, when the request is submitted along with the token for the first time , in struts action run a thread with thread name as the token id and run the logic whatever the client has requested for , when client submit again the same request, check whether the thread is still running(thread.getcurrentthread().interrupted) if still running then send a client redirect 503.
And if you are not using any framework and looking for simple workout.
You can take help of the
java.util.UUID.randomUUID();
Just put the random uuid in session and also in hidden form field and at other side(the jsp page where you are handling other work like storing data into database etc.) take out the uuid from session and hidden form field, If form field matches than proceed further, remove uuid from session and if not than it might be possible that the form has been resubmitted.
For your help i am writing some code snippet to give idea about how to achieve the thing.
<%
String formId=(java.util.UUID.randomUUID()).toString();
session.setAttribute(formId,formId);
%>
<input type='hidden' id='formId' name='formId' value='<%=formId%>'>
You could notify the user that he drinks too much coffee but the best is to disabled the button with javascript, for example like so:
$("#btnADD").on('click', function(btn) {
btn.disabled = true;
});
I made a solution based on rogueleaderr's answer:
jQuery('form').submit(function(){
jQuery(this).unbind('submit'); // unbind this submit handler first and ...
jQuery(this).submit(function(){ // added the new submit handler (that does nothing)
return false;
});
console.log('submitting form'); // only for testing purposes
});
My solution for a similar issue was to create a separate, hidden, submit button. It works like so:
You click the first, visible button.
The first button is disabled.
The onclick causes the second submit button to be pressed.
The form is submitted.
<input type="submit" value="Email" onclick="this.disabled=true; this.value='Emailing...'; document.getElementById('submit-button').click();">
<input type="submit" id='submit-button' value="Email" name="btnSubmitSendCertificate" style='display:none;'>
I went this route just for clarity for others working on the code. There are other solutions that may be subjectively better.
You can use JavaScript.
Attach form.submit.disabled = true; to the onsubmit event of the form.
A savvy user can circumvent it, but it should prevent 99% of users from submitting twice.
You can display successful message using a pop up with OK button when click OK redirect to somewhere else
Disable the Submit Button
$('#btnADD').attr('disabled','disabled');
or
$('#btnADD').attr('disabled','true');
When user click on submit button disable that button.
<form onSubmit="disable()"></form>
function disable()
{
document.getElementById('submitBtn').disabled = true;
//SUBMIT HERE
}
Create a class for the form, in my case I used: _submitlock
$(document).ready(function () {
$(document).on('submit', '._submitlock', function (event) {
// Check if the form has already been submitted
if (!$(this).hasClass('_submitted')) {
// Mark the form as submitted
$(this).addClass('_submitted');
// Update the attributes of the submit buttons
$(this).find('[type="submit"]').attr('disabled', 'disabled');
// Add classes required to visually change the state of the button
$(this).find('[type="submit"]').addClass("buttoninactive");
$(this).find('[type="submit"]').removeClass("buttonactive");
} else {
// Prevent the submit from occurring.
event.preventDefault();
}
});});
Put a class on all your buttons type="submit" like for example "button-disable-onsubmit" and use jQuery script like the following:
$(function(){
$(".button-disable-onsubmit").click(function(){
$(this).attr("disabled", "disabled");
$(this).closest("form").submit();
});
});
Remember to keep this code on a generic javascript file so you can use it in many pages. Like this, it becomes an elegant and easy-to-reuse solution.
Additionally you can even add another line to change the text value as well:
$(this).val("Sending, please wait.");
Add a class to the form when submitted, stopping a user double clicking/submitting
$('form[method=post]').each(function(){
$(this).submit(function(form_submission) {
if($(form_submission.target).attr('data-submitted')){
form_submission.preventDefault();
}else{
$(form_submission.target).attr('data-submitted', true);
}
});
});
You can add a class to your form and your submit button and use jquery:
$(function() {
// prevent the submit button to be pressed twice
$(".createForm").submit(function() {
$(this).find('.submit').attr('disabled', true);
$(this).find('.submit').text('Sending, please wait...');
});
})
None of these solutions worked for me as my form is a chat and repeated submits are also required. However I'm surprised this simple solution wasn't offered here which will work in all cases.
var sending = 0;
$('#myForm').submit(function(){
if (sending == 0){
sending++;
// SUBMIT FORM
}else{
return false;
}
setTimeout(function(){sending = 0;},1000); //RESET SENDING TO 0 AFTER ONE SECOND
}
This only allows one submit in any one second interval.
I have a chrome extension which is just a simple form with two input fields and a submit button. The problem I encountered is that something like this:
$('#submit').submit(function() {
$('#word').val('')
$('#translation').val('')
return false
})
Still reloads the popup.html (e.g. submits the form)! I was forced to change the type of the submit button to just 'button' and use
$('#submit').live('click', function(e) {
$('#word').val('')
$('#translation').val('')
})
This works, but now (of course) the ENTER doesn't work for form 'submission'... and I feel this is a hack when the original prevention of reload by returning false should work...
Anyone else had such a problem?
The .submit() is an event on the form, not on the submit button.
I.E.
<form onsubmit="return false;"></form>
we can cancel the submit action by calling .preventDefault() on the event object or by returning false from the onsubmit event of the form.
$('#YOUR_FORM_ID').submit(function() {
$('#word').val('')
$('#translation').val('')
return false
})