We have an autosave and an explicit save for a particular form (it's a long form, and we don't want the user to lose data). For an explicit save, invalid data will block the save from occurring and an XHR will not be sent back to the server. However, for the autosave, we want the data to be saved (if possible) regardless of front-end validation.
What we need to have happen is, if the save is successful on the backend, the front-end should mark the form as no longer being dirty. But... and here's the sticker - it should not remove any validation errors/error messages from the form.
From what I'm seeing (or at least from what I understand), .$setPristine() will un-dirty the form, but it will, problematically, also remove validation errors.
Is there a way to un-dirty the form without removing the validation errors so that the autosave doesn't run when it's already performed a save, but so that the user still has the feedback of which fields are invalid so that they can fix the issues?
Thanks!
A form's $pristine/$dirty states are not connected to the $valid/$invalid states.
Your error messages shouldn't be removed (unless you use $pristine/$dirty in the condition that shows/hides the messages).
So, you can call the FormController's $setPristine() method in your autosave function, which will "un-dirty" the form, but will not affect the validation and error messages.
See, also, this short demo.
E.g.:
* In the fiddle above, enter something in one field (so it becomes valid and the form becomes dirty).
* The Save button gets enabled.
* Pressing the Save button sets the form's state to $pristine, so the button gets disabled (this simulates the autosave).
* The errors messages are still visible though (and the form's validity state does not change).
Related
So I’m running a WordPress site and it has a form I have made using HTML with a text field, an email field, a password field, and a submit button.
The problem is that users can spam the submit button, and users are occasionally prone to do that as I’m using AJAX to handle the form submission which can take a while.
Any elegant solutions would be good. I have a few suggestions I think could work but I’m not sure how to implement them, if they will actually work, or if they’re even viable.
First possibility I’m thinking of — when WordPress loads a new page, it often has the swirly loading screen with a grey background. could I have the loading screen come on prematurely, as in at the point when I run any AJAX code, too, rather than just when it changes page?
Second possibility I’m thinking of — is there a way to block all of the form fields and the submit button from being pressed as soon as you click it so it cannot be spammed and fields cannot be changed? Could this work via JavaScript (sorry not the best with JS)?
Third possibility I’m thinking of — is there a way that the system only accepts one form from an IP in the space of 5-10 seconds and any other submissions of a POST request in that cooldown time are ignored?
Would any of the above solutions work or be viable enough to work? If so, how would or could they work? I’m thinking the second one is probably the easiest to implement? However, wouldn’t the first one confirm to the user that we’re processing their data so it’d be better for the UX?
Fourth possibility that considers UX and the solution I feel is more practical — is there a way to block the submit buttons and input fields from being pressed or edited once the submit button has been pressed once, and then have a swirly loading bar appear below or above it (maybe via CSS and HTML?) so users know the site is doing something or loading?
Something just to note — the change must be client side only and the change should not affect the user if they come back to the page in future, meaning it should not remain blocked if they refresh the page or come back to it later. I know it’s implied, but wanted just to specify that.
Since you're doing this as an AJAX request, i imagine you currently have some javascript tied to the onsubmit event. Most likely this function of yours encodes the data to JSON and then sends it to the server using ajax.
One way you could accomplish this, is:
Introduce a new variable in the global scope (so outside of the onsubmit-handler); like var submission_cache = ''; or the like.
Next, inside your onsubmit handler, between the stage where you have 'encoded the entire form to a single json string' and the stage where you 'actually send the data', you compare the json to the submission_cache variable. If it matches you ignore the submission, if it doesn't match then you store a copy of the json (or a sha1 checksum of it) in submission_cache, and then just continue with the ajax stuff.
This way:
Since it is a variable on the page, the cache has the same lifetime as the page. If they leave your site and return later, the variable will be empty again, and they can submit identical info as the last time.
Secondly, if they notice they made a typo 1ms after they submitted, they can resubmit (since the cache wont match), which i imagine is desirable.
Another solution that you could use in addition to the above is to simply enable the disabled attribute on the submit button (inside your onsubmit handler function. Re-enable it after a setTimeout or in one of your ajax onreceived/onerror closures.
I have a complex Angular form representing a printable document. Form has two buttons to submit the form. One is for saving the working version and another to print the completed form to PDF.
The problem is simple, but more difficult to solve for me. Of course, when you are going to save a working version there will be unfilled fields. There are some allways required fields (such as name and personal ID) which are needed to save the form. Other fields are required only for printing. So the validity of these fields depends on the action (the button clicked by the user). I cannot determine the validity when the user is editing the field (angular validators are fired when fields content is changing), because I dont know which button will be clicked. I need to fire the validation of the whole form after one of the buttons was clicked. At that point I already know the action and can evaluate the validity of the fields (I have a custom angular validator to do this job).
My question is: how to trigger the (re)validation of the whole form from a function? If it is not possible, are there any other solutions to implement the validation described above?
I would prefer a solution where the $valid and $invalid properties of the fields are always set properly. My custom validator can ensure this. But how to trigger it on every field from a function? If it is not possible to trigger the validation by one function call, it is possible to iterate over all fields of the form? (to call the $validate() method of NgModelController)
This may be an iterative question and answer process because I'm not sure which code to paste. I have a custom, advanced search form (which uses ng-submit) that passes a query object into a controller method and calls a service. When the user has entered some input into one or more fields, pressing the submit button (which uses ng-click) successfully calls the methods and submits the query. However, if the user presses enter to submit the form, those same methods are called, but the query object is missing the bound values of the input fields. I've stepped through with breakpoints and have verified that all of the above is what's happening, but am unsure where the problem lies. Is there a difference in Angular's data binding process between ng-click and pressing the enter key? Do I need to call prevent default somewhere? Let me know what code I need to add to this post to help with troubleshooting. Thanks!
For anyone who may encounter this problem in the future, it turns out that the problem was that the enter key was firing both the Clear and Submit buttons, as the default behavior for a button is submit. It just happened to be firing the Clear button first, otherwise we never would have noticed the problem. The solution was simply to add "type=button" to the clear button.
I've tried to insert a form in woocommerce product page. I've inserted the form in the product page. When the form is submitted I'm trying to get the email (form input value) and validate it accordingly.
The problem is I'm not able to get the value in some theme using jQuery. I see the form and its elements in firebug. But jQuery is not even working for the click event in variable product (woocommerce product page). Here the form is inside their form (which enctype is multipart/form-data), this might be one reason or if I place the form above the variable product form jQuery it works but it returns empty string.
Even if there is some text inside the form input field, it returns empty string.
Here is the form
Here is the jQuery On submit click
jQuery(document).ready(function() {
jQuery('.mailsub').click(function() {
var subaddress = jQuery('.subemail').val();
console.log(subaddress);
if ( jQuery('.subemail').length > 0 ){
console.log('the element with element_id exists in the DOM');
}
//ajax goes here followed by validation for the email
return false;
});
});
I've tried to check whether it is in DOM or not, so I've used the code, it says the element with element_id exists in the DOM.
I'm able to get the form completely work on twentyeleven and defaults themes. It is working in wordpress defaults themes but not in some other third party themes.
What might be the problem? Any suggestion would be much helpful.
The HTML and code as given should mostly work. I'm guessing that there is another element with the class subemail earlier in the document. When you do jQuery(".subemail").val(), jQuery finds all of the matching elements, but then returns the value (if any) of only the first of them.
Side note: If you step through the code with the debugger built into your browser, rather than doing console.log statements, you can inspect variables as the code is running, which is dramatically more educational, usually.
Side note 2: Some browsers submit forms when the user presses Enter in a text field. In that case, the click event on the submit button may not be fired (since the button wasn't clicked). To reliably hook into the form submission process, use the submit event on the form, rather than the click event on the button.
Side note 3: You've said you're using ajax to validate the email address. By default, ajax calls are asynchronous, which means you cannot use the result from the server to decide whether to submit the form, because you don't get the result until after the submit event handler has returned and (probably) the form has already been submitted. You can make the ajax call synchronous, but that locks up the UI of most browsers while the call is in progress, leading to poor user experience. I suggest validating the email address via ajax when the field changes, and then again on the server when it receives the form (you can never rely on client-side validation). That lets you give the user proactive feedback (the on-change validation) without trying to validate it via ajax when submitting the form.
am using a form to register the user on my website and i have a captcha security on it. Everything is working well and good but the only problem that i am facing is that if i enter a wrong captcha or somehow the page refreshes , all the data entered by the user is wiped out.
what i wish to achieve is that even if the captcha entered is wrong and the form is submitted , the form should have all the fields intact as the user filled in excluding the captcha field.
How can this be done? My form is html and by using javascript im validating it
Some browsers may be smart enough to do this, but if you want to make sure, the only way to retain data across a page reload/refresh (including form submission) is to keep it on the server, and/or put it in a cookie.
However, instead of using a submit button, you could use a normal button with an onclick() function which validates the data first, then manually submits the form if appropriate.
document.forms["form_name"].submit()
You also have to handle key events for the form text inputs, to prevent enter from submitting.
However, this is still much easier in the end, since it prevents the page from changing and doesn't require server side storage or cookies.