I found a similar question that is pretty out of date. I wonder if this is possible without using another library.
Currently forms.ValidationErrorstarts form_invalid, which will return a JSON response only with an error code and status.
I have an ajax form and am wondering if the regular fields of the django field in the form field after the ajax submit can submit.
My form is throwing an error:
class PublicToggleForm(ModelForm):
class Meta:
model = Profile
fields = [
"public",
]
def clean_public(self):
public_toggle = self.cleaned_data.get("public")
if public_toggle is True:
raise forms.ValidationError("ERROR")
return public_toggle
Corresponding View mixin for ajax:
from django.http import JsonResponse
class AjaxFormMixin(object):
def form_invalid(self, form):
response = super(AjaxFormMixin, self).form_invalid(form)
if self.request.is_ajax():
return JsonResponse(form.errors, status=400)
else:
return response
def form_valid(self, form):
response = super(AjaxFormMixin, self).form_valid(form)
if self.request.is_ajax():
print(form.cleaned_data)
print("VALID")
data = {
'message': "Successfully submitted form data."
}
return JsonResponse(data)
else:
return response
View:
class PublicToggleFormView(AjaxFormMixin, FormView):
form_class = PublicToggleForm
success_url = '/form-success/'
In the browser console, errors will occur as 400 Bad Request, followed by responseJSON, which has the correct ValidationError message.
Edit: Any way to get field validation to display on client side?
edit: Additional code:
, :
{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}
abort:
ƒ (a)
always:
ƒ ()
catch:
ƒ (a)
done:
ƒ ()
fail:
ƒ ()
getAllResponseHeaders:
ƒ ()
getResponseHeader:
ƒ (a)
overrideMimeType:
ƒ (a)
pipe:
ƒ ()
progress:
ƒ ()
promise:
ƒ (a)
readyState:
4
responseJSON:
public:
["ERROR"]
__proto__:
Object
responseText:
"{"public": ["ERROR"]}"
setRequestHeader:
ƒ (a,b)
state:
ƒ ()
status:
400
statusCode:
ƒ (a)
statusText:
"Bad Request"
then:
ƒ (b,d,e)
__proto__:
Object
Django {{as_p}}:
{% if request.user == object.user %}
Make your profile public?
<form class="ajax-public-toggle-form" method="POST" action='{% url "profile:detail" username=object.user %}' data-url='{% url "profile:public_toggle" %}'>
{{public_toggle_form.as_p|safe}}
</form>
{% endif %}
Javascript:
$(document).ready(function(){
var $myForm = $('.ajax-public-toggle-form')
$myForm.change(function(event){
var $formData = $(this).serialize()
var $endpoint = $myForm.attr('data-url') || window.location.href
$.ajax({
method: "POST",
url: $endpoint,
data: $formData,
success: handleFormSuccess,
error: handleFormError,
})
})
function handleFormSuccess(data, textStatus, jqXHR){
console.log(data)
console.log(textStatus)
console.log(jqXHR)
}
function handleFormError(jqXHR, textStatus, errorThrown){
console.log(jqXHR)
console.log("==2" + textStatus)
console.log("==3" + errorThrown)
$myForm[0].reset();
}
})