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?
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.
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.
Related
Im using Sahi OS to look for emails in mailtrap shared inbox.
I can navigate to the folder, search for an email containing a string, do whatever has to be done and logout.
The issue is the speed.. It takes about 1 second for each step in navigation, thats OK. As soon as Sahi gets to the Inbox, it takes about 1-2 minutes for each step in search procedure.
here is my .sah
// Mailtrap check
loginMailtrap($mailtrapId, $mailtrapPwd);
gotoSharedInboxes();
checkForSmsTicketNumber($ticketNumber);
logoutMailtrap();
// Functions
function loginMailtrap($id, $pwd){
_navigateTo($mailtrapUrl);
_setValue(_emailbox("/email/"), $id);
_setValue(_password("/password/"), $pwd);
_click(_submit("Log in"));
_assert(_isVisible(_heading2("/My Inboxes/")));
}
function gotoSharedInboxes();
_click(_span("/Shared Inboxes/"));
_click(_span("Shared Inbox Name"));
}
function checkForSmsTicketNumber($tn){
var $smsTn = $tn.substr(5)
_log($smsTn);
var $go = true;
var $counter = 0;
while ($go) {
var $elm = _span(0, _in(_listItem($counter, _in(_list("messages_list inbox-content nav-list")) ) ));
var $elmText = _getText($elm);
_log($elmText);
var $index = $elmText.indexOf($smsTn);
if($index == -1){
$go = true;
$counter++;
} else {
$go = false;
_click($elm);
_assert(_isVisible($elm));
}
}
}
function logoutMailtrap(){
_click(_div("/username/"));
_click(_link("/Logout/"));
}
The email that Im looking for is the first in the list.
Step _log($smsTn) takes 2 minutes to complete after _click(_span("Shared Inbox Name"));
then it takes about 2 minutes for _log($elmText);
then 2 minutes for _click($elm);
then 2 minutes for logoutMailtrap();
Any ideas is Sahi parses mailtrap so slowly? Something todo with websockets? I dont have that issue with other sites. Thanks!
I have this script below which is used in a survey. The problem I have is, onbeforeunload() works when I don't call a function inside it. If I make any function call(save_survey() or fetch_demographics()) inside it, the browser or the tab closes without any prompt.
<script type="text/javascript">
$(document).ready(function() {
$('#select_message').hide();
startTime = new Date().getTime();
});
loc = 0;
block_size = {{ block_size }};
sid = {{ sid }};
survey = {{ survey|tojson }};
survey_choices = '';
startTime = 0;
demographics_content = {};
function save_survey(sf)
{
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
var surveydat = '';
if(sf==1)
{ //Success
surveydat = 'sid='+sid+'&dem='+JSON.stringify(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+JSON.stringify(survey_choices);
}
if(sf==0)
{ //Fail
surveydat = 'sid='+sid+'&dem='+json_encode(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+json_encode(survey_choices);
}
//Survey Save Call
$.ajax({
type: 'POST',
url: '/save_surveyresponse/'+sf,
data: surveydat,
beforeSend:function(){
// this is where we append a loading image
$('#survey_holder').html('<div class="loading"><img src="/static/img/loading.gif" alt="Loading..." /></div>');
},
success:function(data){
// successful request; do something with the data
$('#ajax-panel').empty();
$('#survey_holder').html('Success');
alert("Dev Alert: All surveys are over! Saving data now...");
window.location.replace('http://localhost:5000/surveys/thankyou');
},
error:function(){
// failed request; give feedback to user
$('#survey_holder').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
}
function verify_captcha()
{
// alert($('#g-recaptcha-response').html());
}
function block_by_block()
{
var div_content ='<table border="0" cellspacing="10" class="table-condensed"><tr>';
var ii=0;
var block = survey[loc];
var temp_array = block.split("::");
if(loc>=1)
{
var radio_val = $('input[name=block_child'+(loc-1)+']:checked', '#listform').val();
//console.log(radio_val);
if(radio_val!=undefined)
survey_choices += radio_val +'\t';
else
{
alert("Please select one of the choices");
loc--;
return false;
}
}
for(ii=0;ii<block_size;ii++)
{
//Chop the strings and change the div content
div_content+="<td>" + temp_array[ii]+"</td>";
div_content+="<td>" + ' <label class="btn btn-default"><input type="radio" id = "block_child'+loc+'" name="block_child'+loc+'" value="'+temp_array[ii]+'"></label></td>';
div_content+="</tr><tr>";
}
div_content+='<tr><td><input type="button" class="btn" value="Next" onClick="survey_handle()"></td><td>';
div_content+='<input type="button" class="btn" value="Quit" onClick="quit_survey()"></td></tr>';
div_content+="</table></br>";
$("#survey_holder").html(div_content);
//return Success;
}
function updateProgress()
{
var progress = (loc/survey.length)*100;
$('.progress-bar').css('width', progress+'%').attr('aria-valuenow', progress);
$("#active-bar").html(Math.ceil(progress));
}
function survey_handle()
{
if(loc==0)
{
verify_captcha();
$("#message").hide();
//Save the participant data and start showing survey
fetch_demographics();
block_by_block();
updateProgress();
$('#select_message').show();
}
else if(loc<survey.length)
{
block_by_block();
updateProgress();
}
else if(loc == survey.length)
{
//Save your data and show final page
$('#select_message').hide();
survey_choices += $('input[name=block_child'+(loc-1)+']:checked', '#listform').val()+'\t';
//alert(survey_choices);
//Great way to call AJAX
save_survey(1);
}
loc++;
return false;
}
</script>
<script type="text/javascript">
window.onbeforeunload = function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
//fetch_demographics();
save_survey(0);
return "You have spent "+Math.ceil(t)+ " minute/s on the survey!";
//!!delete last inserted element if not quit
}
</script>
I have checked whether those functions have any problem but they work fine when I call them from different part of the code. Later, I thought it might be because of unreachable function scope but its not the case. I have tried moving the onbeforeunload() at the end of script and the problem still persists. Wondering why this is happening, can anyone enlighten me?
I identified where the problem was. I am using json_encode instead of JSON.stringify and hence it is crashing(which I found and changed already in sf=1 case). That tip with debugger is invaluable. Also, its working fine even without async: false.
Thank you again #AdrianoRepetti!
Is there any way to get the current time of website in order to set range time for reaction?
e.g if current time of website >= 14:00 && current time of website < 15:00
do reaction
else
another reaction
I want to do this checking type of fuction every 30' sec
EDITED
e.g If in my country the time is 14:00 and in another one is 19:00 I want to do the reaction to another country based in my country's time. Correct my if I do smthng wrong.
here is the code for php file to fetch server time, name it t.php.
<?php
$b = time ();
echo date("H",$b);
?>
and here is the code for other file on which you use ajax: Run this file using xamp/wamp.
Place both files in sane directory .
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript">
setInterval(function() {
$.ajax({
url : "t.php",
type: 'GET',
success: function(data){
if(data >= 9 && data < 10){
alert('yes');
// do something
} else{
alert('no');
// do something
}
}
});
}, 1000);
</script>
Here is the Solution:
you can find current time of website using javascript because it is a client side scripting language
In php I think there is no way to find client's time (not sure), That's why I am using jquery.
to use it in php file use ajax.
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script>
$(document).ready(function(){
function call_notification_count() {
var todaydate = new Date(); // current time of browser. or you can say Time of client's location
var month = todaydate.getMonth()+1+"";if(month.length==1) month="0" +month;
var date = todaydate.getDate()+"";if(date.length==1) date="0" +date;
var year = todaydate.getFullYear();
var hours = todaydate.getHours();
var minutes = todaydate.getMinutes();
var seconds = todaydate.getSeconds();
var todaytime = hours+":"+minutes+":"+seconds;
var todaydateonly = year+"-"+month+"-"+date+" ";
alert(todaytime);
if(hours >= 14){
// do something
}else{
// do something
}
}
setInterval(call_notification_count, 3000); // Set time intervel here like for every 30 sec.
});
</script>
I have implemented an online quiz using jQuery. I have this specific requirement I want to implement at the end of the quiz.
if (number_of_answered_questions == total_questions) {
save the score to the database;
redirect to redirect_url;
}
This redirect_url depends on the score. (for ex: if the score < 10, redirect to page1.html and if 10 < score < 15, redirect to page2.html)
I tried using jQuery.post, but I'm not sure how to implement both in the same 'post'.
How can I implement these two tasks in jQuery?
I can't write the logic to "save to database" in the redirect pages because they keep changing. (I mean admin can change the redirect pages).
You can trigger a redirect in JS by modifiying window.location.href. You simply need to change your pseudocode/conditionals into the JS equivalent, and then modify the href accordingly to redirect, once your save completes successfully (i.e. in the callback for the post method).
var total_questions = ...;
var number_of_answered_questions = ...;
var score = ...;
// other quiz logic...
var postData = { "score": score, ... };
if (number_of_answered_questions == total_questions) {
$.post("/saveScores.php", postData, function() {
if (score < 10) {
window.location.href = "page1.html"
}
else if (10 < score && score < 15) {
window.location.href = "page2.html";
}
});
}
I am using jquery to reload a page with the below code
<script type="text/javascript">
$(document).ready(function(){
setInterval(function() {
window.location.reload();
}, 10000);
})
</script>
But i had some requirement, that i need to refresh the page only for 6 times, and display a message that "Something problem occurred"
So how to refresh/reload a page only for specific times(6 in my case) using jquery ?
Based on the comment of LShetty:
A basic example of using localStorage could be seen here http://coding.smashingmagazine.com/2010/10/11/local-storage-and-how-to-use-it/
E.g. something along the lines
<script type="text/javascript">
$(document).ready(function(){
var counter = localStorage.getItem('counter');
if (counter == null) {
counter = 0;
}
counter++;
if (counter<=6) {
localStorage.setItem('counter', counter);
setInterval( function() {
window.location.reload();
}, 10000 );
}
})
</script>
Of course you could use a cookie for the same purpose, as you are going to store just a counter (way bellow the 4K limit of data stored in a cookie). For example you could utilize the createCookie and readCookie functions from the following article http://www.quirksmode.org/js/cookies.html
Just an idea: you can use query string to pass the counter between page refreshes. Something like this:
<script type="text/javascript">
var counter = 0;
$(document).ready(function(){
counter = parseInt(getParameterByName("counter"));
if(counter < 6){
setInterval(function() {
window.location.href = "http://" + window.location.host + window.location.pathname + '?counter=' + (counter + 1);
}, 10000);
}
})
//convenient method to get parameters from query string
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
</script>
what about this?
$(function(){
if($('#sessioncounter').val() <= 6 ){
setTimeout(function(){
window.location = window.location;
}, 6000);
}
});
$('#sessioncounter').val() gives the counter value which you save in every load in the session. i dont know what kind of backend language you are using.. anyway, make a hidden field
<input type='hidden' id='sessioncounter' />
then save after each reload the counter into this field.
Using hash variables also works when it's an older browser without localstorage.
$(document).ready(function(){
var count = parseInt(window.location.hash.replace('#',''))
if(!count){
count = 0;
}
count++;
if(count < 7){
setTimeout(function(){ window.location = 'http://'+window.location.hostname+window.location.pathname+'#'+count;}, 1000);
}
});