1 | """Table widget. |
---|
2 | """ |
---|
3 | import grok |
---|
4 | from hurry import yui |
---|
5 | from zope.interface import Interface |
---|
6 | from waeup.sirp.widgets.interfaces import ITableProvider |
---|
7 | |
---|
8 | def varName(string): |
---|
9 | varname = string.lower() |
---|
10 | return ''.join([x for x in varname |
---|
11 | if x in 'abcdefghijklmnopqrstuvwxyz_0123456789']) |
---|
12 | |
---|
13 | class Col(object): |
---|
14 | """A column in a table. |
---|
15 | """ |
---|
16 | header = 'Unnamed' |
---|
17 | type = None |
---|
18 | sortable = False |
---|
19 | width = 100 |
---|
20 | |
---|
21 | def __init__(self, header=u'Unnamed', width=None, sortable=False, |
---|
22 | type=None, data=()): |
---|
23 | self.header = header |
---|
24 | self.width = width |
---|
25 | self.sortable = sortable |
---|
26 | self.type = type |
---|
27 | self.data = data |
---|
28 | self.key = varName(header) |
---|
29 | |
---|
30 | class Table(object): |
---|
31 | """A table. |
---|
32 | """ |
---|
33 | def __init__(self, title=u'Unnamed', width=500, height=180, cols=()): |
---|
34 | self.title = title |
---|
35 | self.cols = cols |
---|
36 | self.width = width |
---|
37 | self.height = height |
---|
38 | self.internal_title = varName(title) |
---|
39 | |
---|
40 | def renderHTML(self): |
---|
41 | result = '<div id="%s-tablecontainer"><table id="%s-table">' % ( |
---|
42 | self.internal_title, self.internal_title) |
---|
43 | data_rows = self.getRows() |
---|
44 | result += '<thead><tr>' |
---|
45 | for col in self.cols: |
---|
46 | result += '<th>%s</th>' % (col.header,) |
---|
47 | result += '</tr></thead>\n' |
---|
48 | result += '<tbody>' |
---|
49 | |
---|
50 | for row in data_rows: |
---|
51 | result += '<tr>\n ' |
---|
52 | for elem in row: |
---|
53 | result += '<td>%s</td>' % elem |
---|
54 | result += '\n</tr>' |
---|
55 | result += '</tbody></table></div>' |
---|
56 | return result |
---|
57 | |
---|
58 | def getRows(self): |
---|
59 | data_cols = (x.data for x in self.cols) |
---|
60 | # turn rows into cols and vice versa: |
---|
61 | # ((a, 1, p), (b, 2, q)) --> ((a, b), (1, 2), (p, q)) |
---|
62 | data_rows = tuple(map(lambda *x: (x), *data_cols)) |
---|
63 | return data_rows |
---|
64 | |
---|
65 | |
---|
66 | class YUITable(Table): |
---|
67 | """A table that can generate JavaScript code for use with YUI. |
---|
68 | """ |
---|
69 | def need(self): |
---|
70 | yui.dragdrop.need() # datatable needs dragdrop loaded in advance. |
---|
71 | # This dependency is not defined yet in hurry.yui. |
---|
72 | yui.paginator.need() |
---|
73 | yui.datatable.need() |
---|
74 | yui.sam.need() |
---|
75 | yui.fonts.need() |
---|
76 | |
---|
77 | def getJSTableCode(self, paginator=True): |
---|
78 | title = self.internal_title |
---|
79 | fielddefs = ",".join(['{key:"%s"}'%x.key for x in self.cols]) |
---|
80 | coldefs = ",".join([ |
---|
81 | '{key:"%s",label:"%s",sortable:%s}' % ( |
---|
82 | x.key, x.header, str(x.sortable).lower()) |
---|
83 | for x in self.cols |
---|
84 | ]) |
---|
85 | result = """ |
---|
86 | YAHOO.util.Event.addListener(window, "load", function() { |
---|
87 | var %sDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get("%s-table")); |
---|
88 | %sDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE; |
---|
89 | %sDataSource.responseSchema = { |
---|
90 | fields: [%s] |
---|
91 | }; |
---|
92 | |
---|
93 | var %sColDefs = [%s]; |
---|
94 | var %sDataTable = new YAHOO.widget.DataTable("%s-tablecontainer", |
---|
95 | %sColDefs, %sDataSource, |
---|
96 | { |
---|
97 | paginator: new YAHOO.widget.Paginator({ |
---|
98 | rowsPerPage: 15, |
---|
99 | template: YAHOO.widget.Paginator.TEMPLATE_ROWS_PER_PAGE, |
---|
100 | rowsPerPageOptions: [10,15,30,50,100], |
---|
101 | pageLinks: 5 |
---|
102 | }), |
---|
103 | draggableColumns:true }); |
---|
104 | }); |
---|
105 | """ % ( |
---|
106 | title, title, title, title, fielddefs, title, coldefs, |
---|
107 | title, title, title, title) |
---|
108 | return result |
---|
109 | |
---|
110 | |
---|
111 | |
---|
112 | class YUIStaticTableView(grok.View): |
---|
113 | grok.context(Interface) |
---|
114 | grok.name('yuistatictables.js') |
---|
115 | grok.require('zope.Public') |
---|
116 | |
---|
117 | def render(self): |
---|
118 | self.response.setHeader('Content-Type', |
---|
119 | 'text/javascript; charset=UTF-8') |
---|
120 | try: |
---|
121 | provider = ITableProvider(self.context) |
---|
122 | except: |
---|
123 | # No table provider for the context. Be gentle... |
---|
124 | return u'/* No content */' |
---|
125 | tables = provider.getTables() |
---|
126 | results = [table.getJSTableCode() for table in tables] |
---|
127 | return '\n'.join(results) |
---|