Flask landing page contact form - flask

I learn Flask and started to make a simple landing page for the project. Here is the route that handles the contact form
#app.route("/courses")
def courses():
form = ContactForm()
if request.method == 'POST':
if form.validate() == False:
flash('All fields are required.')
return render_template('courses.html', title="contact", form=form)
else:
msg = Message(recipients=['coterakg#gmail.com'])
msg.body = """From: %s <%s>%s"""%(form.name.data, form.email.data, form.message.data)
mail.send(msg)
return render_template('courses.html', title="contact", success=True)
if request.method == 'GET':
return render_template('courses.html', title="contact", form=form)
Then there is a template part which has the form
<form class="form-horizontal" action="{{ url_for('index') }}" id="contactform" method="post">
<div class="modal-header">
<h4>Задайте нам любой вопрос!</h4>
</div>
<div class="modal-body">
{{ form.hidden_tag() }}
<div class="form-group">
<label for="contact-name" class="control-label">Имя:</label>
<div>
{{ form.name }}
</div>
</div>
<div class="form-group">
<label for="contact-email" class="control-label">Email:</label>
<div>
{{ form.email }}
</div>
</div>
<div class="form-group">
<label for="question" class="control-label">Ваш вопрос:</label>
<div>
{{ form.message }}
</div>
</div>
</div>
<div class="modal-footer">
<a class="close-reveal-modal">×</a>
<button class="button" type="submit" value="contact" data-reveal-id="closeModal">Отправить</button>
<div data-reveal class="reveal-modal" id="closeModal">
<h1>Спасибо за Ваш вопрос!</h1>
<a class="close-reveal-modal">×</a>
</div>
</div>
</form>
And lastly - the part with form
from flask.ext.wtf import Form
from wtforms import StringField, BooleanField, SubmitField
from wtforms.validators import DataRequired
class ContactForm(Form):
name = StringField("Name", validators=[DataRequired()])
email = StringField("Email", validators=[DataRequired()])
message = StringField("Message", validators=[DataRequired()])
submit = SubmitField("Send")
Any ideas why this is not working?

here is a good examples for you https://github.com/jawr/flask-contact/blob/master/main.py
And detailed steps here http://code.tutsplus.com/tutorials/intro-to-flask-adding-a-contact-page--net-28982
I would also suggest you to use some 3rd party service as a mail server (Mandrill, etc).

Related

Django Forms Invalid but no Errors

Maybe it might be an oversight but I do not know the point where I am getting it wrong.
My form is rendered correctly but it keeps failing without errors.
forms.py
from crispy_forms.helper import FormHelper
from django import forms
from django.utils.translation import ugettext as _
class BeneficiaryForm(forms.Form):
"""Add Beneficiary template form"""
# Form fields
account_currency = forms.ModelChoiceField(queryset=Currency.objects.all(), empty_label=_('Select account currency'))
bank_account_type = forms.CharField(max_length=50, required=False)
email = forms.CharField(max_length=150, required=False, help_text=_("We'll notify them when a transfer is made"))
name = forms.CharField(max_length=50, required=False)
swift_code = forms.CharField(max_length=11, required=False,
widget=forms.TextInput(attrs={'placeholder': 'MSBCCNBJ001'}))
iban = forms.CharField(max_length=34)
def __init__(self, *args, **kwargs):
super(BeneficiaryForm, self).__init__()
self.helper = FormHelper()
self.helper.form_show_labels = False
views.py
def beneficiaries(request):
"""View function for viewing Beneficiaries and adding a Beneficiary instance"""
if request.method == 'POST':
form = BeneficiaryForm(request.POST)
if form.is_valid():
print("Form is valid")
print(request.POST['bank_account_type'])
print(request.POST['email'])
print(request.POST['name'])
print(request.POST['iban'])
print(request.POST['swift_code'])
print("Form is invalid")
print(form.errors)
form = BeneficiaryForm()
context = {
'form': form
}
return render(request, 'dashboard/beneficiaries.html', context)
and in my rendered form. I have this block to show errors and nothing shows up
HTML
<form action="{% url 'beneficiary_index' %}" method="post">
{% csrf_token %}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
{% if field != '__all__' %}
<strong>{{ field.label }}:</strong>
{% endif %}
{{ error|escape}}
</div>
{% endfor %}
{% endfor %}
{% endif %}
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">{% trans "Account currency" %}</label>'
</div>
{{ form.account_currency | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">{% trans "Bank Account type" %}</label>
</div>
{{ form.bank_account_type | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">Their email(optional)</label>
</div>
{{ form.email | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">Full name of account holder</label>
</div>
{{ form.name | as_crispy_field }}
</div>
<h6>{% trans "Recipient Bank Information" %}</h6>
<hr>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">Swift code</label>
</div>
{{ form.swift_code | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">IBAN</label>
</div>
{{ form.iban | as_crispy_field }}
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">{% trans 'Add Beneficiary' %}</button>
</div>
</form>
This is the Html to the form. I have just tried all the suggestions and still without the errors.
Form is Invalid is the only thing printed on screen without the form.errors
You need to create the GET request empty form in the else block or return the request in the POST block.
You are re-creating an empty form before returning the response.
def beneficiaries(request):
"""View function for viewing Beneficiaries and adding a Beneficiary instance"""
if request.method == 'POST':
form = BeneficiaryForm(request.POST)
if form.is_valid():
print("Form is valid")
print(request.POST['bank_account_type'])
print(request.POST['email'])
print(request.POST['name'])
print(request.POST['iban'])
print(request.POST['swift_code'])
# do other stuff like saving to DB
# then redirect
else:
print("Form is invalid")
print(form.errors)
elif request.method == 'GET':
form = BeneficiaryForm()
else:
# maybe return 404
pass
context = {
'form': form
}
return render(request, 'dashboard/beneficiaries.html', context)
Or maybe you can try Class Based Views, to avoid the if-else block for GET and POST requests.
Try adding this to the place you want the error to appear (In the HTML file)
Better if you use it inside the tags.
{% if form.errors %}
<p>Form is invalid</p>
{% endif %}
I Hope this answers the question.

can't raise ValidationError django validators

I need to know how I raise ValidationError of a validators in django.
First I tried the methode on form in simple page and forms and it works perfectly.
but the problems appear when I use modal fade class in a page works with pk
for example(127.0.0.1:8000/wsheets/AMA2/).
the message is
(The view Home.views.wellsets didn't return an HttpResponse object. It returned None instead.)
and mt views.wellsets is
def wellsets(request, WeelN):
serchedWl = WellSheets.objects.filter(WellID__exact=WeelN)
form= WelshetForm()
context ={
'title': 'SearchWS',
'Wellslistsh':serchedWl,
'WeelN':WeelN,
'form':form,
}
if request.method == 'POST':
form =WelshetForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellSheetg', WeelN)
else:
return render(request,'Home/WELLINFO/W_TchD/wellshts.html', context)
and my form + validator is:
from django.core.exceptions import ValidationError
class WelshetForm(forms.ModelForm):
WellID = forms.CharField(label='Well Name',max_length=15)
FileNm = forms.CharField(label='File Name',max_length=15)
def clean_SHRPath(self):
SHRPath = self.cleaned_data.get('SHRPath')
size= SHRPath._size
if SHRPath._size > 1024*1024*10:
raise forms.ValidationError('Size is bigger than allowed')
return SHRPath
and at last this is my html form
<button type="button" class="btn button1 btn-outline-success mb-2 btn-block" data-toggle="modal" data-target="#myModal" >
<p class="thicker">Add new Well-Sheet</p></button>
<div class="modal fade" id="myModal" role="dialog" >
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><p class="thicker">Upload Well-sheet</p></h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<p class="thicker">Check your file before uploading ({{WeelN}})</p>
<div class="w3-panel w3-light-grey w3-round-large solid"">
<form method="POST" id="formOne" enctype= multipart/form-data>
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.WellID|as_crispy_field }} </div></div>
<div class="form-row">
<div class="form-group col-md-8 mb-0">
{{ form.SHRPath }}</div></div>
<p style="color:red;">Maximum upload size is 10Mb</p>
<br>
<input class="btn btn-success mb-6" name="form_uplod" type="submit" value="AddSheet">
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>
</div>
</div>
Modal form
As #IainShelvington said, you need to remove else block to get a response. You can try like this:
def wellsets(request, WeelN):
serchedWl = WellSheets.objects.filter(WellID__exact=WeelN)
form= WelshetForm()
if request.method == 'POST':
form =WelshetForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellSheetg', WeelN)
context ={
'title': 'SearchWS',
'Wellslistsh':serchedWl,
'WeelN':WeelN,
'form':form,
}
return render(request,'Home/WELLINFO/W_TchD/wellshts.html', context)
So that, even if the validation fails, you will get a response with form containing error data. To show form errors in template, try like this:
<div class="form-group col-md-8 mb-0">
{{ form.SHRPath }}</div>
{% if form.SHRPath.errors|length > 0 %}
<p style="color:red;">{{ form.SHRPath.errors.0 }}</p>
<br>
{% endfor %}
More information can be found in documenation.
Hi In fact I did it by other way
no error message appear in the bootstrap modal at the moment of submitting but it works fine.
in my views.py I created a new form (form_error):
def wellsets(request, WeelN):
serchedWl = WellSheets.objects.filter(WellID__exact=WeelN)
form= WelshetForm()
form_error = False
if request.method == 'POST':
form =WelshetForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellSheetg', WeelN)
else:
form_error = 'Check your file Name, type and size <10Mb'
context ={
'title': 'SearchWS',
'Wellslistsh':serchedWl,
'WeelN':WeelN,
'form':form,
'form_error': form_error,
}
return render(request,'Home/WELLINFO/W_TchD/wellshts.html', context)
and in my Html :
{% if form %}
<div class="w3-panel w3-light-grey w3-round-large solid"">
<form method="POST" id="formOne" enctype= multipart/form-data>
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.WellID|as_crispy_field }}</div></div>
{% if form_error %}
<li style="color:red;"><strong>Check the Well if it does exist</strong></li>
{% endif %}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.FileNm|as_crispy_field }}</div></div>
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.Folio|as_crispy_field }}</div></div>
<div class="form-row">
<div class="form-group col-md-8 mb-0">
{{ form.SHRPath }}</div></div>
{% if form_error %}
<li style="color:red;"><strong>{{form_error}}</strong></li>
<li style="color:red;"><strong>File type (pdf, jpg ,xls..) only accepted</strong></li>
{% endif %}
<p style="color:red;">Maximum upload size is 10Mb</p>
<br>
<input class="btn btn-success mb-6" data-target="#myModal" name="form_uplod" type="submit" value="AddSheet">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>
{% endif %}
and I creted a validators.py and in it:
def validate_file_size(value):
filesize= value.size
print('very nice',filesize/(1024*1024))
if filesize > 1024*1024*10:
raise ValidationError(_("The maximum file size that can be uploaded is 10MB"), code='invalid')
return value
def validate_text(value):
from Home.models import Wellinfo
WELDATA= Wellinfo.objects.filter(WellID=value)
print(value, WELDATA)
if Wellinfo.objects.filter(WellID=value).exists():
return value
raise ValidationError("The Well does't exists!")
and at last in the model.py i called the decorator as;
class WellSheets(models.Model):
WellID = models.CharField(max_length=15, validators= [validate_text])
FileNm = models.CharField(max_length=15)
Folio = models.PositiveIntegerField(blank=True, null=True)
SHRPath = models.FileField(upload_to='Well_sheets/', validators= [validate_file_size])
at the end the file will not added or uploaded and when I cambak to my modal window I see that
Description of modal window

Django CSRF token missing or incorrect but CSFR has been added

Django give me the following error CSRF token missing or incorrect. but I don't find the issue.
I have created my forms:
class ModCollaboratoriForm(forms.ModelForm):
class Meta:
model = AltriCosti
fields = "__all__"
and my simple views.py:
def collaboratori_commessa(request):
collaboratori_commessa=AltriCosti.objects.all()
if request.method == 'POST':
form = ModCollaboratoriForm(request.POST)
if form.is_valid():
print("Il form è valido")
new_input = form.save()
else :
form = ModCollaboratoriForm()
context={
'form':form,
'collaboratori_commessa': collaboratori_commessa,
}
return render(request, 'commesse/collaboratori_commessa.html', context)
And in my collaboratori_commessa.htm the following form:
<form id="contact-form" name="contact-form" method="post" >
{% csrf_token %}
<div class="card card-outline card-info shadow ">
<div class="card-header ">
<h4 class="mb-0">
<img src="{% static 'icon/plus-circle.svg' %}"> Informazioni generali
</h4>
</div>
<div class="card-body">
{{ form.media }}
<div class="row">
<div class="form-group col-2 0 mb-0" >
{{form.codice_commessa|as_crispy_field}}
</div>
.....
</div>
<div class="card-footer">
<div class="col-md-2">
<button class="btn btn-info form-control" type="submit" onclick="submitForm()">Registra</button>
</div>
</div>
</form>
Why django give me the CSRF Error?

Issues with two forms submission in django one after another

I'm working on forget password page in which the user first have to answer the question for enabling the textfields for creating new password.
Here, I have two forms, One for security question and second for password and confirm password.
Following is my forms.py
from django import forms
from .models import SecurityQuestions
class PasswordForm(forms.Form):
password = forms.CharField(disabled=True, widget=forms.PasswordInput(attrs={'placeholder':'New Password'}))
password_confirm = forms.CharField(disabled=True, widget=forms.PasswordInput(attrs={'placeholder':'Re-enter Password'}))
def clean(self, *args,**kwargs):
password = self.cleaned_data.get('password')
password_confirm = self.cleaned_data.get('password_confirm')
if password and password_confirm:
if password != password_confirm:
raise forms.ValidationError('Password Mismatch')
return super(PasswordForm, self).clean(*args, **kwargs)
class PasswordVerificationForm(forms.Form):
question = forms.ModelChoiceField(queryset=SecurityQuestions.objects.all(), empty_label=None, widget=forms.Select(attrs={'class':'form-control','id': 'sectxt'}))
answer = forms.CharField(label='answer', widget=forms.TextInput(attrs={'placeholder':'Answer','id': 'anstxt'}))
Following is my views.py
from django.shortcuts import render, redirect
from .forms import PasswordForm, PasswordVerificationForm
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.hashers import make_password
from .models import SecurityQuestions
from django.contrib import messages
#login_required
#csrf_exempt
def password_reset(request):
form = PasswordForm(request.POST or None)
form1 = PasswordVerificationForm(request.POST or None)
if request.method == 'POST':
if request.POST.get("verify", False):
question = request.POST.get('question')
answer = request.POST.get('answer')
print("question",question)
print("answer",answer)
check = SecurityQuestions.objects.get(id=question) #id=1
print(check.answer)
if check.answer == answer:
messages.success(request, 'Enter Your New Password', 'alert-success')
form.fields['password'].disabled = False
form.fields['password_confirm'].disabled = False
else:
redirect('/')
messages.error(request, 'Incorrect Answer', 'alert-danger')
if request.POST.get("create", False):
if form.is_valid():
print("For Changing Password...")
password = form.cleaned_data.get('password')
request.user.password = make_password(password)
request.user.save()
return redirect('/')
else:
form = PasswordForm()
form1 = PasswordVerificationForm()
return render(request,"forget_password.html", {"form": form, "form1":form1})
Following is my forget_password.html
<div class="container">
<div class="main">
<div class="row justify-content-center">
<div class="col-md-4">
<div class="login-form">
<div class="row">
<div class="col-md-12">
<div class="login-title-holder">
<h4>Forgot Password</h4>
</div>
</div>
<form method="post">
<div class="form-group col-md-12">
<div class="input-group">
{{ form1.question | add_class:'form-control' }}
<span class="input-group-append">
<div class="input-group-text input-group-icon"><i class="fa fa-question" aria-hidden="true"></i></div>
</span>
</div>
</div>
<div class="form-group col-md-12">
<div class="input-group">
{{ form1.answer | add_class:'form-control' }}
<span class="input-group-append">
<div class="input-group-text input-group-icon "><i class="fa fa-comment" aria-hidden="true"></i></div>
</span>
</div>
</div>
<div class="col-md-12">
{% if messages %}
{% for message in messages %}
<div {% if message.tags %} class="alert {{ message.tags }} text-center"{% endif %}>
×
{{ message }}
</div>
{% endfor %}
{% endif %}
<input type="submit" name = "verify" formmethod="post" style="visibility: hidden;">
</div>
</form>
<form method="post">
<div class="form-group col-md-12">
<div class="input-group">
{{ form.password | add_class:'form-control' }}
<span class="input-group-append">
<div class="input-group-text input-group-icon"><i class="fa fa-key" aria-hidden="true"></i></div>
</span>
</div>
</div>
<div class="form-group col-md-12">
<div class="input-group">
{{ form.password_confirm | add_class:'form-control' }}
<span class="input-group-append">
<div class="input-group-text input-group-icon"><i class="fa fa-key" aria-hidden="true"></i></div>
</span>
</div>
</div>
<div class="col-md-12">
<div class="button-holder">
Cancel
<button class="login-btn" type="submit" formmethod="post" name="create">Create</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
If I enter the security answer first, based on the condition, if true, it enables the textfields for password and password_confirm.
But it's not creating the new password.
However, if I change the disabled = False in PasswordForm then it creating the new password successfully.
I want to know why it's not executing the code after the first form executes successfully.
Thanks!
You really should chain this into 2 urls, rather then trying 2 forms in one page. You can only submit one form and this is the problem you're facing. Once you have submitted the security question, you instantiate the form again with fields disabled:
form = PasswordForm(request.POST or None)
And now they do not get enabled, because the submit button called 'verify' from form1 is no longer present, so the code in that branch is not executed.
Let's say url is /password_reset/ - a rough outline (untested):
#login_required
#csrf_exempt
def security_question(request):
form = PasswordVerificationForm(request.POST)
if request.method == 'POST':
if form.is_valid():
token = generate_strong_token() # Implement: generate a strong token, url safe
request.session["password_reset_token"] = token
return redirect(f'/password_reset/{token}/')
else:
return render(...)
#login_required
#csrf_exempt
def change_password(request, **kwargs):
form = PasswordForm(request.POST)
token = request.session.get('password_reset_token')
if token == kwargs['token']:
if request.method == 'POST' and form.is_valid():
del request.session['password_reset_token']
# handle password change and redirect to wherever
else:
return render(...)
else:
raise SecurityError('Invalid token')
Your urls would be something like:
urlpatterns = [
re_path('password_reset/(?P<token>[0-9A-F]{32})/', change_password)
path('password_reset/', security_question)
]

Django modelformset_factory deleting objects marked by can_delete

Hello I have got question I have made modelformset_factory and in options I have choosen can_delete = True and now I don't know how to delete marked objects as 'DELETE' : True to delete them from database. I was trying to do this in some ways and it didnt work. I was looking for it also in django formsetmodels documentation but this didnt help me. With this option can_delete = True I get additional checkbox in my html page Delete and marking him only prints me in console on print:
{'username': 'sw', 'email': 'a#gmail.com', 'city': 'ss', 'code': 12345, 'id': , 'DELETE': False}
Saving forms to database is working but I dont know how to delete marked forms from database.
I would be very thankful for every help.
I have made modelformset_factory from model in models.py
class TestModel(models.Model):
username = models.CharField(max_length=120)
email = models.EmailField()
city = models.CharField(max_length=120)
code = models.IntegerField()
#W admin panelu za miast TestModel object bedzie username
def __str__(self):
return self.username
Then I have added in my views.py function:
def django_modelformset(request):
TestModelFormset = modelformset_factory(TestModel, fields=['username', 'email', "city",
"code"], extra=1, can_delete=True)
formset = TestModelFormset(request.POST or None)
if formset.is_valid():
for form in formset:
print(form)
print(form.cleaned_data)
form.save()
context = {"formset": formset}
return render(request, "modelformset.html", context)
My modelformset.html looks like this:
<form method="POST" action="">
{% csrf_token %}
{{ formset.management_form}}
{% for form in formset %}
<div>
{{ form.as_p }}
<hr/>
</div>
{% endfor %}
<input type="submit" value="Save">
I haven't personally had to do this, but from the docs it seems you have a few options.
Call save on the formset instead of each form.
if formset.is_valid():
formset.save()
If you must loop through each form you could something like this.
if formset.is_valid():
for form in formset:
print(form.cleaned_data)
if form.cleaned_data["DELETE"]:
# Do what you want with the form data
# i.e. get the object from the database and delete it.
else:
form.save()
Loop through the deleted forms separately.
if formset.is_valid():
forms = formset.save(commit=False)
for object in formset.deleted_objects:
object.delete()
It's work for me
view.py
Blog_MetaFormSet = modelformset_factory(Metas, form=MetaForm, extra=0, can_delete=True)
Blog_MetaQuerySet = Metas.objects.filter(blog=blog_obj).order_by('created_at')
contex={
"blog_meta_formset": Blog_MetaFormSet(request.POST,queryset=Blog_MetaQuerySet),
}
if blog_meta_formset.is_valid():
for metaform in blog_meta_formset:
meta_obj = metaform.save(commit=False)
meta_obj.blog = blog_obj
if metaform.cleaned_data["DELETE"]==True:
meta_obj.delete()
else:
meta_obj.save()
In Templates
<div class="row">
<div id="cfield-form-list"> {{ blog_meta_formset.management_form }} {% for meta_form in blog_meta_formset %}
<div id="form-{{forloop.counter0}}" class="cfield-form xrow">
<div class="col-md-12 mb-3">
<div class="row d-flex align-items-center">
<div class="col-md-4">
<label class="form-label">Name</label> {{ meta_form.title|attr:"class:form-control"|attr:"type:text" }} </div>
<div class="col-md-4">
<label class="form-label">Value</label> {{ meta_form.value|attr:"class:form-control"|attr:"rows:2" }} </div>
<div class="col-md-4">
<div class="form-check custom-checkbox mb-3 checkbox-primary"> {{ meta_form.DELETE|attr:"class:form-check-input"|attr:"type:checkbox" }}
<label class="form-check-label" for="customCheckBox2">Delete</label>
</div>
</div>
</div>
</div> {{meta_form.id}} </div> {% endfor %} </div>
<div id="empty_form" class="hidden">
<div class="col-md-12 mb-3">
<div class="row d-flex align-items-center">
<div class="col-md-4">
<label class="form-label">Name</label> {{ blog_meta_formset.empty_form.title|attr:"type:text"|attr:"class:form-control" }} </div>
<div class="col-md-4">
<label class="form-label">Value</label> {{ blog_meta_formset.empty_form.value|attr:"class:form-control"|attr:"rows:2" }} </div>
<div class="col-md-4">
<div class="form-check custom-checkbox mb-3 checkbox-primary"> {{ blog_meta_formset.empty_form.DELETE|attr:"class:form-check-input"|attr:"type:checkbox" }}
<label class="form-check-label" for="customCheckBox2">Delete</label>
</div>
</div>
<div class="col-md-4">
<button type="button" class="btn btn-danger remove_cfield" rel="">Delete</button>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<button type="button" id="add-cfield" class="btn btn-primary mb-3 mt-3 ">Add Custom Field</button>
</div>
</div>
In js
const totalNewForms = document.getElementById('id_form-TOTAL_FORMS')
const addMoreBtn = document.getElementById('add-cfield')
addMoreBtn.addEventListener('click',add_new_form)
function add_new_form(event){
if (event){
event.preventDefault()
}
const currentCF_Forms = document.getElementsByClassName('cfield-form')
console.log(currentCF_Forms)
const currentCF_FormCount = currentCF_Forms.length //+ 1
const formCopyTarget = document.getElementById('cfield-form-list')
const copyEmptyFormEl = document.getElementById('empty_form').cloneNode(true)
//remove class hidden
copyEmptyFormEl.setAttribute('class','cfield-form xrow')
copyEmptyFormEl.setAttribute('id',`form-${currentCF_FormCount}`)
const regex = new RegExp('__prefix__','g')
copyEmptyFormEl.innerHTML = copyEmptyFormEl.innerHTML.replace(regex,currentCF_FormCount)
totalNewForms.setAttribute('value', currentCF_FormCount +1)
//now add new empty form element to our html form
formCopyTarget.append(copyEmptyFormEl)