GRIDPLUS2 - Example 6 | ![]() |
||||||
|
Example Of a Partial Application |
This is an example of a partial "Course Bookings" application using the gpdb command to access a TDBC based SQL database. This example is intended to demonstrate a number of GRIDPLUS screen desgin/layout features and how a GRIDPLUS application may be structured.
Note: The courses/locations/names in this example are entirely ficticious!!!
This example assumes familiarity with the previous/earlier examples, as the more basic GRIDPLUS usage is not described in full.
User Guide |
Main Window:
The toolbar contains four links:-
![]() | Make Booking. |
![]() | Show Bookings. |
![]() | Show Location. |
![]() | Exit Application. |
The main display has two tablelists. On the left is a list of available training courses, on the right is a list of dates on which the course is run.
The details of the selected course are shown in the bottom left text display. By default, details of the location for the currently selected course/date are shown in the bottom right text display.
Some courses are run at more than one location, selecting a date with a different location will update the location display:-
Selecting the Show Bookings toolbar link will cause the bottom right text display to show the bookings for the currently selected course/date. Selecting a different date will update the bookings display.
Selecting the Show Location toolbar link will cause the bottom right text display to show the location details for the currently selected course/date.
![]() | Save new booking. |
![]() | Close "New Booking" window without saving booking. |
![]() | Edit booking. |
![]() | Cancel booking. |
![]() | Save amended booking. |
![]() | Close "Edit Booking" window without saving changes. |
Source Code |
#-----------------------------------------# # Procedure To Display New Booking Screen # #-----------------------------------------# proc toolbar,book {} { global {} gpdb db . { select students from dates where dateid = :(.dates:dateid) } booked@ if {$(course@students) == $(booked@students)} { tk_messageBox -title "New Booking" -message "Course '[.courses title]' is Fully Booked" return } gridplus window .booking -modal 1 -windowcommand booking:details,close gridplus entry .booking.details -optionset input -wtitle "New Booking" { {|#Toolbutton "Save Booking" .save :filesave16 |: "Close" .close :fileclose16} = {"Course Title" .title <} {"Location" .location <} {"Date" .date 12 <} {"Booking Reference " .bookingid 12 <} = {"First Name" .firstname +} {"Last Name" .lastname} {"Company" .company} {"Address" .address1} {"" .address2} {"" .address3} {"Zip Code" .zipcode 12} } gpset [list \ .booking.details,title [.courses title] \ .booking.details,location [.dates location] \ .booking.details,date [.dates date] \ .booking.details,locationid [.dates locationid] \ .booking.details,bookingid [format {SAT%06s} [gpdb db . {select nextid from control; update control set nextid = nextid+1} =]] \ ] pack .booking.details } #------------------------------------------------------# # Procedure To Set "Info" Text Widget To Show Bookings # #------------------------------------------------------# proc toolbar,bookings {} { gpset @showLocation@ 0 refreshInfo } #------------------------------------------------------# # Procedure To Set "Info" Text Widget To Show Location # #------------------------------------------------------# proc toolbar,location {} { gpset @showLocation@ 1 refreshInfo } #-------------------------------# # Procedure To Exit Application # #-------------------------------# proc toolbar,exit {} { db close exit } #---------------------------# # Procedure To Edit Booking # #---------------------------# proc info,edit {} { global {} gridplus window .edit -modal 1 -windowcommand edit:details,close gridplus entry .edit.details -optionset input -wtitle "Edit Booking" { {|#Toolbutton "Save Booking" .save :filesave16 |: "Close" .close :fileclose16} = {"Course Title" .title <} {"Location" .location <} {"Date" .date 12 <} {"Booking Reference " .bookingid 12 <} = {"First Name" .firstname +} {"Last Name" .lastname} {"Company" .company} {"Address" .address1} {"" .address2} {"" .address3} {"Zip Code" .zipcode 12} } gpdb db .edit.details, { select bookings.bookingid, bookings.firstname, bookings.lastname, bookings.company, bookings.address1, bookings.address2, bookings.address3, bookings.zipcode, strftime('%d/%m/%Y',date(bookings.time,'unixepoch')) as date, courses.title, locations.address1 as location from bookings, courses, locations where bookings.bookingid = :(.info) and courses.courseid = bookings.courseid and locations.locationid = bookings.locationid } pack .edit.details } #-----------------------------# # Procedure To Cancel Booking # #-----------------------------# proc info,cancel {} { global {} gpdb db . { select firstname || ' ' || lastname as name from bookings where bookingid = :(.info) } booking@ set action [tk_messageBox -icon warning -title "Cancel Booking" -message "Cancel Booking For '$(booking@name)'" -type yesno] if {$action eq "yes"} { setStudents $(.info) -1 gpdb db . {delete from bookings where bookingid = :(.info)} updateBookings refreshInfo } } #-------------------------------# # Procedure To Save New Booking # #-------------------------------# proc booking:details,save {} { global {} gpdb db .booking.details, { insert into bookings values( :(bookingid), :(.courses:courseid), :(.dates:dateid), :(locationid), :(.dates:time), :(firstname), :(lastname), :(company), :(address1), :(address2), :(address3), :(zipcode) ) } setStudents $(.booking.details,bookingid) +1 updateBookings refreshInfo booking:details,close } #------------------------------------------------------# # Procedure To Close New Booking Window Without Saving # #------------------------------------------------------# proc booking:details,close {} { gridplus clear .booking destroy .booking } #----------------------------------# # Procedure To Save Edited Booking # #----------------------------------# proc edit:details,save {} { global {} gpdb db .edit.details, { update bookings set firstname = :(firstname), lastname = :(lastname), company = :(company), address1 = :(address1), address2 = :(address2), address3 = :(address3), zipcode = :(zipcode) where bookingid = :(.info) } updateBookings refreshInfo edit:details,close } #-------------------------------------------------------# # Procedure To Close Edit Booking Window Without Saving # #-------------------------------------------------------# proc edit:details,close {} { gridplus clear .edit destroy .edit } #-------------------------------------------------------# # Procedure To Set Number Of Students Booked For Course # #-------------------------------------------------------# proc setStudents {bookingid increment} { global {} gpset @bookingid@ $bookingid gpset @increment@ $increment gpdb db . { update dates set students = students + :(@increment@) where dateid = (select dates.dateid from bookings, dates where bookings.bookingid = :(@bookingid@) and dates.dateid = bookings.dateid) } } #--------------------------------------# # Procedure To Refresh Courses Display # #--------------------------------------# proc refreshCourses {} { gpdb db . { select courseid, title, duration from courses } .courses } #-------------------------------------# # Procedure To Refresh Course Display # #-------------------------------------# proc refreshCourse {} { global {} gpdb db . { select * from courses where courseid = :(.courses:courseid) } course@ gpset -| .course \ "<font helvetica:default><size 10:default><bgcolor lightgray><size +6><b>$(course@title)</b></size> </bgcolor> <b>Course Code</b><indent 6>$(course@courseid)</indent> <b>Format</b><indent 6>$(course@format)</indent> <b>Duration</b><indent 6>$(course@duration)</indent> <b>Description</b><indent 6>$(course@description)</indent> <b>Prerequisites</b><indent 6>$(course@prerequisites)</indent> <b>Objectives</b><indent 6>$(course@objectives)</indent> <b>Students</b><indent 6>$(course@students) (maximum)</indent> " } #---------------------------------------------------------------# # Procedure To Update/Refresh Display When A Course Is Selected # #---------------------------------------------------------------# proc courses {} { refreshCourse refreshDates updateLocation updateBookings refreshInfo } #--------------------------------------------------------------------# # Procedure To Update/Refresh Display When A Course Date Is Selected # #--------------------------------------------------------------------# proc dates {} { updateLocation updateBookings refreshInfo } #------------------------------------# # Procedure To Refresh Dates Display # #------------------------------------# proc refreshDates {} { gpdb db . { select dates.dateid, locations.locationid, dates.time, strftime('%d/%m/%Y',date(dates.time,'unixepoch')) as date, locations.address1 from dates, locations where dates.courseid = :(.courses:courseid) and dates.locationid = locations.locationid } .dates } #----------------------------------------------# # Procedure To Update Location Display Details # #----------------------------------------------# proc updateLocation {} { global {} gpdb db . { select * from locations where locationid = :(.dates:locationid) } location@ image create photo locationImage -data $(location@image) gpset -| @location@ \ "<font helvetica:default><size 10:default><bgcolor lightgray><size +6><b>$(location@address1)</b></size> </bgcolor> <b>Image</b><indent 6><image locationImage></indent> <b>Address</b><indent 6>$(location@address1) $(location@address2) $(location@address3) $(location@zipcode)</indent> " } #----------------------------------------------# # Procedure To Update Bookings Display Details # #----------------------------------------------# proc updateBookings {} { global {} gpset -| @bookings@ \ "<font helvetica:default><size 10:default><bgcolor lightgray><size +6><b>Bookings: <size +4>[.dates date]</b></size> </bgcolor>" gpdb db . { select * from bookings where dateid = :(.dates:dateid) } foreach { gpset -| @bookings@ \ "$(@bookings@) <image :edit16~edit:$(booking@bookingid)> <image :actcross16~cancel:$(booking@bookingid)><indent 3>$(booking@firstname) $(booking@lastname) $(booking@company) $(booking@address1) $(booking@address2) $(booking@address3) $(booking@zipcode)</indent> " } booking@ } #-------------------------------------# # Procedure To Refresh "Info" Display # #-------------------------------------# proc refreshInfo {} { global {} if {$(@showLocation@)} { gpset .info $(@location@) } else { gpset .info $(@bookings@) } } #=======================# # Start The Application # #=======================# package require gridplus 2.11 namespace import -force gridplus::* #----------------------# # Initialise Variables # #----------------------# gpset @showLocation@ 1 #---------------# # Open Database # #---------------# # Require TDBC with Sqlite3 driver. package require tdbc::sqlite3 # Open database tdbc::sqlite3::connection create db "C:/GRIDPLUS/gridplus211/examples/example6.db" #-----------------------------------------------# # Set Widget Defaults And GRIDPLUS options sets # #-----------------------------------------------# gpoptions { pad 0 padding {0 0 0 0} } gridplus optionset Toolbutton { -widget button -width 12 } gridplus optionset input { -padding {5 5 5 5} -width 60 } #----------------------------# # Create Main User Interface # #----------------------------# gridplus button .toolbar -style Toolbutton { {"Make Booking" .book :caltoday16} {"Show Bookings" .bookings :callist16} \ {"Show Location" .location :navhome16} {"Exit" .exit :actexit16} } gridplus tablelist .courses -scroll y -height 8 -width 75 -selectfirst 1 -action single { 0 Code =courseid 0 Title 0 Duration } gridplus tablelist .dates -scroll y -height 8 -width 45 -selectfirst 1 -sortfirst 1 -action single { 0 dateid hide 0 locationid hide 0 time hide 0 Date 0 Location } gridplus text .course -scroll y -tags 1 -height 20 -width 75 gridplus text .info -scroll y -tags 1 -height 20 -width 45 gridplus layout .main -wtitle "Course Bookings" { .toolbar - .courses .dates .course .info } pack .main #------------------------------# # Populate Interface With Data # #------------------------------# refreshCourses courses
Comments |
proc toolbar,book {} { global {} gpdb db . { select students from dates where dateid = :(.dates:dateid) } booked@ if {$(course@students) == $(booked@students)} { tk_messageBox -title "New Booking" -message "Course '[.courses title]' is Fully Booked" return } gridplus window .booking -modal 1 -windowcommand booking:details,close gridplus entry .booking.details -optionset input -wtitle "New Booking" { {|#Toolbutton "Save Booking" .save :filesave16 |: "Close" .close :fileclose16} = {"Course Title" .title <} {"Location" .location <} {"Date" .date 12 <} {"Booking Reference " .bookingid 12 <} = {"First Name" .firstname +} {"Last Name" .lastname} {"Company" .company} {"Address" .address1} {"" .address2} {"" .address3} {"Zip Code" .zipcode 12} } gpset [list \ .booking.details,title [.courses title] \ .booking.details,location [.dates location] \ .booking.details,date [.dates date] \ .booking.details,locationid [.dates locationid] \ .booking.details,bookingid [format {SAT%06s} [gpdb db . {select nextid from control; update control set nextid = nextid+1} =]] \ ] pack .booking.details }
This is a procedure to display the "New Booking" screen.
The "Toolbutton" style applies both the ttk "Toolbutton" style -and- the "Toolbutton" optionset to the button grid.
The gpset command is used to set values for the disabled entries. This makes use of the tablelist widget command to obtain values from the ".courses" and ".dates" tablelists.
The next available booking ID is obtained from the databse "control" table using the gpdb command...
gpdb db . {select nextid from control; update control set nextid = nextid+1} =
...which returns the selected "nextid" and increments the value ready for the next booking.
proc toolbar,bookings {} { gpset @showLocation@ 0 refreshInfo }
This is a procedure to set the "@showLocation@" flag. When this flag is set to zero
the bottom right text display will show the bookings for the currently
selected course/date.
The flag is stored in the global null named array using gpset.
This to store the values of the GRIDPLUS widgets, but it is safe to use it for other purposes.
It is recommended that the name have an "@" prefix/siffix to ensure it will not clash, and will
not be cleared by a GRIDPLUS clear command/mode.
The call to "refreshInfo" updates the ".info" text to show the bookings.
This is a procedure to set the "@showLocation@" flag. When this flag is set to zero
the bottom right text display will show the bookings for the currently selected course/date.
See the above comments for "toolbar,bookings".
This is a procedure to close the database and exit the application.
This is a procedure to display the "Edit Booking" screen.
The "Toolbutton" style applies both the ttk "Toolbutton" style -and- the "Toolbutton"
optionset to the button grid.
The gpdb command populates the entries from "bookings", "courses"
and "locations" database tables, for the selected "bookingid".
This is a procedure to cancel (delete) a booking.
The gpdb command obtains the name of the selected person from the "bookings" table. This value is to be identfied as "name"
with the item prefix "booking@". Therefore the null named array item "booking@name" will be set to the value of the name of the selected person.
A confirmation dialog is displayed. If the user presses the "Yes" button, the number of
students booked on the course is decremented, the booking is deleted from the database and the
display updated to reflect the change.
This is a procedure to save a new booking into the database.
The gpdb command is used to insert the new booking values.
After the booking is added to the database the number of students booked on the course is
incremented, the display updated to reflect the change and the window is closed using the
"booking:details,close" procedure.
NOTE: Where the name of a value begins with "." (For example: ".courses.courseid")
it is the full name of the GRIDPLUS item. If not(For example "firstname"), the window name
(in this case ".booking.details,") will be added as a prefix (".booking.details,firstname").
This is a procedure to clear the contents of the ".booking" window and to destroy it.
This is a procedure to save an edited booking into the database.
The gpdb command is used to update the booking values.
After the edited booking is written to the database the display updated to reflect the change and
the window is closed using the "edit:details,close" procedure.
This is a procedure to clear the contents of the ".edit" window and to destroy it.
This is a procedure to increment/decrement (depending on the value of "increment")
the number of students booked for the course/date associated with "bookingid".
NOTE: The gpset command is used to set the values of "@bookingid@"
and "@increment@" in order for them to be accessed within "gpdb". Using the "@" prefix/suffix
will ensure that the names do not conflict with any automatically generated item names. Other characters could
be used, however; This is the recommended convention.
This procedure uses the gpdb command to update/refresh the contents of the
".courses" tablelist.
This is a procedure to update/refresh the ".course" text.
The gpdb command is used to read the course details from the database into the null named array.
The array items are the names of the result column prefixed with "course@".
The gpset command is used to set the contents of the ".course" text.
As the ".course" text item is set to have the tag processing enabled, gpset
will process the tags automatically.
NOTE: The gpset command makes use of the "-|"
option to allow the value text to be indented in the source code without effecting what appears in the application.
The indent (which must be space characters only) is automatically removed when the value is set.
This is a procedure to update/refresh the ".dates" tablelist,
update/set the "location" and "bookings" global null named array items and
update/refresh the ".info" text, when a line is selected in the
".courses" tablelist.
This is a procedure to update/set the "location" and "bookings" global
null named array items and update/refresh the ".info" text,
when a line is selected in the ".dates" tablelist.
This procedure uses the gpdb to update/refresh the contents of the ".dates" tablelist.
This is a procedure to update/set the value of the "@location@" item in the global
null named array.
The gpdb command is used to read the location details from the database
into the null named array. The array items are the names of the result column prefixed with "location@".
The image of the location is stored in the database as a base64 encoded GIF. The Tk image
is created using the "image create" command. This information will be displayed in
the ".info" text when the ".info" text is set to
the value of "$(@location@)".
This is a procedure to update/set the value of the "@bookings@" item in the global null named array.
The booking date is returned by the ".dates" widget command.
The heading information is set, then for each booking, the booking information is added to the "(@bookings@)"
array item. To do this the gpdb command foreach option is used. The "foreach"
command body is executed for all results matching the "select" criteria. The column values for each returned
row are put into null named array prefixed with "booking@"
The first line of each booking is prefixed with two icons.
For example: The "edit" icon is created using the following tag:-
<image :edit16~edit:$(booking@bookingid)>
This will display the "edit16" icon from the ICONS
package. The icon has an associated command "edit". As the GRIDPLUS text
which will contain this icon is called ".info", the name of the procedure invoked by the icon
will be "info,edit". The command also has a parameter, in this case the
"booking@bookingid". When the icon is clicked the value of "$(.info)" will be set
to the value of "$(booking@bookingid)" and "info,edit" invoked.
This is a procedure to set the contents of the ".info" text
depening on the value of the "$(@showLocation@)" flag.
This is the start of processing. The "(@showLocation@)" flag is initialised and
the database opened.
Sets the option database and optionsets for the application.
Creates a toolbar using GRIDPLUS buttons.
The "Toolbutton" style applies both the ttk "Toolbutton" style -and- the "Toolbutton"
optionset to the button grid.
Creates two tablelists. Both tablelists have the
-selectfirst 1 option set. This
causes the first row in the tablelist to be automatically selected when the
content of the tablelist is set using the gpset command.
Both tablelists also have the -action single option
set. This sets a binding such that when a line is selected using a single-click the procedure
associated with the tablelist ("courses" or "dates") is also invoked.
The -sortfirst 1 option used for ".dates"
makes sure that the dates are displayed in the correct order.
Creates two texts. Both have a vertical scrollbar and
tags processing enabled.
Create and display the GRIDPLUS window layout.
Initialise the contents of the tablelists and texts.
proc toolbar,location {} {
gpset @showLocation@ 1
refreshInfo
}
proc toolbar,exit {} {
db close
exit
}
proc info,edit {} {
global {}
gridplus window .edit -modal 1 -windowcommand edit:details,close
gridplus entry .edit.details -optionset input -wtitle "Edit Booking" {
{|#Toolbutton "Save Booking" .save :filesave16 |: "Close" .close :fileclose16}
=
{"Course Title" .title <}
{"Location" .location <}
{"Date" .date 12 <}
{"Booking Reference " .bookingid 12 <}
=
{"First Name" .firstname +}
{"Last Name" .lastname}
{"Company" .company}
{"Address" .address1}
{"" .address2}
{"" .address3}
{"Zip Code" .zipcode 12}
}
gpdb db .edit.details, {
select bookings.bookingid,
bookings.firstname,
bookings.lastname,
bookings.company,
bookings.address1,
bookings.address2,
bookings.address3,
bookings.zipcode,
strftime('%d/%m/%Y',date(bookings.time,'unixepoch')) as date,
courses.title,
locations.address1 as location
from bookings,
courses,
locations
where bookings.bookingid = :(.info)
and courses.courseid = bookings.courseid
and locations.locationid = bookings.locationid
}
pack .edit.details
}
proc info,cancel {} {
global {}
gpdb db . {
select firstname || ' ' || lastname as name
from bookings
where bookingid = :(.info)
} booking@
set action [tk_messageBox -icon warning -title "Cancel Booking" -message "Cancel Booking For '$(booking@name)'" -type yesno]
if {$action eq "yes"} {
setStudents $(.info) -1
gpdb db . {delete from bookings where bookingid = :(.info)}
updateBookings
refreshInfo
}
}
proc booking:details,save {} {
global {}
gpdb db .booking.details, {
insert into bookings
values(
:(bookingid),
:(.courses:courseid),
:(.dates:dateid),
:(locationid),
:(.dates:time),
:(firstname),
:(lastname),
:(company),
:(address1),
:(address2),
:(address3),
:(zipcode)
)
}
setStudents $(.booking.details,bookingid) +1
updateBookings
refreshInfo
booking:details,close
}
proc booking:details,close {} {
gridplus clear .booking
destroy .booking
}
proc edit:details,save {} {
global {}
gpdb db .edit.details, {
update bookings
set firstname = :(firstname),
lastname = :(lastname),
company = :(company),
address1 = :(address1),
address2 = :(address2),
address3 = :(address3),
zipcode = :(zipcode)
where bookingid = :(.info)
}
updateBookings
refreshInfo
edit:details,close
}
proc edit:details,close {} {
gridplus clear .edit
destroy .edit
}
proc setStudents {bookingid increment} {
global {}
gpset @bookingid@ $bookingid
gpset @increment@ $increment
gpdb db . {
update dates
set students = students + :(@increment@)
where dateid = (select dates.dateid
from bookings,
dates
where bookings.bookingid = :(@bookingid@)
and dates.dateid = bookings.dateid)
}
}
proc refreshCourses {} {
gpdb db . {
select courseid,
title,
duration
from courses
} .courses
}
proc refreshCourse {} {
global {}
gpdb db . {
select *
from courses
where courseid = :(.courses:courseid)
} course@
gpset -| .course \
"<font helvetica:default><size 10:default><bgcolor lightgray><size +6><b>$(course@title)</b></size>
</bgcolor>
<b>Course Code</b><indent 6>$(course@courseid)</indent>
<b>Format</b><indent 6>$(course@format)</indent>
<b>Duration</b><indent 6>$(course@duration)</indent>
<b>Description</b><indent 6>$(course@description)</indent>
<b>Prerequisites</b><indent 6>$(course@prerequisites)</indent>
<b>Objectives</b><indent 6>$(course@objectives)</indent>
<b>Students</b><indent 6>$(course@students) (maximum)</indent>
"
}
proc courses {} {
refreshCourse
refreshDates
updateLocation
updateBookings
refreshInfo
}
proc dates {} {
updateLocation
updateBookings
refreshInfo
}
proc refreshDates {} {
gpdb db . {
select dates.dateid,
locations.locationid,
dates.time,
strftime('%d/%m/%Y',date(dates.time,'unixepoch')) as date,
locations.address1
from dates,
locations
where dates.courseid = :(.courses:courseid)
and dates.locationid = locations.locationid
} .dates
}
proc updateLocation {} {
global {}
gpdb db . {
select * from locations
where locationid = :(.dates:locationid)
} location@
image create photo locationImage -data $(location@image)
gpset -| @location@ \
"<font helvetica:default><size 10:default><bgcolor lightgray><size +6><b>$(location@address1)</b></size>
</bgcolor>
<b>Image</b><indent 6><image locationImage></indent>
<b>Address</b><indent 6>$(location@address1)
$(location@address2)
$(location@address3)
$(location@zipcode)</indent>
"
}
proc updateBookings {} {
global {}
gpset -| @bookings@ \
"<font helvetica:default><size 10:default><bgcolor lightgray><size +6><b>Bookings: <size +4>[.dates date]</b></size>
</bgcolor>"
gpdb db . {
select *
from bookings
where dateid = :(.dates:dateid)
} foreach {
gpset -| @bookings@ \
"$(@bookings@)
<image :edit16~edit:$(booking@bookingid)> <image :actcross16~cancel:$(booking@bookingid)><indent 3>$(booking@firstname) $(booking@lastname)
$(booking@company)
$(booking@address1)
$(booking@address2)
$(booking@address3)
$(booking@zipcode)</indent>
"
} booking@
}
proc refreshInfo {} {
global {}
if {$(@showLocation@)} {
gpset .info $(@location@)
} else {
gpset .info $(@bookings@)
}
}
#----------------------#
# Initialise Variables #
#----------------------#
gpset @showLocation@ 1
#---------------#
# Open Database #
#---------------#
# Require TDBC with Sqlite3 driver.
package require tdbc::sqlite3
# Open database
tdbc::sqlite3::connection create db "C:/GRIDPLUS/gridplus211/examples/example6.db"
gpoptions {
pad 0
padding {0 0 0 0}
}
gridplus optionset Toolbutton {
-widget button
-width 12
}
gridplus optionset input {
-padding {5 5 5 5}
-width 60
}
gridplus button .toolbar -style Toolbutton {
{"Make Booking" .book :caltoday16} {"Show Bookings" .bookings :callist16} \
{"Show Location" .location :navhome16} {"Exit" .exit :actexit16}
}
gridplus tablelist .courses -scroll y -height 8 -width 75 -selectfirst 1 -action single {
0 Code =courseid
0 Title
0 Duration
}
gridplus tablelist .dates -scroll y -height 8 -width 45 -selectfirst 1 -sortfirst 1 -action single {
0 dateid hide
0 locationid hide
0 time hide
0 Date
0 Location
}
gridplus text .course -scroll y -tags 1 -height 20 -width 75
gridplus text .info -scroll y -tags 1 -height 20 -width 45
gridplus layout .main -wtitle "Course Bookings" {
.toolbar -
.courses .dates
.course .info
}
pack .main
refreshCourses
courses
Copyright © 2015 Adrian Davis.