1
+ <!DOCTYPE html>
2
+ < html >
3
+ < head >
4
+ < meta http-equiv ="content-type " content ="text/html; charset=windows-1252 "> < meta charset ="iso-8859-1 ">
5
+ < style >
6
+ body , td , th {
7
+ font-family : sans-serif;
8
+ font-size : 12px ;
9
+ }
10
+ td {
11
+ border-style : solid;
12
+ border-width : 0px 0px 1px 0px ;
13
+ border-color : # 000 ;
14
+ padding : 3px ;
15
+ }
16
+ th {
17
+ border-style : solid;
18
+ border-width : 1px ;
19
+ border-color : # 000 ;
20
+ background-color : # 61D7A4 ;
21
+ padding : 4px ;
22
+ }
23
+ </ style >
24
+ < script type ="text/javascript " src ="https://cdnjs.cloudflare.com/ajax/libs/brython/3.8.8/brython.js "> </ script >
25
+ </ head >
26
+ < body onload ="brython(1) ">
27
+ < script id ="ascript " type ="text/python ">
28
+ from browser import document , window , html
29
+
30
+ IDB = window . indexedDB
31
+
32
+ def create_db ( * args ) :
33
+ # The database did not previously exist , so create object stores and indexes .
34
+ print ( 'create db' )
35
+ db = request . result
36
+ store = db . createObjectStore ( "books" , { "keyPath" : "isbn" } )
37
+ titleIndex = store . createIndex ( "by_title" , "title" , { "unique" : True } )
38
+ authorIndex = store . createIndex ( "by_author" , "author" )
39
+
40
+ # Populate with initial data .
41
+ store . put ( { "title" : "Quarry Memories" , "author" : "Fred" , "isbn" : 123456 } )
42
+ store . put ( { "title" : "Water Buffaloes" , "author" : "Fred" , "isbn" : 234567 } )
43
+ store . put ( { "title" : "Bedrock Nights" , "author" : "Barney" , "isbn" : 345678 } )
44
+
45
+
46
+ def btn_click ( ev ) :
47
+ "" "Generic callback function for buttons
48
+ " ""
49
+ # The text on the button indicates the action : Add , Edit , Update or Delete
50
+ action = ev . target . text
51
+
52
+ # table row of the clicked button
53
+ row = ev . target . parent . parent
54
+
55
+ if action == "Delete" :
56
+ db = request . result
57
+ tx = db . transaction ( "books" , "readwrite" )
58
+ store = tx . objectStore ( "books" )
59
+ cursor = store . delete ( row . key )
60
+
61
+ # when record is deleted , update table
62
+ cursor . bind ( "success" , show )
63
+
64
+ elif action == "Add" :
65
+ values = [ entry . value for entry in row . get ( selector = "INPUT" ) ]
66
+ data = dict ( zip ( [ 'title' , 'author' , 'isbn' ] , values ) )
67
+ db = request . result
68
+ tx = db . transaction ( "books" , "readwrite" )
69
+ store = tx . objectStore ( "books" )
70
+ if action == "Add" :
71
+ cursor = store . put ( data )
72
+ else:
73
+ cursor = store . put ( data , row . key )
74
+
75
+ # when record is added , update table
76
+ cursor . bind ( "success" , show )
77
+
78
+ elif action == "Edit" :
79
+ # Replace cells for "title" and "author" by INPUT fields
80
+ # Since isbn is he keyPath it can 't be edited
81
+ cells = row . get ( selector = "TD" )
82
+ for cell in cells [ :- 2 ] :
83
+ value = cell . text
84
+ cell . clear ( )
85
+ cell <= html . INPUT ( value = value )
86
+
87
+ # Replace buttons "Edit" and "Delete" by button "Update"
88
+ cells [ - 1 ] . clear ( )
89
+ update_btn = html . BUTTON ( "Update" )
90
+ cells [ - 1 ] <= update_btn
91
+
92
+ # Bind its "click" event
93
+ update_btn . bind ( "click" , btn_click )
94
+
95
+ elif action == "Update" :
96
+ values = [ entry . value for entry in row . select ( "INPUT" ) ]
97
+ data = dict ( zip ( [ "title" , "author" ] , values ) )
98
+ data [ 'isbn' ] = row . key # required for the "store.put" method below
99
+
100
+ db = request . result
101
+ tx = db . transaction ( "books" , "readwrite" )
102
+ store = tx . objectStore ( "books" )
103
+ cursor = store . put ( data )
104
+
105
+ # When record is added , update table
106
+ cursor . bind ( "success" , show )
107
+
108
+
109
+ def show ( ev ) :
110
+ "" "Show the contents of store " books " in a table" ""
111
+ db = request . result
112
+ tx = db . transaction ( "books" , "readonly" )
113
+ store = tx . objectStore ( "books" )
114
+ cursor = store . openCursor ( )
115
+
116
+ # clear table
117
+ document [ "table" ] . clear ( )
118
+
119
+ # headers
120
+ t = html . TABLE ( )
121
+ document [ "table" ] <= t
122
+
123
+ t <= html . TR ( html . TH ( x ) for x in [ "Title" , "Author" , "ISBN" , "Actions" ] )
124
+
125
+ def add_row ( ev ) :
126
+ "" "Add a row to the table for each iteration on cursor
127
+ When cursor in empty , add a line for new record insertion
128
+ "" "
129
+ res = ev . target . result
130
+ if res:
131
+ v = res . value
132
+ row = html . TR ( )
133
+ row <= ( html . TD ( getattr ( v , key ) )
134
+ for key in [ "title" , "author" , "isbn" ] )
135
+ row <= html . TD ( html . BUTTON ( "Edit" ) +
136
+ html . BUTTON ( "Delete" ) )
137
+ row . key = res . key
138
+ t <= row
139
+ getattr ( res , "continue" ) ( )
140
+ else:
141
+ # add empty row
142
+ row = html . TR ( )
143
+ row <= ( html . TD ( html . INPUT ( name = "new_%s" % key ) )
144
+ for key in [ "title" , "author" , "isbn" ] )
145
+ row <= html . TD ( html . BUTTON ( "Add" ) )
146
+ t <= row
147
+ # bind all buttons
148
+ for btn in t . get ( selector = "BUTTON" ) :
149
+ btn . bind ( "click" , btn_click )
150
+
151
+ cursor . bind ( "success" , add_row )
152
+
153
+
154
+ request = IDB . open ( "library" )
155
+
156
+ # If database doesn 't exist, create it
157
+ request . bind ( "upgradeneeded" , create_db )
158
+
159
+ # Else print a table with all elements in table "books"
160
+ request . bind ( "success" , show )
161
+ </ script >
162
+
163
+ < h1 > Library</ h1 >
164
+
165
+ < div id ="table "> < table > < tr > < th > Title</ th > < th > Author</ th > < th > ISBN</ th > < th > Actions</ th > </ tr > < tr > < td > < input name ="new_title "> </ td > < td > < input name ="new_author "> </ td > < td > < input name ="new_isbn "> </ td > < td > < button > Add</ button > </ td > </ tr > </ table > </ div >
166
+
167
+ < style >
168
+ /* colors for highlighted Python code */
169
+ span .python-string {
170
+ color : # 27d ;
171
+ }
172
+ span .python-comment {
173
+ color : # 019 ;
174
+ }
175
+ span .python-keyword {
176
+ color : # 950 ;
177
+ }
178
+ span .python-builtin {
179
+ color : # 183 ;
180
+ }
181
+ em {
182
+ color : # 339 ;
183
+ font-family : courier
184
+ }
185
+ strong {
186
+ color : # 339 ;
187
+ font-family : courier;
188
+ }
189
+ button .nice {
190
+ margin-right : 15% ;
191
+ color : # fff ;
192
+ background : # 7ae ;
193
+ border-width : 2px ;
194
+ border-style : solid;
195
+ border-radius : 5px ;
196
+ border-color : # 45b ;
197
+ text-align : center;
198
+ font-size : 15px ;
199
+ padding : 6px ;
200
+ }
201
+ </ style >
202
+ </ body >
203
+ </ html >
0 commit comments