The best I can come up with so far is my use of a generic view (I'm just 
getting into this web app stuff). I suspect that I need to elaborate 
index.html. Sound right?
Here's my code:


Control -- dispatch_board.py and default.py

#-------------------------------------------------------------------------------
# Name:        dispatch_board
# Purpose:
#
# Author:      Frank Hall
#
# Created:     26/12/2011
# Copyright:
# Licence:     <your licence>
#-------------------------------------------------------------------------------
#!/usr/bin/env python

import re
import pickle

def quote(text):
    return str(text).replace('\\', '\\\\').replace("'", "\\'")

def valid_key(key):
    return re.match('L\d+D\d+', key)

def load_key(row, col):
    return 'L%sD%s'%(row, col)

def jq_cmd(key, value):
    return "jQuery('#%s').val('%s');" % (key, quote(value))

class Node:

    def __init__(self, name, value, size=4, url='.', readonly=True):
        self.name = name
        self.value = value
        self.size = size
        self.url = url
        self.readonly = readonly

    def xml(self):
        return """<input name="%s" id="%s" value="%s" size="%s"
        onfocus="ajax('%s/focus',['%s'], ':eval');"
        onmouseup="ajax('%s/mouseup',['%s'], ':eval');" %s/>
        """ % (self.name, self.name, self.value, self.size,
               self.url, self.name, self.url, self.name,
               (self.readonly and 'readonly ') or '')

    def __repr__(self):
        return self.value


class DispatchBoard:

    def dumps(self):
        return pickle.dumps(self)

    @staticmethod
    def loads(data):
        return pickle.loads(data)

    def load_row_col(self, key):
        if key == '':
            (row, col) = (-1, -1)
        else:
            (row, col) = key[1:].split('D')
        return (int(row), int(col))

    def get_load_value(self, row, col):
        key = load_key(row, col)
        return self.nodes[key].value

    def set_load_value(self, row, col, value):
        key = load_key(row, col)
        self.nodes[key].value = value
        jquery = jq_cmd(key, value)
        return jquery

    def delete_load(self, row, col):
        rnew = self.rows - 1
        r = row
        jquery = ''
        while r < rnew:
            value = self.get_load_value(r + 1, col)
            jquery += self.set_load_value(r, col, value)
            r = r + 1
        jquery += self.set_load_value(r, col, '')
        return jquery

    def insert_load(self, row, col, value, after = False):
        rnew = row
        if after:
            rnew = rnew + 1
        r = self.rows - 1
        jquery = ''
        while r > rnew:
            value_move = self.get_load_value(r - 1, col)
            jquery += self.set_load_value(r, col, value_move)
            r = r - 1
        if r == rnew:
            jquery += self.set_load_value(r, col, value)
        return jquery

    def move_load(self, from_row, from_col, to_row, to_col, after = False):
        value = self.get_load_value(from_row, from_col)
        jquery = self.insert_load(to_row, to_col, value, after)
        jquery += self.delete_load(from_row, from_col)
        return jquery

    def mouseup(self, key):
        if (self.drag_key != '') & (key != self.drag_key):
            (from_row, from_col) = self.load_row_col(self.drag_key)
            (to_row, to_col) = self.load_row_col(key)
            jquery = self.move_load(from_row, from_col, to_row, to_col)
        else:
            jquery = ''
        self.drag_key = ''
        return jquery

    def focus(self, key):
        self.drag_key = key

    def process(self, callback_args):
        ##call this in action that creates table, it will handle ajax 
callbacks
        func = callback_args['func']
        key = callback_args['key']
        if func == 'focus':
            return self.focus(key)
        elif func == 'mouseup':
            return self.mouseup(key)

    def cell(self, key, value, size=4, readonly=True):
        ##key is the name of the cell
        ##value is the initial value of the cell.
        if not valid_key(key):
            raise SyntaxError, "Invalid cell name: %s" % key
        self.nodes[key] = Node(key, value, size, self.url, readonly)

    def xml(self):
        import gluon.html
        (DIV, TABLE, TR, TD, TH, BR) = \
            (gluon.html.DIV, gluon.html.TABLE, gluon.html.TR, gluon.html.TD,
             gluon.html.TH, gluon.html.BR)
        xml_board = DIV(TABLE( \
                    TR(TH(),*[TH('Driver %s' % c) \
                         for c in range(self.cols)]), \
                    *[TR(TH('Load %s' % r), \
                    *[TD(self.nodes[load_key(r, c)]) \
                         for c in range(self.cols)]) \
                         for r in range(self.rows)])).xml()
        return xml_board

    def __init__(self, rows, cols, size=4, url='.', readonly=True):
        self.rows = rows
        self.cols = cols
        self.size = size
        self.url = url
        self.nodes = {}
        self.error = 'ERROR: %(error)s'
        self.drag_key = ''
        for k in xrange(rows*cols):
            key = load_key(k/cols, k%cols)
            self.cell(key, key, size, readonly)

if __name__ == '__main__':
    pass


# -*- coding: utf-8 -*-
# this file is released under public domain and you can use without 
limitations

#########################################################################
## default.py
#########################################################################

from dispatch_board import DispatchBoard

board_rows = 5
board_cols = 5
cell_size = 10
board_cache_key = 'board1'
board_callback = 'callback'


def callback():
    callback_args = {}
    callback_args['func'] = request.args(0)
    callback_args['key'] = request.vars.keys()[0]
    return cache.ram(board_cache_key, lambda: None, 
None).process(callback_args)


def index():
    board = cache.ram(board_cache_key,
                      lambda: DispatchBoard(board_rows, board_cols, 
cell_size, \
                      URL(r=request, f=board_callback)), 0)
    board.nodes['L0D3'].value = 'Frank'
    return dict(board=board)


View -- index.html:

{{extend 'layout.html'}}
{{=board}}

Reply via email to