i'm doing a form that will send an e-mail after completing the fields. The email must contains all the information wrote in the form, but in the forms i did a button to add more items, and this will appeart two new fields of "select component" and "quantity". How can i get the data from these fields that will be created after clicking into "add component" and put into my email?
my views.py
def home(request):
if request.method == 'POST':
form = Form(request.POST)
if form.is_valid():
type = form.cleaned_data['type']
serialNumber = form.cleaned_data['serialNumber']
itemNumber = form.cleaned_data['itemNumber']
date = form.cleaned_data['date']
phase = form.cleaned_data['phase']
capacity = form.cleaned_data['capacity']
centerQuantity = form.cleaned_data['centerQuantity']
componentQuantity = form.cleaned_data['componentQuantity']
componentSelection = form.cleaned_data['componentSelection']
commentary = form.cleaned_data['commentary']
html = render_to_string('emails/email.html', {
'type': type,
'serialNumber': serialNumber,
'item': itemNumber,
'date': date,
'phase': phase,
'capacity': capacity,
'centerQuantity': centerQuantity,
'componentQuantity': componentQuantity,
'componentSelection': componentSelection,
'commentary': commentary,
}
)
send_mail('ATENÇÃO', 'Message', '[email protected]', ['[email protected]'], html_message=html, fail_silently=False)
return redirect('home')
else:
form = Form()
return render(request, 'template.html', {
'form': form
})
My html file:
<body>
<div>
<h2> Engine Information</h2>
<table>
<form action="." method="POST" hx-post=".">
{% csrf_token %}
<tbody>
<tr>
<th>Type</th>
<td>{{form.type}}</td>
</tr>
<tr>
<th>Serial Number</th>
<td>{{form.serialNumber}}</td>
<th>or Material Number</th>
<td>{{form.itemNumber}}</td>
</tr>
<tr>
<th>Manufactoring Date</th>
<td>{{form.date}}</td>
<th>Phase</th>
<td>{{form.phase}}</td>
<th>Capacity</th>
<td>{{form.capacity}}</td>
<th>Center Quantity</th>
<td>{{form.centerQuantity}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="component-form">
<h2>Component</h2>
<div >
<table id="component">
<tbody>
<tr>
<th>Select the component</th>
<td>{{form.componentSelection}}</td>
</tr>
<tr>
<th>Component Quantity</th>
<td>{{form.componentQuantity}}</td>
</tr>
</tbody>
<div id="form-added"></div>
</table>
</div>
<button id="add-more" type="button">Add component</button>
<table>
<tbody>
<tr>
<th>Commentary</th>
<td>{{form.commentary}}</td>
</tr>
</tbody>
</table>
<input type="submit" id="button" value="Submit">
</form>
</div>
<script>
const AddMoreBtn = document.getElementById('add-more')
AddMoreBtn.addEventListener('click', add_new_form)
function add_new_form(event) {
if (event) {
event.preventDefault()
}
//id
const newId = document.getElementsByClassName('parts-form')
const idIncrement = newId.length 1
//
const formAdd = document.getElementById('form-added')
//add new empty form
var componentForm = document.getElementById('component').cloneNode(true)
componentForm.setAttribute('class', 'parts-form')
//id increment
componentForm.setAttribute('id', `form-${idIncrement}`)
formAdd.append(componentForm)
}
</script>
</body>
</html>
My forms.py:
from django import forms
material_type = (
('material', 'Search with material'),
('serial', 'Search with serial number'),
)
component_type = (
('AIR FILTER', 'AIR FILTER'),
('ALUMINIUM FAN', 'ALUMINIUM FAN'),
('BEARING CAP DE', 'BEARING CAP DE')
)
class Form(forms.Form):
type = forms.ChoiceField(choices=material_type, initial="Select One Option")
serialNumber = forms.CharField(label='Serial Number', required=False)
itemNumber = forms.IntegerField(label='Item Number', required=False)
date = forms.DateField(label='Manufactoring Date',widget=forms.DateInput(attrs={'placeholder':'Ex: 10/05/2022'}))
phase = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Ex: Monophasic'}))
capacity = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Ex: 15cv'}))
centerQuantity = forms.IntegerField(label='Center Quantity')
componentSelection = forms.ChoiceField(choices=component_type, label='Component Selection')
componentQuantity = forms.IntegerField(label='Component Quantity')
componentSelection1 = forms.ChoiceField(choices=component_type, label='Component Selection', required=False)
componentQuantity1 = forms.IntegerField(label='Component Quantity', required=False)
commentary = forms.CharField(widget=forms.Textarea(attrs={"rows":8, "cols":80}))
my email.html
<h2 id="title">Submission</h2>
<br>
<p>Type: {{type}}</p>
<p>Serial Number: {{serialNumber}}</p>
<p>Item: {{item}}</p>
<p>Manufactoring Date: {{date}}</p>
<p>Capacity: {{capacity}}</p>
<p>Center Quantity: {{centerQuantity}}</p>
<p>Component Quantity: {{componentQuantity}}</p>
<p>Component Selection: {{componentSelection}}</p>
<p>Commentary: {{commentary}}</p>
<style>
.title{
margin-bottom: 2px;
}
</style>
CodePudding user response:
Handling this scenario with simple django views and forms is not quite easy.
- You need to set the input name attribute using the incremented index and the field name in your javascript.
- Add the increment counter value to a special field in your form, so django knows how many fields have been added using javascript.
- In the
__init__()
method of your form, you have to dynamically add the fields using the provided incremented index. - In your view you can then iterate over the dynamic fields using the incremented index as well.
Some helpful links: