package require Tk proc editRecord {title headers fields} { set oldfocus [focus] set w [toplevel .[clock clicks]] wm resizable $w 1 0 wm title $w $title set n 0 foreach h $headers f $fields { label $w.h$n -text $h -anchor e [entry $w.e$n -width [string length $f]] insert end $f grid $w.h$n $w.e$n -sticky news incr n } button $w.ok -text OK -width 5 -command [list set $w 1] button $w.cancel -text Cancel -command [list set $w 0] grid $w.ok $w.cancel -pady 5 grid columnconfigure $w 1 -weight 1 vwait ::$w if [set ::$w] { #-- collect the current entry contents set n 0 foreach f $fields { lappend res [$w.e$n get] incr n } } else {set res {}} destroy $w unset ::$w ;#-- clean up the vwait variable focus $oldfocus return $res } #-- Testing: wm withdraw . set db { {Author Title Year Category} {{Puzo, Mario} {The Godfather} 1965 Drama} {{Verne, Jules} {Around the world in 80 days} 1862 Adventure} {{Sheldon, Sydney} {The other side of midnight} 1967 Mystery} {{Mc Cullough, Colleen} Thornbirds 1967 Saga} } set res [editRecord Edit: [lindex $db 0] [lindex $db 3]] #-- If not canceled, "commit" the changes to the database if [llength $res] {lset db 3 $res} #-- show the current state of the data, to verify changes were applied puts [join $db \n] exit
RS 2006-07-19 Weeks later, I extended the proc above to also allow non-editable labels and multi-line text fields, which are distinguished by suffix (label=, text+):
proc editRecord {title headers fields} { set oldfocus [focus] set w [toplevel .[clock clicks]] wm resizable $w 1 0 wm title $w $title set n 0 foreach h $headers f $fields { if ![regexp {(.+)([=+])} $h -> hdr type] {set hdr $h; set type ""} label $w.h$n -text $hdr -anchor ne switch -- $type { = {label $w.e$n -width [string length $f] -text $f -anchor w -bg white} + {[text $w.e$n -width 20 -height 6] insert end $f} default {[entry $w.e$n -width [string length $f]] insert end $f} } grid $w.h$n $w.e$n -sticky news incr n } button $w.ok -text OK -width 5 -command [list set $w 1] button $w.cancel -text Cancel -command [list set $w 0] grid $w.ok $w.cancel -pady 5 grid columnconfigure $w 1 -weight 1 vwait ::$w if [set ::$w] { #-- collect the current entry contents set n 0 foreach h $headers f $fields { regexp {(.+)([=+]?)} $h -> hdr type switch -- $type { "" {lappend res [$w.e$n get]} = {lappend res [$w.e$n cget -text]} + {lappend res [$w.e$n get 1.0 end]} } incr n } } else {set res {}} destroy $w unset ::$w ;#-- clean up the vwait variable focus $oldfocus return $res } #-- quick test: editRecord Test {foo= bar grill+} {one two three}