I am looking to better understand the typical approach to form validation with AJAX.
I have found some information on this approach but it is hard sometimes to decipher what is the standard practice and what is a hack.
In my scenario, which is a common one, I have a dynamic form that the user submits and I want to ensure that the form input is valid. If the form input does not pass validation, I want to re-display the form with the input submitted and display an error message.
From what I have read, it appears the best practice approach is to perform an AJAX POST on submit, essentially posting the entire form. The server processes the AJAX post validating the posted items, and if all the items are valid, they are operated on (updates, inserts, etc to database). Finally, the AJAX response returns the validation result. If the validation result indicates success, a simple redirect occurs (the form is not re-posted since the form input was already processed and committed to the DB in the AJAX request). If the validation result indicates an error, the error is displayed and the redirect does not occur.
Is this the correct approach?
Should the form input be processed during the AJAX POST, leaving just a redirect on the callback, or is it best to process the form input after the callback by re-posting the form?
It doesn't make sense to me to re-post the form. In that case, I would think you'd have to validate the data twice for security reasons...both on the AJAX post and the re-post.
It is also possible I missed an even better, more standard approach. Thanks.
Related
I'm developing a form with Symfony2 : several text inputs and one file input (for one picture). I have defined some asserts (maxLength, minLength...) in my entity in order to check the form (isValid).
My problem is : if the user puts bad data in text input (text too long or too short...), he still can submit the form, and error and printed but the user have to re-choose his picture.
As I think it's impossible to keep the picture in the form after bad validation, I should maybe check the form in client side (javascript), before submit.
So, is there an automatic way to do this (to forbidden submit until data are correct)? Can we get the assert minLength, maxLength value in twig ?
Thank you !
Ben.
You can use js validation before submitting the data, using some js form validation tools, but this way you need the replicate the validation logic from the server, so if validation rules changes, you need to modify on both server and client side. I recommend this method to reduce the traffic between client-server.
If you don't want this, use ajax form submitting (example here). You still validate the form using symfony, but the page won't refresh, so you won't lose the attached file. But this generates additional traffic to server, and you also need to implement error displaying using javascript.
CodeIgniter gives an error "The action you have requested is not allowed." when it fails the check for CSRF. As I understand it, this means the POST is missing the hidden token from the form that proves that an attack is not being done.
The token is generated automatically with a call to the CI form_open function.
In my case, I'm using Knockout to post the contents of a ViewModel for saving, like this:
ko.utils.postJson($("form")[0], self.pages);
I've found solutions elsewhere that simply turn off the CSRF setting for the specific page, but that doesn't seem like a good solution.
Presumably because the token is not being received, the postJson call is not submitting the existing form. Is there a way to either submit the required token along with the JSON data or submit the JSON data with the existing form?
try to use form_open() and form_close
all form helper functions that will help.
or: I think it's from time zone difference as the Security class depends on time for hashing.
The specific case I've got in mind is as follows: an AjaxFormComponentUpdatingBehavior("onchange") is added to a TextField in a form. The behavior verifies the text for certain conditions (either the model object or the form component model, doesn't matter), based on which it might display a message (or hide it, if it has already been shown).
The problem is, there are also validators added to the TextField. One of the possible (and likely) scenarios consists of the user typing in, first, a value that causes the message to be displayed by the AJAX request. If, then, he/she types in a value that doesn't pass validation, the message should disappear, but it does not.
Apparently, either the onUpdate() method for the AJAX behavior is not called at all, or I am failing in my attempts to insert a check for non-validated entries (I have tried to test for both null values and empty strings, to no avail; I have no idea what exactly Wicket's validators do to models when data is invalid).
I am wondering if someone who actually understands validators (or AJAX, actually) has any ideas on where the problem could be.
I can post edit and post code if someone tells me this is not a general issue tying validators and AJAX, but most likely a programming mistake. I still believe the former and thus I'll refrain from posting code sections, in order to keep the discussion on an API/theoretical frame.
Thanks.
When using an AjaxFormComponentUpdatingBehavior, if any of the IValidators fail their validation, onError() will be called instead of onUpdate(). Wicket will effectively prevent invalid user input from reaching the IModels in your components, so the component's ModelObject will not be changed at all. The invalid input will probably remain available by means of getInput()/getConvertedInput() (not sure if it will in an AJAX scenario, it sure is in a traditional form submission).
However, take into account that IFormValidators are not executed when using this mechanism. If you've got any, you might be interested in overriding getUpdateModel() so that AjaxFormComponentUpdatingBehavior will not bring maybe-invalid user input into your IModels, and set modelobjects manually when you're certain user input is valid.
Regarding your specific case, you could perform all the required logic in onError() (or rely on Models that will grab data from somewhere else), and just add the components that need refreshing to the AjaxRequestTarget. This is probably what's missing in your scenario.
We have an existing Django form that accepts GET requests to allow users to bookmark their resulting query parameters. The form contains many fields, most of which are required. The form uses semi-standard boilerplate for handling the request, substituting GET for POST:
if request.method == 'GET':
form = myForm(request.GET)
if form.isValid()
# Gather fields together into query.
else
form = myForm()
The problem is that the first time the form is loaded, there's nothing in the GET request to populate the required fields with, so most of the form lights up with 'missing field' errors.
Setting initial values doesn't work; apparently, the non-existent values in the GET request override them.
How can we avoid this? I'm pretty certain we're simply not processing things correctly, but I can't find an example of a form that handles GET requests. We want errors to show up if the user hits the "Submit" button while fields are blank or otherwise invalid, but don't want these errors showing up when the form is initially displayed.
The positional argument to the forms.Form subclass informs Django that you intend to process a form rather than just display a blank/default form. Your if request.method == 'GET' isn't making the distinction that you want because regular old web requests by typing a URL in a web browser or clicking a link are also GET requests, so request.method is equal to GET either way.
You need some differentiating mechanism such that you can tell the difference between a form display and a form process.
Ideas:
If your processing is done via. AJAX, you could use if request.is_ajax() as your conditional.
Alternatively, you could include a GET token that signifies that the request is processing. Under this example, first you'd need something in your form:
<input type="hidden" name="action" value="process_form" />
And then you can look for that value in your view:
if 'action' in request.GET and request.GET['action'] == 'process_form':
form = myForm(request.GET)
if form.is_valid():
# form processing code
else:
form = myForm()
I'll also give you the standard, boilerplate point that it's generally preferable not to use GET for form processing if you can help it (precisely because you run into difficulties like this since you're using an anomalous pattern), but if you have a use case where you really need it, then you really need it. You know your needs better than I do. :-)
If your clean page load doesn't have any non form GET params, you can differentiate between a clean page load and a form submit in your view. Instead of the usual
form = YourForm()
if request.POST:
you can do
if request.GET.items():
form = YourForm(request.GET)
if form.is_valid():
...
else:
form = YourForm()
If your clean page load could have other params (eg email link tracking params) you'll need to use the QueryDict methods to test if any of your form params are in the request.
request.GET is and empty dictionary when you first load a clean form. Once you have submitted the form, request.GET will be populated with your fields data, even if the fields contain only empty data.
My first question is this, which I posted as comment:
Why not just use request.POST and the standard way of processing form data?
After considering everything here, perhaps what you are looking for is a way of processing data in your query string to populate a form. You can do that without using request.GET as your form.data.
In my own views, I take advantage of a utility function I created to add initial data to the form from request.GET, but I am not going to share that function here. Here's the signature, though. initial_dict is typically request.GET. model_forms is either a single ModelForm or a list of ModelForm.
def process_initial_data(model_forms, initial_dict):
Nevertheless, I am able to process the form through the standard practice of using request.POST when the form is POSTed. And I don't have to pass around all kinds of information in the URL query string or modify it with JavaScript as the user enters information.
I would like to validate both single field and multiple field data from a CakePHP form.
The single field validation should be done on blur from each field while the multiple field validation should be done on submitting the form.
I would like to use the $validate property declared in the Model for validating data and I would like to display the errors near each field (single field validation) and on top of the form (for multiple field validation).
My main goal is to achieve this the most "caky" way (if there is one for validating data with jQuery). I couldn't find any useful advice out there and I'm asking you for some help to get this going.
One of my concerns is how shall I pass data from the form to jQuery and then to the action that does the validation and also how shall I return and display the errors, if there are any.
Thank you in advance!
I'd suggest first making sure everything works without jQuery, then use the jQuery Form plugin to submit your forms via AJAX. If you include the RequestHandler component in your AppController, you should find that your controllers distinguish automatically between AJAX and synchronous requests.
OK, so I coded my own solution to this, but I am still waiting for a more "caky" approach.
I made two generic jQuery functions, one for single field validation and one for multiple field validation. The function should grab the data from the specified form and send it to the form's action via AJAX, to a specially created controller method which will attempt to validate data and output an AJAX response ("" for validation has passed and errors for errors in validation). Then, the result is checked in the jQuery function and the default form behaviour is triggered only if the validation has passed. Otherwise, display the errors and return false; to prevent default submission.