2

I'm pretty new to Django (and web development) and find myself struggling with this problem: I built a simple timer using javascript and now want to have a variable in the model that updates when the timer is up. I'm lost in how to do that.

Here's my code:

home.html:

<button onclick='activatecount()' value='countdown'>Start Timer</button>
<p id='countdown'></p>
<p id='endofcount'></p>

<script src='{{ STATIC_URL }}timerapp.js'></script>
</body>
</html>

Then the javascript. There is a button on the screen and when the user clicks the button a timer starts counting down.

var myTime = setInterval(displayTime, 1000);//Calls the function displayTime once every second
function subtractSeconds(){
seconds--;
document.getElementById('countdown').innerHTML = seconds; }

var interval;
var minutes = 2;
var seconds = 10;

function activatecount(){
    countdown('countdown');
}

function countdown(element) {
    interval = setInterval(function() {
        var el = document.getElementById(element); 
        if(seconds == 0) { 
            if(minutes == 0) {
                el.innerHTML = "countdown's over!";  
                clearInterval(interval); 
                return;
            } else { 
                minutes--;
                seconds = 60;
            }
        } 
        if(minutes > 0) { 
            var minute_text = minutes + (minutes > 1 ? ' minutes' : ' minute');
        } else {
            var minute_text = '';
        }
        var second_text = seconds > 1 ? 'seconds' : 'second';
        el.innerHTML = minute_text + ' ' + seconds + ' ' + second_text + ' remaining';
        seconds--; 
        }, 1000); 
}

My views.py:

def home(request):
    return render_to_response('home.html', context_instance=RequestContext(request))

And finally my models.py:

class User(models.Model):
    username = models.CharField(max_length=10)
    email = models.EmailField(max_length=254)
    first_name = models.CharField(max_length = 20)
    last_name = models.CharField(max_length = 20)
    join_date = models.DateField().auto_now_add
    block_count = models.IntegerField()

def __unicode__(self):
    return self.username

All I want is for block_count to be incremented by one when the timer is up. (I'll add further functionality later, but I'm totally lost with this seemingly trivial thing.) All I can find is discussions on how to submit data to the database using forms and POST, but I'm not using a form here.

Should one use POST here? If so, how?

0

2 Answers 2

1

Create a second view to update the model. Call the second view using jquery's .ajax method if you want to be able to stay on the same page while the database updates.

Something like:

views.py

def ajax(request):
    if request.is_ajax():
    // add 1 to your block count

jquery:

function countdown(element) {
interval = setInterval(function() {
    var el = document.getElementById(element); 
    if(seconds == 0) { 
        if(minutes == 0) {
            el.innerHTML = "countdown's over!";  
              $.ajax({
                type:"POST",
                url :"/ajax-url/",
                error:function(data){alert('Error');}
                success:function(data{alert('OK!');}
                });
            clearInterval(interval); 
            return;
            // etc etc

urls:

url(r'^ajax-url/$', 'views.ajax'),

This is the general idea. I have not tested this code, but it should give you a starting point from which to understand how to solve your problem.

Sign up to request clarification or add additional context in comments.

6 Comments

Note that this JS assumes the use of jQuery, which isn't in evidence in the question.
Also to note: This example can be rewritten without jQuery, though you might lose your mind.
Nick, thanks for your answer. A starting point that certainly is.
Two questions: 1) Is using jQuery the only manageable way? you seem to think that's the case? 2) Are there any articles or tutorials on problems like this? It seems that should be a very common problem and have a simple solution. I might be wrong, of course. @Jake? Anyway, I'll look into Nick's suggestion for now and try to figure this out.
@BrianFabianCrain If you want to make the http request asynchronously jQuery is your best bet. If you want to not use jquery I believe 'xhr' in google would get you started.
|
0

You could create a form like this

<form name="myform" action="/update-model/ method="post">
<input type="hidden" name="update" value="yes">
</form>

and a view like this

def update_model(request):
    if request.POST:
        if request.POST['update']:
            #do your code here.

and your javascript like this

    if(minutes == 0) {
            el.innerHTML = "countdown's over!";  
            document.myform.submit();
            clearInterval(interval); 
            return;
        } else { 
            minutes--;
            seconds = 60;
        }

In Django (and web apps in general) when you need the server to do something, you send an HTTP request to it. This is accomplished by mapping a method to a url (urls.py). Then you can do deprecated for 1.5

url = "{% url my_url_name %}"

You have a few choices on how to send that request with the web browser (your web app's GUI, right?)

  • Asynchronously
  • Synchronously

Sending the request synchronously requires the standard page load. Google's homepage form is synchronous. You want to do this anytime the request needs to move the user to another page or the app needs to restart after the submission. You do this with form submissions and links.

Sending the request asynchronously allows parts of the page to load (reload) at different times, and as they can be processed by the server. Searching again from a google search results page asynchronously pulls in search results. You do this using a technique called ajax.

1 Comment

Thanks very much for your answer. I have been looking into Ajax (was unfamiliar with it before). I'm first going to try doing synchronously and afterward use AJAX to do it asynchronously. It will probably take me a few days, but edit my answer with the result after.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.