0

I have a function in views.py which takes input (through the post-request on an HTML page) and appends it to a list and then returns the newly appended list. Upon submitting, the whole page refreshes. I have a background element (a video on a loop).

In my HTML file, I have changed the button type from type="submit" to type="button", which prevents the page from re-loading and continues to play background video correctly. However, it doesn't seem to run my main function. I thought maybe using type="button" and then making a to run the function might work, but I might be wrong on that. I have read solutions others have posted with Javascript and AJAX; I tried to copy and paste some but without success. I am new to programming and would really appreciate feedback and help! Thanks Tobias

in views.py :

def test5(request):
    pd = [8, 24, 'kb']
    user_data = {}

    if request.method == 'POST':

        x = request.POST.get('x') 

        pd.append(x)

    return render(request,'app/test5.html',{'data': pd})

in test5.html :

{% extends 'app/testbase.html' %}  <!-- this brings in my background video -->

{% block content %}

This is a test<br>
[8, 24, 'kb'] <br>

<script>
    function click_action()  {
    }
</script>

<form method="post" action="/app/test5/" id="post-form">
    {% csrf_token %}

    <input name="x" placeholder="Enter number" value="" required autofocus>

    <button onclick="click_action()" name="start_button" id="myBtn" type="submit">add to list </button>
</form>

{{ data }}

{% endblock %}

I would like to get the newly appended list (pd) printed on the screen without the page being refreshed after hitting the button. Thanks for the help!!!!

BPDESILVA
  • 2,040
  • 5
  • 15
  • 35

2 Answers2

0

Write your form as follows:

<form id="post-form">
    {% csrf_token %}

    <input id="idName" name="x" placeholder="Enter number" value="" required autofocus>

    <button onclick="click_action()" name="start_button" id="myBtn" type="button">add to list </button>
</form>

put the following code inside your click_action() function

$('#myBtn').click(function(){
    var name=$("#idName").val();

    $.ajax({
        url: "/app/test5/",
        method: "POST", 
        data: {"name": name}, 
        success: function (data) {        
            // Show a pop up on success
        }
    });
});

In your views.py script's function, if you write return render(request,'app/test5.html',{'data': pd}) at the end of the function like yours, it'll always redirect after execution this view function. So, try avoiding this and use JsonResponse(status = 200, data = {'success' : 1}).

So, in your views.py

from django.http.response import JsonResponse


def test5(request):
    pd = [8, 24, 'kb']
    user_data = {}

    if request.method == 'POST':

        x = request.POST.get('x') 

        pd.append(x)

    return JsonResponse(status = 200, data = {'success' : 1})
  • Thanks Mahmood Al Rayhan for your answer! i think there is something small missing, but I can not figure out. I copied your code into my django project. When I load my page on chrome it shows a white page with only {'success' : 1} on it. Do I need to put the page's html name somewhere in the return statement? – tobias wettstein Jul 02 '19 at 16:46
  • Write `return JsonResponse(status = 200, data = {'pd' : pd})` as view's return statement and add `if (data.pd) {alert("New data: " + data.pd);}` inside ajax success function. – Mahmood Al Rayhan Jul 02 '19 at 17:12
  • Still no success. Now the page displays {"pd": [8, 24, "kb"]} with a white background. Thanks again for your help! – tobias wettstein Jul 02 '19 at 18:13
  • use `return HttpResponse(json.dumps({'pd' : pd}))` – Mahmood Al Rayhan Jul 02 '19 at 18:24
  • Still page shows only this on white background: {"pd": [8, 24, "kb"]}. do i need to use two return statements maybe (one indented to if statement and the second one with a render_to_response)?? also, don't i need to call that 'pd' variable somewhere on my html page? Trying to wrap my around this, thanks for helping! – tobias wettstein Jul 02 '19 at 18:51
0

First, your page is reloading because that is the default behavior of the forms when you click on submit, you can prevent that using: e.preventDefault()

You can use this code:

<script>
    function submit_action(event)  {
        event.preventDefault();  // to prevent the page reload (and the submit also)

        let number = $("#numberInput").val();

        $.ajax({
           url: "/app/test5/",
           method: "POST", 
           data: {"x": number}, 
           success: function (data) {        
               // here you receive the data and you need "manually" update the template
               console.log(data);
           }
       });
    }
</script>

<form method="post" action="/app/test5/" id="post-form" onsubmit="submit_action(event)">
    {% csrf_token %}

    <input id="numberInput" name="x" placeholder="Enter number" value="" required autofocus>

    <button type="submit">add to list </button>
</form>

You need to have included JQuery in this code, you can learn it here if you don't know how

I guess you are just playing with this code, the best way to add a number to a list is just use javascript and DOM manipulation unless you need store the value in a database o something like that.

Yasiel Cabrera
  • 540
  • 4
  • 11
  • Thank you Yasiel Cabrera for your help!! The page loads correctly but when hitting button, it does not change the list. In the console I get the following error: VM205:1 POST http://127.0.0.1:8000/app/test5/ 403 (Forbidden) (anonymous) @ VM205:1 send @ jquery-3.4.1.min.js:2 ajax @ jquery-3.4.1.min.js:2 submit_action @ (index):118 onsubmit @ (index):131 I made sure I included jquery as instructed. also i put in a console.log('test') right before the ajax line and that does show up. do u have any idea where i am going wrong? thanks again for your help – tobias wettstein Jul 02 '19 at 17:57
  • That's because by default django need csrf_token to send data using POST method. In [this post](https://stackoverflow.com/questions/12744159/django-jquery-post-request) there is a more complete answer and in [this other post](https://docs.djangoproject.com/en/dev/ref/csrf/) you can see how to handle it. As summary, you need to send another variable in your data section of the ajax call with the scrf, here is how you get that value: `var csrftoken = $("[name=csrfmiddlewaretoken]").val();` – Yasiel Cabrera Jul 02 '19 at 18:46
  • Thanks Yasiel Cabrera. I used csrf_exempt to get rid of the error. The page loads correctly and does not give me an error in the console. however, it does not return appended list, so it still does not work. thanks for your help!! – tobias wettstein Jul 02 '19 at 19:31