This page describes how to make Pyjamas work with web2py. It is easy actually and it does not require any additional library other than web2py and pyjamas.
(Updated by Alexei Vinidiktov (alexei.vinidiktov (at) gmail.com) to work with pyjamas 0.5p1 and the built-in jsonrpc gateway of web2py.)
Inspired by this Django page.
Thanks to Luke Kenneth Casson Leighton and Chris Prinos for their help.
web2py is a web framework written in Python. Pyjamas is a Python port of the google web toolkit (written in Java). Pyjamas can be used with web2py to create web applications.
In terms of an MVC framework, web2py acts as the Model and Pyjamas acts as the Views and Controller.
In this brief tutorial, we will create a very simple todo list. The primary purpose of this tutorial is to briefly demonstrate how to serve data with web2py, how to create and display widgets with Pyjamas, and how to handle user events with Pyjamas.
Here is the software that is needed:
This tutorial will not go into how to install each of these components, nor their basic usage. Hopefully, some of them can be downloaded as packages for your linux distribution. One reader recommended that you have a fairly recent web2py version.
Create a new app called "todo"
db=SQLDB('sqlite://storage.db')
db.define_table('todo', db.Field('task'))
from gluon.tools import Service # import rpc services
service = Service(globals())
def index():
redirect(URL(r=request,f='todoApp'))
@service.jsonrpc
def getTasks():
todos = db(db.todo.id>0).select()
return [(todo.task,todo.id) for todo in todos]
@service.jsonrpc
def addTask(taskFromJson):
db.todo.insert(task= taskFromJson)
return getTasks()
@service.jsonrpc
def deleteTask (idFromJson):
del db.todo[idFromJson]
return getTasks()
def call():
return service()
def todoApp():
return dict()
<html>
<head>
<meta name="pygwt:module"
content="{{=URL(r=request,c='static',f='output/TodoApp')}}">
<title>Simple Todo Application</title>
</head>
<body bgcolor="white">
<h1>Simple Todo Application</h1>
<i>Type a new task to insert in db, click on existing task to delete it</i>
<script language="javascript"
src="{{=URL(r=request,c='static',f='output/pygwt.js')}}">
</script>
</body>
</html>
from pyjamas.ui.RootPanel import RootPanel
from pyjamas.ui.Label import Label
from pyjamas.ui.VerticalPanel import VerticalPanel
from pyjamas.ui.TextBox import TextBox
import pyjamas.ui.KeyboardListener
from pyjamas.ui.ListBox import ListBox
from pyjamas.ui.HTML import HTML
from pyjamas.JSONService import JSONProxy
class TodoApp:
def onModuleLoad(self):
self.remote = DataService()
panel = VerticalPanel()
self.todoTextBox = TextBox()
self.todoTextBox.addKeyboardListener(self)
self.todoList = ListBox()
self.todoList.setVisibleItemCount(7)
self.todoList.setWidth("200px")
self.todoList.addClickListener(self)
self.Status = Label("")
panel.add(Label("Add New Todo:"))
panel.add(self.todoTextBox)
panel.add(Label("Click to Remove:"))
panel.add(self.todoList)
panel.add(self.Status)
self.remote.getTasks(self)
RootPanel().add(panel)
def onKeyUp(self, sender, keyCode, modifiers):
pass
def onKeyDown(self, sender, keyCode, modifiers):
pass
def onKeyPress(self, sender, keyCode, modifiers):
"""
This functon handles the onKeyPress event, and will add the item
in the text box to the list when the user presses the enter key.
In the future, this method will also handle the auto complete feature.
"""
if keyCode == KeyboardListener.KEY_ENTER and sender == self.todoTextBox:
id = self.remote.addTask(sender.getText(),self)
sender.setText("")
if id<0:
RootPanel().add(HTML("Server Error or Invalid Response"))
def onClick(self, sender):
id = self.remote.deleteTask(sender.getValue(sender.getSelectedIndex()),self)
if id<0:
RootPanel().add(HTML("Server Error or Invalid Response"))
def onRemoteResponse(self, response, request_info):
self.todoList.clear()
for task in response:
self.todoList.addItem(task[0])
self.todoList.setValue(self.todoList.getItemCount()-1,task[1])
def onRemoteError(self, code, message, request_info):
self.Status.setText("Server Error or Invalid Response: ERROR "
+ code + " - " + message)
class DataService(JSONProxy):
def __init__(self):
JSONProxy.__init__(self, "../../default/call/jsonrpc",
["getTasks", "addTask","deleteTask"])
if __name__ == '__main__':
app = TodoApp()
app.onModuleLoad()
cd /path/to/todo/static/
python ~/python/pyjamas-0.5p1/bin/pyjsbuild TodoApp.py