The form is rendered a number of times depending on the user’s previous selection, it displays n forms if n was inputed by the user on the previous screen.
I want to make the choices of the forms dynamic, ie, if an user selects one choice in the first form that choice is not available on the other form and so on, so there cannot be duplicated choices.
I belive JS is the solution for this as I am not saving every form one by one but all in one go (see views below). However, I have very little knowledge of JS and all I tried did not work (based in prompts from AI). That is why I ask here to see if I could achive this with Django -and I will be happy to stay away from JS!
I would like to keep the forms save in bluk at the end but if saving one form at time and render the next with the reduced choices is possible I will considerate.
Any guidance?
Here is the template’s relevant content:
<form method="post">
{% csrf_token %}
{% for form in shocks_forms %}
<h4>Sector {{ forloop.counter }}</h4>
{{ form.as_p }}
{% endfor %}
<button type="submit">Submit</button>
</form>
And here the full backend view to understan how forms are send and render:
def simulation_shocks_view(request, pk):
simulation = get_object_or_404(Simulation, pk=pk)
number_of_sectors_to_shock = simulation.number_of_sectors_to_shock
if request.method == 'POST':
form_list = [ShockForm(request.POST, prefix=str(i+1)) for i in range(number_of_sectors_to_shock)]
if all(form.is_valid() for form in form_list):
shocks_data = {}
for form in form_list:
sector = form.cleaned_data['sector']
amount = form.cleaned_data['amount']
shocks_data[sector] = amount
simulation.shocks = shocks_data
simulation.save()
return redirect('simulation_details', pk=simulation.id)
else:
pass
else:
form_list = [ShockForm(prefix=str(i+1)) for i in range(number_of_sectors_to_shock)]
context = {
'shocks_forms': form_list,
}
return render(request, 'shock_form.html', context)
Side note: What you’re doing here with the multiple forms is an ideal case for using a formset. (It would make your code a lot simpler.)
Please post the JS that you are trying to use.
Yes, you can do this using Django-only if you’re willing to do this:
This also simplifies the code in that you would no longer be handling multiple forms. To use this method, you would display one form, with (perhaps) the previous selections being shown on the page. The key would be that those previous selections must not be forms - just a static display, perhaps a table.
Thanks for the tip @KenWhitesell, I tried to use the formsets but I see the only code change would be instead of: form_list = [ShockForm(request.POST, prefix=str(i+1)) for i in range(number_of_sectors_to_shock)]
I would do: form_list = formset_factory(ShockForm, extra=number_of_sectors_to_shock)
It is shorter and more friedndly to understand but as a beginner I don’t see much more avantage to change the code, is it that saving computational time or other aspects I cannot perceive?
I am not sure if I want that functionality as I would prefer the user to have forms on the screen while making the selection. Is there some way to maybe show the forms but with the selection disabled? Like this the user cannot modify it and is still shows the form with the previous selection. I tried that but I struggle to pass the request.POST data from the form to other views wihtout saving it… The forms load with disabled fields but the data became empty. My goal would be to save them all in bulk at the end but still have that dynamic selection applied if possible.
I just copy/pasted several options from AI chatbots and did not work so I dont think is fair to show you all here and expect to get it fixed. Seems that JS is the way to go for my requirements, maybe better to ask for any guidance on sources to learn/understand how to produce the code by myself?
That’s why I labeled that as a “Side note”. There are other operations that it could simplify, but it’s your decision as to how that all gets handled.
This really isn’t a great option with choosing to do it this way. You need to save the data from the first view somewhere, and that may as well be the database. Otherwise you’re creating a lot of headaches for yourself with trying to pass data between views.
It’s all a matter of finding the right learning materials for you.
I don’t know how much JavaScript you know or what JS frameworks you may be using or wanting to use. But you are going to need to be familiar with the HTML that you’re looking to modify - what a select list looks like, how to locate an element in a page, etc. Being reasonably familiar with the language itself and its features is also important.
I hesitate making specific recommendations regarding tutorials because not everyone comes to a topic with the same background or pre-existing knowledge, and different people have different learning styles.
(Also, since I’m well beyond that stage myself, I don’t really follow what’s currently available in the “getting started” category for JavaScript.)