So, I spend the best part of the day playing with your example but wasn't
able to make it work.
The best I have is that I see that before the form is submitted
*getprogress* is called and return the expected value, but while progress
is running it blocks the invocation of *getprogress* and the prints in
*getprogress* are executed all at once after the sleep loop of *progress*
is complete. It looks like a limitation of web2py. I didn't try to create a
new thread for the update of
*cache.ram('progress_data', ...)*
Am I doing something wrong?
Here is what I got, after making some minor modification to your code to
make it work for me:
In my *controller/playground.py*
# Progress bar example:
# See: https://groups.google.com/d/msg/web2py/zgSLxeg7avw/JvPidEBMAQAJ
import time
def progress():
some_form = SQLFORM.factory(Field('a_field'))
if request.post_vars:
n = 20 #simulate 20 iterations
for i in range(n):
msg = "Working"
percent = 100*(i+1) / n
progress_data = cache.ram('progress_data',
lambda: dict(percent=percent, msg=msg
),
time_expire=0)
print "progress:", progress_data
time.sleep(1)
#we are calling this controller through ajax so return a string
when done
return "done"
else:
progress_data = cache.ram('progress_data',
lambda: dict(percent=(-1), msg='Ready'),
time_expire=0)
return locals()
def getprogress():
progress_data = cache.ram('progress_data', lambda: None, None)
print "getprogress:", progress_data
return progress_data
And in my *view/playground/progress.html* I have:
{{extend 'layout.html'}}
{{=a_form}}
<div class="container-fluid">
<div id="pbar">
<div class="row">
<div class="col-md-12">
<h3 id="pbar_status">Ready...</h3>
</div>
<div class="col-md-12">
<div class="progress progress-bar-xl"
style="margin-top: 3px">
<div class="progress-bar progress-bar-warning"
role="progressbar"
aria-valuenow="60"
aria-valuemin="0"
aria-valuemax="100"
style="width: 0%;">0%</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
function ProgressBar (selector) {
self = this
self.el = $(selector)
self.text = self.el.find("#pbar_status");
self.progress = self.el.find(".progress-bar");
self.btnstart = self.el.find("#start");
self.btnabort = self.el.find("#abort");
self.value = 0;
self.min = 0;
self.max = 100;
self.interval = 5000;
self.running = false;
self.timer = null;
self.offset = 0;
self.set_progress = function (value) {
value = value || 0;
var done = false;
if (value >= self.max) {
value = self.max
done = true;
};
value = parseInt(value) + "%";
self.progress.css("width", value);
self.progress.text(value);
if (done) {
self.done();
};
};
self.done = function (msg) {
var msg = msg || "Process Completed"
self.text.text(msg)
console.log("done", self.timer);
clearInterval(self.timer);
self.running = false;
};
self.abort = function (e) {
if (self.running) {
self.value = 0;
self.set_progress(0);
self.text.text("Aborted");
if (self.timer) {
clearInterval(self.timer);
};
self.running = false;
};
}
// ask the server for the progress
self.ask = function () {
var ask = $.ajax({
type: "GET",
url: window.location.origin + "{{=URL('getprogress.json')}}",
dataType: "json",
});
ask.done(function (json) {
console.log(json);
var percent = parseInt(json.percent);
var msg = json.msg;
if (percent == -1) {
console.log(msg);
return;
};
self.text.text("Processing...");
self.text.text(msg);
self.value = percent + self.offset;
self.set_progress(self.value);
});
ask.fail(function (xhr, status, error) {
var resp = xhr.responseText;
self.done("Error (see browser's console for details)");
if (console) {
console.log(resp);
};
});
};
self.start = function (e) {
if (self.running) {
console.log("already runing");
} else {
console.log("running");
self.value = 0;
self.set_progress();
self.ask();
self.timer = setInterval(self.ask, self.interval);
self.running = true
};
};
self.set_progress(self.value);
}
// start here
$(function() {
var pbar = new ProgressBar("#pbar");
pbar.start();
})
</script>
Thank you very much.
Cheers,
Chen.
On Tuesday, February 16, 2016 at 11:15:06 PM UTC+2, Alfonso Serra wrote:
>
> Im trying to make a progress bar by reading and writing a session variable:
>
> There are 2 controllers:
>
> Get session.progress
> def getprogress():
> print "getprogress:", session.progress
> return session.progress
>
> This one takes 5 seconds to perform and changes session.progress each time.
> def progress():
> # when a form is submitted, change progress each second
> if request.post_vars:
> for i in range(5):
> session.progress = i
> print "main:", session.progress
> sleep(1)
> return "done"
> else:
> session.progress = -1
> return locals()
>
> At the view, there are two ajax calls. One that triggers "getprogress"
> each second, and another one that triggers "progress" when a random form is
> submitted through ajax to avoid redirection.
>
> at the browser's console, getprogress only returns -1
>
> at the python console i get a log like this:
> getprogress: -1
> getprogress: -1
> main: 0
> getprogress: -1
> main: 1
> getprogress: -1
> main: 2
> getprogress: -1
> main: 3
> getprogress: -1
> main: 4
> getprogress: -1
>
> getprogress should be changing since im writing the session variable.
>
> If im changing a session variable in a controller why hasnt changed when i
> ask for it on another one?
>
> Should i be using cron jobs or threads to make a progress bar? Whats the
> best way?
>
> Thank you very much.
>
>
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.