显示错误时以Django形式保持焦点

时间:2018-07-27 10:50:46

标签: django html5 django-forms

我有一个主页视图,其中有一个页脚可以联系。一切工作正常,除了在表单中出现错误并且视图重新显示具有相应错误的所有内容时,它不会将焦点保持在表单中(它显示的视图就像您是第一次输入一样,并且因此除非向下滚动,否则用户看不到他们的表格不正确)。

我曾经考虑过用JS发送消息,但这确实很丑陋。 我尝试了所有发现错误的方法(从不同的功能引发错误),但问题仍然存在。

有什么主意吗?

此外,即使我将required设置为False,该表单仍会显示一条消息(“ Complete this field”),我认为该消息来自html,如何删除它?

非常感谢您!

代码:

<form method="post">
		{% csrf_token %}

		{{ form.non_field_errors }}


<div class="fieldWrapper">
    {{ form.message.errors }}
    <label for="{{ form.message.id_for_label }}">Your message:</label>
    {{ form.message }}
</div>
<div class="fieldWrapper">
	<strong>{{ form.mail.errors }}</strong>
    
    <label for="{{ form.mail.id_for_label }}">Your email address:</label>
    {{ form.mail }}
</div>
<div class="fieldWrapper">
    {{ form.number.errors }}
    <label for="{{ form.number.id_for_label }}">CC yourself?</label>
    {{ form.number }}
</div>



		<button type="submit" class="btn btn-primary">Submit</button>
	</form>

class ContactForm(forms.Form):
	mail    = forms.CharField(required=False, label=_('Mail'))
	number  = forms.CharField(required=False, label=_('Number'))
	message = forms.CharField(min_length = 0, max_length=500, label=_('Message'))

	def clean_mail(self):
		mail = self.cleaned_data['mail']
		
		if '@' not in mail:
			raise ValidationError({"mail": _('The mail should contain "@"')})

		return mail

1 个答案:

答案 0 :(得分:0)

  

有什么主意吗?

我有一个使用jquery验证插件的想法,但是不确定是否可以在项目中使用它。与Django错误消息(error_messages)集成非常简单。让我解释一下。

  1. 第一个:JavaScript中的函数,用于检查是否需要发送csrf:

    function csrfSafeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    
  2. 第二:如果需要动态显示一般错误(非字段错误),则可以在JavaScript中使用。

    function showGenericErrors(errorMessages, id) {
        len = errorMessages.length
        if (len > 0) {
        errorDiv = `
        <div class="alert alert-danger alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>`;
            for (var i = 0; i < len; i++) {
                errorDiv += errorMessages[i];
                errorDiv += (i === len-1) ? '' : '<br>';
            }
            errorDiv += '</div>';
            $(errorDiv).insertAfter($('SOME_ELEMENT_OF_YOUR_PREFERENCE'));
        }
    }
    
  3. 第三:您认为Django响应中包含JsonResponse(请记住->从django.http导入Json响应)。

    return JsonResponse({'messages': form.errors}, status=500, safe=False)
    
  4. 第四:激活jquery验证插件并使用ajax处理您的Submit事件,以将数据发送到Django以进行验证。

    form = $('form');
    var $validator = $(form).validate({
        rules: {
            mail: {
                required: true,
                email: true
            },
            number: {
                required: true,
                minlength: 7,
                maxlength: 15
            },
            message: {
                required: true,
                maxlength: 500
            },
        },
        messages: {
            mail: {
                required: 'Mail required',
                email: 'Invalid mail'
            },
            number: {
                required: 'Number required',
                minlength: 'Please enter at least {0} characters', //{0} will take the minlength specified in rules
                maxlength: 'Please enter no more than {0} characters'
            },
            message: {
                required: 'Message required',
                maxlength: 'Please enter no more than {0} characters'
            },
        },
        submitHandler: function(form) {
            $('.alert').remove();
            var formData = new FormData(form);
            $.ajax({
                url: 'contactus',
                type: 'POST',
                data: formData,
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader('X-CSRFToken', $('[name=csrfmiddlewaretoken]').val());
                    }
                },
                success: function(data) {
                    console.log(data);
                },
                error: function(xhr) {
                    console.log(xhr.responseJSON);
                    data = xhr.responseJSON;
                    if (data.messages) {
                        genericErrors = [];
                        fieldErrors = {};
                        for (var i in data.messages) {
                            if (i === '__all__') {
                                genericErrors = data.messages[i];
                            } else {
                                fieldErrors[i] = data.messages[i][0];
                            }
                        }
                        $validator.showErrors(fieldErrors);
                        showGenericErrors(genericErrors, id);
                    }
                },
                cache: false,
                contentType: false,
                processData: false
            });
        },
        errorElement: "em",
        errorPlacement: function(error, element) {
            error.addClass("help-block");
    
            if (element.prop("type") === "checkbox") {
                error.insertAfter(element.parent("label"));
            } else {
                error.insertAfter(element);
            }
        },
        highlight: function(element, errorClass, validClass) {
            $(element).parents(".fieldWrapper").addClass("has-error").removeClass("has-success");
        },
        unhighlight: function(element, errorClass, validClass) {
            $(element).parents(".fieldWrapper").addClass("has-success").removeClass("has-error");
        }
    });