Django/Js:如何在不重新加载整个页面的情况下发布表单 [英] Django/Js: how to post a form without reloading whole page

查看:44
本文介绍了Django/Js:如何在不重新加载整个页面的情况下发布表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序当前流经3页:

My application currently flows through 3 pages:

  1. 用户在索引页面中选择问题
  2. 用户在答案页面中提交答案
  3. 在结果页面中向用户显示结果.

我想将其压缩到单个页面,用户在该页面上提交问题的答案,结果显示在同一页面上.

I want to compress that down to a single page where the user submits an answer to the question and result is shown on the same page.

以下 django-template 代码使用Bootstrap手风琴分隔问题.如何在不刷新整个页面的情况下发布表单?我希望能够在页面上显示结果,使用Javascript等更新CSS样式.

The following django-template code separates questions with Bootstrap accordion. How do I post the form without refreshing the whole page? I want to be able to display the result on the page, update CSS styling with Javascript etc.

<h2>{{ category.title }}</h2>
    <div class="accordion" id="accordion{{category.title}}">

      {% for challenge in category.challenge_set.all %} 
      <div class="card">
        <div class="card-header" id="heading{{challenge.id}}">
          <h2 class="mb-0">
            <button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapse{{challenge.id}}" aria-expanded="true" aria-controls="collapse{{challenge.id}}">
              {{ challenge.question_text }} - {{ challenge.point_value }} points
            </button>
          </h2>
        </div>
        <div id="collapse{{challenge.id}}" class="collapse in" aria-labelledby="heading{{challenge.id}}" data-parent="#accordion{{category.title}}">
          <div class="card-body">
            
            <p>{{ challenge.description }}</p>
          
            <form action="{% url 'challenges:answer' challenge.id %}" method="post">
            
              {% if challenge|is_answered:request %}
                <label for="answered">Answer</label>
                <input type="text" name="answered" id="answered" value="{{ challenge.answer_text }}" readonly>
              {% else %}
              {% csrf_token %}
                <label for="answer">Answer</label>
                <input type="text" name="answer" id="answer">
                <input type="submit" value="Submit">
              {% endif %}
            </form>
        </div>
      </div>
      {% endfor %}

    </div>

这是视图:

def index(request):
    context = {'challenges_by_category_list': Category.objects.all()}
    return render(request, 'challenges/index.html', context)

def detail(request, challenge_id):
    challenge = get_object_or_404(Challenge, pk=challenge_id)
    return render(request, 'challenges/detail.html', {'challenge': challenge})

def results(request, challenge_id, result):
    challenge = get_object_or_404(Challenge, pk=challenge_id)
    return render(request, 'challenges/results.html', {'challenge':challenge, 'result':result})

def answer(request, challenge_id):
    challenge = get_object_or_404(Challenge, pk=challenge_id)
    result = "Incorrect, try again!"
    if challenge.answer_text.lower() == request.POST['answer'].lower():
      current_user = request.user
      session = User_Challenge(user=current_user, challenge=challenge, answered=True)
      session.save()
      points = Profile(user=current_user, points=challenge.point_value)
      points.save()
      result = "Correct!"
    return HttpResponseRedirect(reverse('challenges:results', args=(challenge.id, result)))

推荐答案

您可以尝试以下操作:

在模板中添加以下脚本:

Add the below script in your template:

<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>

编写脚本和其中的函数以提交表单数据.

write a script and a function inside it to submit the form data.

<script type="text/javascript">
    function submitData( challenge_id ){
        // Get answer from the input element
        var answer = document.getElementById("answer").value;

        // add the url over here where you want to submit form & challenge_id is also taken as a parameter.
        var url = "<your_url>";

        $.ajax({
            url: url,
            data: {
                'answer': answer,
            },
            dataType: 'JSON',
            success: function(data){
                // show an alert message when form is submitted and it gets a response from the view where result is provided and if url is provided then redirect the user to that url.
                alert(data.result);
                if (data.url){
                   window.open(data.url, '_self');
                }
            }
        });
    }
</script>

更改提交按钮的类型,并添加onclick事件以调用 submitData()函数,并将质询ID传递给该函数.并从表单中删除操作attr.见下文:

Change type of the submit button and add an onclick event to call the submitData() function and pass the challenge id to it. And remove the action attr from the form. see below:

<form method="post">
    {% csrf_token %}
    {% if challenge|is_answered:request %}
        <label for="answered">Answer</label>
        <input type="text" name="answered" id="answered" value="{{ challenge.answer_text }}" readonly>
    {% else %}
        <label for="answer">Answer</label>
        <input type="text" name="answer" id="answer">
        // over here
        <button type="button" onclick="submitData({{ challenge.id }})">
            Submit
        </button>
    {% endif %}
</form>

从视图返回对Ajax调用的JsonReponse.

Return a JsonReponse to the ajax call from the views.

views.py

def answer(request, challenge_id):
    answer = request.GET.get('answer', False)
    url = False
    if challenge.objects.filter(id=challenge_id).exists() and answer:
       challenge = Challenge.objects.get(id=challenge_id)
       if challenge.answer_text.lower() == answer.lower():
          current_user = request.user
          session = User_Challenge(user=current_user, challenge=challenge, answered=True)
          session.save()
          points = Profile(user=current_user, points=challenge.point_value)
          points.save()
          result = "Correct!"
  
          # specify the url where you want to redirect the user after correct answer
          url = "" 
    else:
       result = "Incorrect, try again!"
    data = {
       'result': result,
       'url': url
    }
    return JsonResponse(data)

这篇关于Django/Js:如何在不重新加载整个页面的情况下发布表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆