7

I'm trying to implement a simple code testing server. The client will submit their code on the webpage and we will run it with two test cases (which could take several minutes) and we'll post the results. The page will be simple with a submission form and an output box.

My problem is with updating the output box. I'm looking for the simplest way to implement the output box so that we show results as we run different test cases.

I tried googling for solutions and I found some like socket.io but my experience with ajax and socket.io or even js is very limited so I'm looking for the simplest way to do this.

Sudipta
  • 4,773
  • 2
  • 27
  • 42
Kiarash
  • 7,378
  • 10
  • 44
  • 69
  • 1
    Sounds like basic ajax to me. You fetch the results and update the output box using javascript. – keyser Jan 15 '14 at 09:10
  • 1
    I know it should be basic. can you point me to some doc or snippet somewhere? – Kiarash Jan 15 '14 at 09:16
  • I was looking for an answer to this title and I found another solution based on htmx, may this is comment be useful for other ones: https://htmx.org/ – Omid Estaji Sep 04 '22 at 15:26

2 Answers2

8

In case you are looking for code to auto-update a field in HTML here is the code which you could use. The setInterval in JavaScript schedules get_log view to be pulled every 1 second for result of get_log_from_disk method.

urls.py

    url(r'^get_log/$', 'myapp.views.get_log', name='get_log'),
    url(r'^submit/$', 'myapp.views.submit', name='submit'),

views.py

def submit(request):
    ## Handle POST
    ## Your code comes here
    return render(request, 'submit.html', {})

def get_log_from_disk():
    ## Your code comes here
    return "Test 1 OK; Test 2 OK"

def get_log(request):
    results = get_log_from_disk()
    return HttpResponse(results)

in submit.html add

<head>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
</head>

<body>
[<div id="output_box"></div>]

<script>
$(document).ready(function() {
  $.ajaxSetup({ cache: false }); // This part addresses an IE bug.  without it, IE will only load the first number and will never refresh
  var my_refresh = setInterval(function() {
    $('#output_box').load('/get_log/');
  }, 1000); // the "1000"
});

</script>
</body>

You could modify "$('#output_box').load('/get_log/');" to test for status of request and when "204 No Content" is returned you can remove the function (clearInterval(my_refresh );)

see Stop setInterval call in JavaScript

Modify get_log view to return "204 No Content" when there is no more content to be sent.

Here I have uploaded working version

https://github.com/lukaszszajkowski/Django-jQuery-Example-update-part-of-page/tree/master

Some reading

Auto-refreshing div with jQuery - setTimeout or another method?

Community
  • 1
  • 1
fragles
  • 680
  • 6
  • 19
  • 1
    This works. but how can it be a bit smarter.. not pinging the server until the form is submitted, and no pinging after server sent the last message? – Kiarash Jan 15 '14 at 15:11
  • 2
    see my implementation https://github.com/lukaszszajkowski/Django-jQuery-Example-update-part-of-page/tree/master – fragles Jan 15 '14 at 17:06
  • btw. I don't get your logic behind a separate "results" view and your "handle post" comment in there. There is no need for a results url which wouldn't work unless user submitted smth. – Kiarash Jan 15 '14 at 21:20
  • Yes. "handle post" makes no sense - this is a copy paste error. I cloned results out of the submit view. Separate results view is a generic solution see implementation of vote in https://docs.djangoproject.com/en/1.5/intro/tutorial04/. "always return an HttpResponseRedirect after successfully dealing with POST data" – fragles Jan 16 '14 at 08:13
1

This could be what you are looking for:

var ajaxForm = function() {
  $.ajax({
    type: 'POST',
    contentType: 'application/json',
    dataType: 'json',
    url: '/path/to/django/controller',
    // The data sent to the Django view in JSON format
    data: JSON.stringify({
      formField: $('#body').val()
    }),
    success: function (data) {
      $('#output-box').html(data);
    }
  });
}

$('#form').on('submit', function (e) {
  e.preventDefault();
  ajaxForm();
});

The implementation of a Django controller can be something like:

import json
from django.http import HttpResponse

def ajax_view(request):
    if request.method == 'POST':
        request_data = json.load(request.raw_post_data)
        # do something
        response_data = {}
        response_data['result'] = 'Failed'
        response_data['message'] = 'Your test not ended well'
        return HttpResponse(
            json.dumps(response_data),
            content_type='application/json'
        )
Gianluca Mancini
  • 1,302
  • 9
  • 10
  • Thanks. But with this how can I post the result of each test case after it's done? I mean I want to update the output box more than once – Kiarash Jan 15 '14 at 10:16