Re: Return value from javascript to controller

278 views
Skip to first unread message

Niphlod

unread,
Apr 14, 2013, 8:21:56 AM4/14/13
to web...@googlegroups.com
did you see by any chance https://github.com/niphlod/w2p_timezone_plugin ?
it seems you're trying to do what is done at
https://github.com/niphlod/w2p_timezone_plugin/blob/master/modules/plugin_timezone/__init__.py#L124

On Sunday, April 14, 2013 6:51:11 AM UTC+2, funm...@gmail.com wrote:
Hi All,

I am very new to coding, and am learning my way with the web2py framework and tools. I am trying to get return a value that i got from the view to the controller. This seems to be a basic idea, but i am not sure how to do it. Hope you may share an example. thanks!

Regards,
Wayne


The view, list_prototype2.html. I want to pass var tz back to the controller.

<script type="text/javascript" src="{{=URL('static','js\jstz-1.0.4.min.js')}}"></script>
<script type="text/javascript">
$(document).ready(function( ) {
    var tz = jstz.determine( );
    response_text = 'No timezone found';
    if (typeof (tz) === 'undefined') {
        response_text = 'No timezone found';
    }
    else {
        response_text = tz.name( );
    }
    $('#Method_2_tz_info').html(response_text);

});
</script>
<p id="Method_2_tz_info"></p>

Anthony

unread,
Apr 14, 2013, 12:11:35 PM4/14/13
to web...@googlegroups.com
In general, you would have to do that either via a form submission, or via an Ajax request.

Anthony

funm...@gmail.com

unread,
Apr 15, 2013, 10:15:09 AM4/15/13
to web...@googlegroups.com
Hi Niphlod,

Thanks for providing this plugin. This sounds like what i am trying to do. This is great. I will have to learn how to use it.

regards,
Wayne

Niphlod於 2013年4月14日星期日UTC+8下午8時21分56秒寫道:

funm...@gmail.com

unread,
Apr 15, 2013, 10:16:43 AM4/15/13
to web...@googlegroups.com
Hi Anthony,

Thanks for the tip.

While i should use the plugin, i do want to learn how this can be done. I am trying to google around for this. If you may share any tips or starting points to read, it will be greatly appreciated.

Regards,
Wayne

Anthony於 2013年4月15日星期一UTC+8上午12時11分35秒寫道:

Anthony

unread,
Apr 15, 2013, 10:20:21 AM4/15/13
to web...@googlegroups.com

Niphlod

unread,
Apr 15, 2013, 11:03:38 AM4/15/13
to web...@googlegroups.com
PS: as the source code of the plugin was updated, now you'd have to watch for this line instead

https://github.com/niphlod/w2p_timezone_plugin/blob/master/modules/plugin_timezone/__init__.py#L138

basically it's an ajax POST.

funm...@gmail.com

unread,
Apr 15, 2013, 11:42:10 AM4/15/13
to web...@googlegroups.com
Thanks again, Anthony.

Anthony於 2013年4月15日星期一UTC+8下午10時20分21秒寫道:

funm...@gmail.com

unread,
Apr 15, 2013, 11:49:44 AM4/15/13
to web...@googlegroups.com
Hi Niphlod,

This will be some learning. Thanks for pointing it out.

I am really a newbie here. I've tried to "upload" your plugin to my application. It's a zip file that i download from Github. It's doesn't allow me to do the upload, and said my app does not exist or i don't have enough permission.

I've then tried to download another layout plugin to try out. That "Keep it Simple" layout does work. It's a .w2p.

I am wondering what i need to do to use your plugin. I read that the zip file has a couple folders. Should I uncompress it and simply copy them over? Github is a new thing to me. Maybe I used the wrong way or got the wrong file.

regards,
Wayne

Niphlod於 2013年4月15日星期一UTC+8下午11時03分38秒寫道:

Niphlod

unread,
Apr 15, 2013, 12:09:45 PM4/15/13
to web...@googlegroups.com
yep, github downloads a zip that holds a folder that holds the content

- archive.zip
      - w2p_timezone_plugin-master
            - modules
            - static

What you need to do is copy the modules and static folders "on top" of your applications one..... e.g. if your app is at /path/to/web2py/application/yourappname/ you should copy modules and static under that folder (which has already a "static" and a "modules" folder).

Don't worry, within each of them there is a folder plugin_timezone that "holds" the plugin content completely separate from your app, so no file overwrites will be done.            

fun man

unread,
Apr 16, 2013, 2:10:38 PM4/16/13
to web...@googlegroups.com
Hi Niphlod,

I need to trouble you again for your guidance.

I've successfully copied the files. I've added a new application tz_test to test the plugin.

This is my controller and there are some other scaffolding coded not included.
========================================================
import pytz
from plugin_timezone import fast_tz_detector

def detect_timezone():
    tz = fast_tz_detector()
    return dict(tz=tz)

def test():
    detect_timezone()
    zone = session.plugin_timezone_tz
    form = SQLFORM.grid(db.sometable)
    return dict(form=form)
   
This is my model.
=============
db = DAL("sqlite://storage.sqlite")
import pytz
user_timezone = session.plugin_timezone_tz or 'UTC'
db.define_table('sometable',
  Field('appointment', 'datetime',
        requires=IS_DATETIME(timezone=pytz.timezone(user_timezone))
  )
)

I called the below page to create a new row in the table.
http://127.0.0.1:8000/tz_test/default/test/new/sometable?_signature=84a55b727259cb27cb2c2234966da9d9b0cd7dfd#

I was given a form to fill, and select a date. Then the form rejected me. Do you have any suggestion on how i may resolve this?

Appreciate your help to provide some insights..

Thanks
Wayne






--
 
---
You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/aV1nNiDIwiY/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Niphlod

unread,
Apr 16, 2013, 3:17:11 PM4/16/13
to web...@googlegroups.com

Ohhh, whoopsie..... it needs a fix, sorry ^_^
Redownload the plugin from github.

PS: That will work ok if a user landed on the "detect_timezone" page....if you need to autodetect in the same page as the form, you should be able to do

def test():
      fast_tz = fast_tz_detector()
      form = yourform .....

      .....
      return dict(form=form, fast_tz=fast_tz)

all in one shot (given that you use the generic template nothing has to be done, if you use your own you need to include somewhere {{=fast_tz}} in it)

fun man

unread,
Apr 16, 2013, 10:14:58 PM4/16/13
to web...@googlegroups.com
Hi Niphlod,

I downloaded the new one, and copied the files over. Keeping my original model. This is now my controller.

1) fast_tz returns None,
2) the "submit" button to the db was not taken, and the still ask me to fill out the form again.

Would you mind to take a look at it? thanks for your help.

def test():
    fast_tz = fast_tz_detector()
    #create a new appt
    form = SQLFORM(db.sometable).process(next=URL('index'))
    if form.process().accepted:
        response.flash = 'form accepted'
    elif form.errors:
        response.flash = 'form has errors'
    else:
        response.flash = 'please fill out the form'
    return dict(form=form, fast_tz=fast_tz)
   




fast_tz_form_add_result.png

Niphlod

unread,
Apr 17, 2013, 3:10:11 AM4/17/13
to web...@googlegroups.com
that's exactly what I tested yesterday evening... can you please try to strip out the next=URL('index') part ?
It's the only thing that is different.

fun man

unread,
Apr 17, 2013, 8:40:25 AM4/17/13
to web...@googlegroups.com
Hi Niplod,

It still behaves similarly.


1) fast_tz returns None,
2) the "submit" button to the db was not taken, and the still ask me to fill out the form again.

This is my updated controller.

def test():
    fast_tz = fast_tz_detector()
    #create a new appt
    form = SQLFORM(db.sometable).process()

    if form.process().accepted:
        response.flash = 'form accepted'
    elif form.errors:
        response.flash = 'form has errors'
    else:
        response.flash = 'please fill out the form'
    return dict(form=form, fast_tz=fast_tz)

Niphlod

unread,
Apr 17, 2013, 11:05:19 AM4/17/13
to web...@googlegroups.com
I'll try that again verbatim in a few hours (as soon as I get my hands on a pc with python ^_^) and report back.

PS: what error does the form return ?

Funmanhk

unread,
Apr 17, 2013, 1:00:23 PM4/17/13
to web...@googlegroups.com, web...@googlegroups.com
Hi Niphlod,

As always, thanks for your help. 

I do not think I got an explicit error this time. However, the input is not taken. When I clicked submit, the page blink and showed me a blank "Add" page. 

Regards,

Niphlod

unread,
Apr 17, 2013, 3:14:26 PM4/17/13
to web...@googlegroups.com
ok.

There was an error in your code, a double call to process() .....
But there was also on my end: when you do in the same function that shows the form a fast_tz_detector(), basically you trigger a POST request that "updates" the formkey associated with the form.
Blame on me that use LOAD() all the times.

In order to avoid intricacies of CSRF (that you can definitely circumvent by hand, but it's not recommended if you don't understand all the implications), it's better either to check for the timezone earlier in the process.
Actually the module is in use in a site of mine, where a default "landing page" is hit by every user before having the possibility to fill a form ... also, it's not useful to check for the user timezone everytime he loads a page ^_^.
Even so, if you want to detect the timezone in the same page where there is the form, your "safest" resort would be to include a LOADed component that triggers the timezone detection.....

Summary: here's the code to accomplish timezone detection in the form....
def mytzdetector(): #just does timezone detection
    fast_tz
= fast_tz_detector()
   
return dict(fast_tz=fast_tz)

def test():
   
if not session.plugin_timezone_tz: #if it's already set, skip detection
        fast_tz
= LOAD('default', 'mytzdetector.load', ajax=True) #load with ajax
   
else:
        fast_tz
= None

    form
= SQLFORM(db.sometable)

fun man

unread,
Apr 18, 2013, 5:58:59 AM4/18/13
to web...@googlegroups.com
I've downloaded the plugin again. Trying this controller setup, with the same model in the previous email.

This time the error is "form has errors". So it looks like something is returned, but not good enough to get it to submit.

Niphlod,

I agree with you that i should use a landing page. Assume it is my index page per below.

thanks for your help.


import pytz
from plugin_timezone import fast_tz_detector

def mytzdetector(): #just does timezone detection
    fast_tz = fast_tz_detector()
    return dict(fast_tz=fast_tz)

def test():
    if not session.plugin_timezone_tz: #if it's already set, skip detection
        fast_tz = LOAD('default', 'index.load', ajax=True) #load with ajax

    else:
        fast_tz = None

    form = SQLFORM(db.sometable)
    if form.process().accepted:
        response.flash = 'form accepted'
    elif form.errors:
        response.flash = 'form has errors'
    else:
        response.flash = 'please fill out the form'
    return dict(form=form, fast_tz=fast_tz)

def index():
    """
    example action using the internationalization operator T and flash
    rendered by views/default/index.html or views/generic.html

    if you need a simple wiki simple replace the two lines below with:
    return auth.wiki()
    """
    fast_tz = fast_tz_detector()
    response.flash = T("Welcome to web2py!")
    return dict(fast_tz=fast_tz)

This is my model
================

db = DAL("sqlite://storage.sqlite")
import pytz
user_timezone = session.plugin_timezone_tz or 'UTC'
db.define_table('sometable',
  Field('appointment', 'datetime',
        requires=IS_DATETIME(timezone=pytz.timezone(user_timezone))
  )
)

fast_tz_form_add_result2.png

Niphlod

unread,
Apr 18, 2013, 6:11:36 AM4/18/13
to web...@googlegroups.com
that seems more a problem with the format of the date than the fact that it has to be "timezone-normalized"....what language translation are you using ?

PS: what I meant with "landing page" is that you're sure that the user will hit that page before arriving to the form.
If you are sure, there's no need to embed the LOADed fragment in the form page

fun man

unread,
Apr 18, 2013, 10:35:51 AM4/18/13
to web...@googlegroups.com
i am not using any specific language translation. It should be the default language.

i also think that it is timezone issue, but not very sure how to do the normalization. The model i use is     Field('modified_on', 'datetime'),
I see that there is no timezone attached at the end.


--

Niphlod

unread,
Apr 18, 2013, 11:41:28 AM4/18/13
to web...@googlegroups.com
the whole point of timezone normalization is NOT having "a timezone attached at the end".
It's storing in the database as UTC and displaying as "localized" to the users.
Are we sure that you fully grasped what the timezone implementation on the IS_DATE* validators in web2py and that that idea fits with your one ?

fun man

unread,
Apr 18, 2013, 12:20:18 PM4/18/13
to web...@googlegroups.com
yes. I am with you. I didn't store timezone in the db, and will be using UTC for all input to the db too.

I hope to find a way to use the detected timezone to use in the .represent method for the sqlform.grid.
    db.prototype.modified_on.represent = lambda value, row : pytz.UTC.localize(value).astimezone(pytz.timezone('Asia/Tokyo'))

The above is working for me. I basically hardcode it to 'Asia/Tokyo'. I am trying to get the value from your plugin to replace my hard coded one above.

Niphlod

unread,
Apr 18, 2013, 3:13:36 PM4/18/13
to web...@googlegroups.com
packed an app with a few examples: might explain better how to deal with timezones.
web2py.app.fun_man.w2p

Funmanhk

unread,
Apr 18, 2013, 7:46:36 PM4/18/13
to web...@googlegroups.com
Thanks Niphlod. May I know where I can pick up the examples? 

Appreciate your help on this. 


<web2py.app.fun_man.w2p>

Funmanhk

unread,
Apr 18, 2013, 8:33:47 PM4/18/13
to web...@googlegroups.com, web...@googlegroups.com
Btw, I want to say that Niphlod has been very helpful. I am definitely missing the HTML+JS knowledge, but that didn't stop me to try out in web2py and have a good attempt on this issue. 

I am one little step away from solving this time zone problem haunting me for a few months.  I wouldn't have the courage to start this adventure without seeing the community's effort here. 

Thanks Niphlod, and everyone to create and support this. 

On 19 Apr, 2013, at 3:13, Niphlod <nip...@gmail.com> wrote:

<web2py.app.fun_man.w2p>

fun man

unread,
Apr 18, 2013, 9:08:55 PM4/18/13
to web...@googlegroups.com
Sorry Niphlod. I was on my phone, and didn't see this attachment. Thanks again for helping me out without asking for anything. I will try to learn from your example.

fun man

unread,
Apr 18, 2013, 9:58:09 PM4/18/13
to web...@googlegroups.com
hi Niphlod,

I've tried your example in the attachment. The good news is that the user selected timezone it the profile/register page is working consistently! Great work! Thank you!

The bad news is that the dynamic detection, and return from the client session is still not working...
def index():
    some_message = "here timezone is detected"
    tz = fast_tz_detector()

I found out that tz is still not returning anything in the index page. That should be my landing page, and once this is detected. I want to move this value to the db. Then use it for the rest of the other functions in the application.

I am reading your plugin, and it will take me some time to really figure out what is going on inside fast_tz_detector()... Not sure why it didn't return the thing I want :-)

Niphlod

unread,
Apr 19, 2013, 3:39:17 AM4/19/13
to web...@googlegroups.com
fast_tz_detector returns a SCRIPT().
Of course you can't "read it" because the page executes it, so it's fine if you see a blank space:
If you see the page source (using firefox, right click --> View page source) you'd see a <script>blablablabla</script>

On the "let's save it to the database" topic ..... try it yourself:

def index():
   
print 'Hi, you should save this ', request.vars
    some_message
= "here timezone is detected"
    tz
= fast_tz_detector()
   
return ....

When you return a "fast_tz_detector()", as soon as the browser loads the page, javascript detects the timezone and it is sent back to the same controller function (in this case, "index").

Another way is to "hack it up" somewhere

def index():
   
if session.plugin_timezone_tz:
           db
.sometable.insert(
detected_timezone=session.plugin_timezone_tz, user_id=auth.user_id)

    some_message
= "here timezone is detected"
    tz
= fast_tz_detector()

   
return .....

fun man

unread,
Apr 19, 2013, 7:03:34 AM4/19/13
to web...@googlegroups.com
Thanks again, Niphlod. I am getting close to finish what i want to do :-)

I can see that I get the time zone. After changing the timezone a few times, I am not seeing it any more.....

I am trying to trouble shoot this. I figured that i need to close my browser, but this doesn't seem to make it work again...

please visit:
        http://127.0.0.1:8000/
starting browser...
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {'timezone': 'Asia/Shanghai'}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {'timezone': 'Asia/Shanghai'}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {'timezone': 'Africa/Johannesburg'}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {'timezone': 'Africa/Johannesburg'}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {'timezone': 'Africa/Johannesburg'}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {'timezone': 'America/Los_Angeles'}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>

C:\Users\lab\Downloads\web2py>python web2py.py
No handlers could be found for logger "web2py"
web2py Web Framework
Created by Massimo Di Pierro, Copyright 2007-2013
Version 2.4.5-stable+timestamp.2013.03.18.22.46.22
Database drivers available: SQLite(sqlite3), MySQL(pymysql), PostgreSQL(pg8000), MS
odbc), Ingres(pyodbc), IMAP(imaplib)
please visit:
        http://127.0.0.1:8000/
starting browser...
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
please visit:
        http://172.27.169.52:8000/
starting browser...
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
<Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>
Hi, you should save this  <Storage {}>



Funmanhk

unread,
Apr 19, 2013, 7:41:13 AM4/19/13
to web...@googlegroups.com, web...@googlegroups.com
Niphlod,

Thank you for pointing this out. I have some serious learning ahead. Thank you for being patient with my questions. 

I am good with your approach below. The first suggestion works out for me, and my time zone issue is resolved. 

Thank you!

fun man

unread,
Apr 19, 2013, 7:46:32 PM4/19/13
to web...@googlegroups.com
Hi Niphlod,

def index():
    # when people first login, they will get their timezone set.
    tz = fast_tz_detector()
    print
    print 'Hi, you should save this returned by request.vars', request.vars     # if you debug, uncomment this line, and make sure return tz=tz below
    
    print "plugin_timezone_tz == ", session.plugin_timezone_tz
    if session.plugin_timezone_tz:
        if db.userinfo[auth.user_id] == None:     # check first time login
            db.userinfo.insert(detected_timezone=session.plugin_timezone_tz, id=auth.user_id)   #insert record
        else:
        db.userinfo[auth.user_id]=dict(detected_timezone=session.plugin_timezone_tz)        #update record
        print " called index & after db udpate = ", db.userinfo[auth.user_id].detected_timezone


Hi, you should save this returned by request.vars <Storage {'timezone': 'Australia/Darwin'}>
plugin_timezone_tz ==  America/New_York
 called index & after db udpate =  America/New_York

My machine is set to 'Australia/Darwan' now. request.vars is working fine.

Is there a reason why session.plugin_timezone_tz always return "America/New_York"? No matter how I changed my timezone of the client, i didn't see session.plugin_timezone_tz got updated.

After this, my timezone problem should go away :-)

thanks for your help.

fun man

unread,
Apr 19, 2013, 7:55:42 PM4/19/13
to web...@googlegroups.com
Apologize everyone, and Niphlod,

I forgot to restart my browser, and now the 2 values are consistent ...... my bad for the disturbance.

Niphlod

unread,
Apr 20, 2013, 8:36:19 AM4/20/13
to web...@googlegroups.com
for future watchers of this thread: if you test this "changing your timezone", remember to clear the session.... in a normal world a user doesn't switch timezones within the same session ^_^

Reply all
Reply to author
Forward
0 new messages