I have a contact form and i'm using Ajax to submit the form. However i have a problem i cannot figure out how to display error messages, to notify user that has entered wrong data. For example name field accepts only letters, also i'm using PhoneNumberField to check phone.
<p id="error_1_id_name" class="invalid-feedback"><strong>Wrong First Name, use only letters</strong></p>
Enter a valid phone number (e.g. +12125552368).
When submitting the form with invalid data for example enter name with numbers i'm getting
When entering correct data everything works as expected.
Any help is appreciated.
views.py
def contact(request):
form = ContactForm(request.POST or None)
data = {}
if request.is_ajax():
if form.is_valid():
form.save()
data['name'] = form.cleaned_data.get('name')
data['status'] = 'ok'
return JsonResponse(data)
context = {
'form': form,
}
return render(request, 'pages/contact.html', context)
main.js
const alertBox = document.getElementById('alert-box')
const form = document.getElementById('contact')
const name = document.getElementById('id_name')
const email = document.getElementById('id_email')
const phone = document.getElementById('id_phone')
const subject = document.getElementById('id_subject')
const budget_range = document.getElementById('id_budget_range')
const message = document.getElementById('id_message')
const csrf = document.getElementsByName('csrfmiddlewaretoken')
console.log(csrf)
const url = ""
const handleAlerts = (type, text) =>{
alertBox.innerHTML = `<div class="alert alert-${type}" role="alert">
${text}
</div>`
}
form.addEventListener('submit', e=>{
e.preventDefault()
const fd = new FormData()
fd.append('csrfmiddlewaretoken', csrf[0].value)
fd.append('name', name.value)
fd.append('email', email.value)
fd.append('phone', phone.value)
fd.append('subject', subject.value)
fd.append('budget_range', budget_range.value)
fd.append('message', message.value)
$.ajax({
type: 'POST',
url: url,
data: fd,
success: function(response){
console.log(response)
const sText = `successfully saved ${response.name}`
handleAlerts('success', sText)
setTimeout(()=>{
alertBox.innerHTML = ""
name.value = ""
email.value = ""
phone.value = ""
subject.value = ""
budget_range.value = ""
message.value = ""
}, 3000)
},
error: function(error){
console.log(error)
handleAlerts('warning', 'ups...something went wrong')
},
cache: false,
contentType: false,
processData: false,
})
})
console.log(form)
contact.html
<div class="col-lg-6">
<div class="form-box">
<h3>Write A Comment</h3>
<form class="form" id="contact" method="POST" action="" autocomplete="off">
{% csrf_token %}
<div class="messages"></div>
<div class="input__wrap controls">
<div class="form-group">
<div class="entry">
<!--<label>What's your name?</label>-->
{{ form.name|as_crispy_field }}
</div>
<!--<div class="help-block with-errors"></div>-->
</div>
<div class="form-group">
<div class="entry">
<!--<label>What's your email address?</label>-->
{{ form.email|as_crispy_field }}
</div>
<!--<div class="help-block with-errors"></div>-->
</div>
<div class="form-group">
<div class="entry">
<!--<label>What's your email address?</label>-->
{{ form.phone|as_crispy_field }}
</div>
<!--<div class="help-block with-errors"></div>-->
</div>
<div class="form-group">
<div class="entry">
<!--<label>Subject</label>-->
{{ form.subject|as_crispy_field }}
</div>
<!--<div class="help-block with-errors"></div>-->
</div>
<div class="form-group">
<div class="entry">
<!--<label>What's your budget range?</label>-->
{{ form.budget_range|as_crispy_field }}
</div>
<!--<div class="help-block with-errors"></div>-->
</div>
<div class="form-group">
<div class="entry">
<!--<label>What's up?</label>-->
{{ form.message|as_crispy_field }}
</div>
<!--<div class="help-block with-errors"></div>-->
</div>
<div class="image-zoom" data-dsn="parallax">
<input type="submit" value="Send Message" class="btn" style="color: #75DAB4">
</div>
<div id="alert-box"</div>
</div>
</form>
</div>
</div>
</div>
This is the output:
<!DOCTYPE html>
<html lang="en-US">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="discrption" content="parallax one page" />
<meta name="keyword"
content="agency, business, corporate, creative, freelancer, interior, joomla template, K2 Blog, minimal, modern, multipurpose, personal, portfolio, responsive, simple" />
<!-- Title -->
<title>Impruves - Digital Agency</title>
<!-- Font Google -->
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,500,600,700,800&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Raleway:400,500,600,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon" />
<link rel="icon" href="/static/img/favicon.ico" type="image/x-icon" />
<!-- custom styles (optional) -->
<link href="/static/css/plugins.css" rel="stylesheet" />
<link href="/static/css/style.css" rel="stylesheet" />
</head>
<body class="hamburger-menu dsn-effect-scroll dsn-ajax" data-dsn-mousemove="true">
<div class="preloader">
<div class="preloader-after"></div>
<div class="preloader-before"></div>
<div class="preloader-block">
<div class="title">Impruves</div>
<div class="percent">0</div>
<div class="loading">loading...</div>
</div>
<div class="preloader-bar">
<div class="preloader-progress"></div>
</div>
</div>
<!-- Nav Bar -->
<div class="dsn-nav-bar">
<div class="site-header">
<div class="extend-container">
<div class="inner-header">
<div class="main-logo">
<a href="/">
<img class="dark-logo" src="/static/img/logo-dark.png" alt="" />
<img class="light-logo" src="/static/img/logo.png" alt="" />
<!--<span>Impruves</span>-->
</a>
</div>
</div>
<nav class=" accent-menu main-navigation">
<ul class="extend-container">
<li><a href="/">Home</a></li>
<li><a href="/work/">Work</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
</div>
</div>
<div class="header-top header-top-hamburger">
<div class="header-container">
<div class="logo main-logo">
<a href="/">
<img class="dark-logo" src="/static/img/logo-dark.png" alt="" />
<img class="light-logo" src="/static/img/logo.png" alt="" />
</a>
</div>
<div class="menu-icon" data-dsn="parallax" data-dsn-move="5">
<div class="icon-m">
<i class="menu-icon-close fas fa-times"></i>
<span class="menu-icon__line menu-icon__line-left"></span>
<span class="menu-icon__line"></span>
<span class="menu-icon__line menu-icon__line-right"></span>
</div>
<div class="text-menu">
<div class="text-button">Menu</div>
<div class="text-open">Open</d