django dynamic ajax form - ajax

i'm trying to write csv importer for my project that i can use for any model, it should be a wizard that first you upload the csv file, in the second step it generates a form based on the csv file for mapping csv field with database fields, on the first call to the form i should specify the model for the mapping, that can be a hidden input in the first form. on the other hand i want to use ajax for all the process, i don't know what to use exactly so it would be a complete reusable module and also with writing less java-script also how should i generate the second dynamic form. thanks.

Submit the first form through ajax. The request will contain (hidden) which form to use, so just render that form (based on a ModelForm). Make a template for each possible form(model) and return the rendered template accordingly.
The ajax call will remove the first form, on success and replace it with the response (which will be the second form).

Related

Dynamically add form to formset in Django and submit with AJAX

I have read a lot of answers relating to how to dynamically add forms to an model formset in Django and can successfully implement that. However, I would now like to submit the formset with AJAX. This is mostly working now but I have an issue that I can't find a solution to in any other answer:
If you dynamically add a form to the formset, you give it a new form id number that is one larger than the maximum the form currently has and you also increment the management TOTAL_FORMS count by one. The newly added form then saves successfully as a new object.
I am trying to submit by AJAX so the user can continue editing without having the page refresh. The formset saves fine but any dynamically added forms are now existing objects. To account for this I need to increment the INITIAL_FORMS count on the management form when the save is successful. Easy enough. However, I've also realised I need to give the newly created objects an ID since they now exist in the database.
How can I get my view to tell me the ID of the new objects in its response to the AJAX call? Or is there a better way of looking at this?
Django forms and formsets are intended for classic browser-based posting of data. Though they can definitely be made to work with Javascript, the more you want to part from the normal behavior, the more complex it gets.
Depending on your requirements, you might start thinking about dropping it and switch to Javascript + REST endpoint. Of course, if you need progressive enhancements and you are required to have it work without javascript, that's not an option.
In any case, you want to have a customized view for posting from JS, so that you can get the result back and parse it easily in your AJAX handler. Probably some JSON.
There are several approaches you could take.
Have your AJAX send data to a different URL. This is pertinent if you have an API or are planning to build one at some point. So your form, when submitted normally, will do its old-style processing but your AJAX will talk to the API endpoint instead.
For instance, your form send to https://example.com/myform, but your Javascript code talks to REST api at https://example.com/api/v1/mymodel/ (sending PUT, POST and DELETE requests as appropriate).
Or if you don't have an API and building one seems overkill, you may just alter your view so it formats its output differently depending on whether the data is being submitted in the regular way or using AJAX.
You'd go about it like this:
class MyFormView(.....):
def render_to_response(self, context, **kwargs):
if self.request.is_ajax():
return self.render_to_json(context, **kwargs)
return super().render_to_response(context, **kwargs)
def render_to_json(context, **kwargs):
data = {
# see below!
}
return HttpResponse(
content=json.dumps(data).encode('ascii'),
content_type='application/json',
)
This is just an outline. You need to ensure is_ajax will detect it properly (see django doc). And you need to properly build data from context: extract the things you want to send back to your JS code and put them in the dict.
You will find it's manageable if you just do this for one, maybe two views in your project, but very quickly you'll want to have a small API instead, especially given how easy it is to build one with packages such as Django REST framework.
In your view, where you save the object, AFTER the save, the object.id will contain the new id for the object, which you can return via json or however you want in your ajax response, and then yes you will need to fill that into the formset row so that it will be submitted the next time.
One thing you have to watch out for is that django expects all existing rows to be at the top of the formset, and any new rows to be at the bottom. Otherwise, the formset save will complain about missing id's. So if you're doing any kind of sorting in your javascript, you can't do that.. unless you do quite a bit of fixing of all the field names etc in the formset. The formset code uses the numbers in the management form to determine which rows to insert and which rows to update, it does not do it on the basis of whether or not an id is present. Unfortunately...

Does successful form elements are submited as parameters automatically on AJAX calls?

Do we have to include all form elements (ids and values) manually in the query string when making an Ajax call, or they are automatically (according to standard) included as parameters to the query string of the request?
Well, since no one is eager to answer my question. I will.
the quick answer is no. by standard let's say HTML standard. form element values are not automatically submitted a long with a request as parameters, when making an Ajax call.
but when you submit a form by submit() function of the form element, it will include all successful elements in the query and will send it as parameters to the server.
so If you are using Ajax, you have to include every elements which you need yourself.
however there are some utility functions that can help you. like the serialize() method in Jquery framework.
have fun :)

Getting partial view fragments with Spring MVC

I'm new in Spring MVC, I just started my first project and I'm doing some research to be sure to set it up in a proper way (should work in the long-term!).
I already know that for a part of the project, I will need to manually change small fragments of the page through Ajax. I know it's possible to change part of the page (using Tiles). What I really need, though, is for example to change a single line in a table containing dynamically generated data (i.e. data coming from the database).
Can you suggest anything?
I don't want to use JSF or Spring JS.
Thank you.
You have at least two choices:
render on the server, send the update html snippet to the brower and use JavaScript to replace them
send an AJAX request to the server, but this time return only the data (JSON) and the "render" the table line in the browser (or just update some pices of text)
For the fist choice you need a dedicated jsp file (and tiles configuration) to render only a single line. As fare as I know, there is no technical support.
What you can do, to reduce the amount of duplicated code is to use that single line rendering jsp in like in include in the one that renders the complete table.
Of course instead of using JSP to render the single line you can also use the Java Method that handles the request, and make it returning the html string.

Django Forms - Processing GET Requests

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.

Validate data from CakePHP form with jQuery (AJAX)

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.

Resources