Version 14 of Adding 'history' to BWidget ComboBox widgets.

Updated 2005-08-11 11:57:48

WJG (10th June, 2005) Why doesn't the BWidget ComboBox does have a 'built-in' means of updating the selection list from data validated in its entry box. Perhaps it has and I haven't looked hard enough. Anyway, it was quicker to just cook something up. So here's my offering.

 # -------------------------------------------------------------
 # ComboBox_history.tcl
 # Written by William J Giddings, 2005
 # -------------------------------------------------------------
 # 
 # Purpose:
 # --------
 # To provide history for the BWidget ComboBox. 
 # 
 # Note:
 # -----
 # * This is not achieved by manipulating the BWidet code but by 
 # simply providing a suitable procedure to be called when the 
 # entry subwidget is validated.
 # * New validated entries are placed at the top of the list.
 # * Duplicate entries will not be added.
 #
 # Use:
 # ---------------
 # ComboBox .cmb -values {str1 str2..} -command _h
 #
 # -------------------------------------------------------------

 # -------------------------------------------------------------
 # a simple handler, no args required
 # -------------------------------------------------------------

 proc _h {} {  
    set w [winfo parent [focus]] 
    set a [$w get]
    set b [$w cget -values]
    #check to see if value already there..
    if { [lsearch -exact $b $a] } { $w configure -values "\{$a\} $b"} 
 }

 # -------------------------------------------------------------
 # the ubiquitous demo!
 # -------------------------------------------------------------
 proc demo {} {
    package require BWidget
    pack [ComboBox .cmb -values {{She sells} {sea shells} {by the} {sea shore} } -command _h]
 }

 demo

ramsan You should correct one of the lines in the above code by:

    if { [lsearch -exact $b $a] == -1 } {
        $w configure -values [linsert $b 0 $a]
    }

or, even better (to put the new value at first position):

  if { [set ipos [lsearch -exact $b $a]] != -1 } {
     set b [lreplace $b $ipos $ipos]
  }
  $w configure -values [linsert $b 0 $a]

WJG My original code is simple and clear (KISS). Adding the extra lines adds unecessary complexity. With regard to the 'first position' -try the the demo. The most recently entered item does appear at the top of the drop-down list.

ramsan: Try to enter in your code a sentence with spaces in it. Also, it may or may not be a requirement to avoid duplicate entries in the list.

WJG In general, why would one want to keep the duplications? Thanks for the comment on strings. I've adjusted the code to allow substrings.


See also Enhancing BWidget