Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 除非提交两次,否则不提交表格。Ajax、香草js、django_Javascript_Django_Ajax - Fatal编程技术网

Javascript 除非提交两次,否则不提交表格。Ajax、香草js、django

Javascript 除非提交两次,否则不提交表格。Ajax、香草js、django,javascript,django,ajax,Javascript,Django,Ajax,我试图提交一个带有AJAX和香草JavaScript的Django表单,但是除非我两次单击submit按钮,否则表单实际上不会提交 我在表单上有一个事件侦听器,它停止默认提交以避免重新加载页面,然后打开一个XMLHttpRequest。在第一次提交时,我得到了200条回复,但数据实际上还没有发送到数据库。但是,如果我再次单击submit按钮,我会从服务器获得所需的201(item created)响应,它会重新加载我的帖子并添加新帖子 我对使用异步数据仍然有点不熟悉,无法理解它为什么不工作。如果

我试图提交一个带有AJAX和香草JavaScript的Django表单,但是除非我两次单击submit按钮,否则表单实际上不会提交

我在表单上有一个事件侦听器,它停止默认提交以避免重新加载页面,然后打开一个XMLHttpRequest。在第一次提交时,我得到了200条回复,但数据实际上还没有发送到数据库。但是,如果我再次单击submit按钮,我会从服务器获得所需的201(item created)响应,它会重新加载我的帖子并添加新帖子

我对使用异步数据仍然有点不熟悉,无法理解它为什么不工作。如果我删除e.preventDefault,表单将正确提交,新帖子将在页面重新加载后显示

相关JS代码段:

const postCreateFormEl = document.getElementById("post-create-form")
const postsEl = document.getElementById("posts")

const handlePostSubmit = function(e){
    e.preventDefault()    
    const myForm = e.target
    const myFormData = new FormData(myForm)
    const url = myForm.getAttribute("action")
    const method = myForm.getAttribute("method")
    const xhr = new XMLHttpRequest()

    xhr.open(method, url)
    xhr.setRequestHeader("HTTP_X_REQUESTED_WITH", "XMLHttpRequest")
    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
    xhr.onload = function() {
        const serverResponse = xhr.response
        console.log(serverResponse, xhr.status)
        const postsEl = document.getElementById("posts")
        loadPosts(postsEl)         
    }
    xhr.send(myFormData)   
}

postCreateFormEl.addEventListener("submit", handlePostSubmit)
django视图片段:

def home_view(request, *args, **kwargs):
    form = PostForm()
    return render(request, "pages/home.html", context={'form': form})

def post_create_view(request, *args, **kwargs):
    form = PostForm(request.POST or None)
    next_url = request.POST.get("next") or None
    if form.is_valid():
        obj = form.save(commit=False)
        obj.save()
        if request.is_ajax():
            return JsonResponse({"success": "Object created"}, status=201)
        if next_url != None and is_safe_url(next_url, ALLOWED_HOSTS):
            return redirect(next_url)
        form = PostForm()
    return render(request, 'components/form.html', context={"form": form})
在控制台中的第一次提交时,它返回事件目标,在第二次提交时,它返回预期的jsonresponse。任何方向都是感激的

编辑:

home.html:

<form class='form' id='post-create-form' method='POST' action='/create-post'>
    <input type='hidden' value='/' name='next'/>    
    {% csrf_token %}
    {{ form.media }}
    {{ form.as_p }}
    <input type='submit' value='submit'>
</form>

大多数所见即所得编辑器不会编辑用户输入时将提交的实际输入元素。相反,他们所做的是在提交此类表单时附加一个事件,然后在提交表单时设置输入值。CKEditor对此也不例外,它也这样做

因此,这里发生的事情是,您提交表单,并且您的onsubmit处理程序首先启动。不幸的是,这意味着当您通过ajax提交表单时,输入永远不会被填充,但是在ajax调用之后,输入确实会被填充。这就是你第二次提交成功的原因

要解决这个问题,您可以让CKEditor自己在提交时更新输入值。这样修改脚本,并确保脚本位于加载表单媒体的下方:

const handlePostSubmit = function(e){
    e.preventDefault()
    for (instance in CKEDITOR.instances) {
        CKEDITOR.instances[instance].updateElement();
    }
    // Rest of your function
}

请显示您的模板/html。我假设您在
主视图中呈现此表单
?然后请显示
页面/home.html
的相关部分。另外,请展示你的url模式。除了表单和div,home.html里面真的没有太多内容,我发布了帖子和我之前共享的所有JavaScript代码。我有一种感觉,这可能与ckeditor有关。我已经按照要求用url模式和home.html编辑了我的文章。还添加了forms.py以防万一
class PostForm(forms.ModelForm):
    content = forms.CharField(widget=CKEditorUploadingWidget())
    class Meta:
        model = Post
        fields = '__all__'
    def clean_content(self):
        content = self.cleaned_data.get("content")
        if len(content) > MAX_POST_LENGTH:
            raise forms.ValidationError("This post is too long")
        return content
const handlePostSubmit = function(e){
    e.preventDefault()
    for (instance in CKEDITOR.instances) {
        CKEDITOR.instances[instance].updateElement();
    }
    // Rest of your function
}