INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Combo Box

How can I create a SuperCombo? by ChrisRChamberlain
Posted: 8 May 02 (Edited 19 Dec 06)

SuperCombo is a "collection" of three base classes - Textbox, CommandButton and Grid, and a custom class, cusSuperCombo.

The example and code that follows is for the simplest version of SuperCombo - that is a single column grid, the .RecordSource of which is a lookup table. Only one instance of cmdSuperCombo and grdSuperCombo is required for this particular version, regardless of how many textboxes you wish to convert, plus the custom class, cusSuperCombo.

The code can be used as a foundation for far more sophisticated versions.

By adding or removing code in the .GotFocus(), .InteractiveChange(), .KeyPress() and .LostFocus() events of a textbox, any textbox on any form can be converted to or from a SuperCombo.

In the .GotFocus() event of the textbox, cmdSuperCombo and grdSuperCombo are "called" into position - when the textbox loses focus, they disappear.

The grid is accessed by the down arrow or mouse click. Once in the grid, Enter or a mouse click will select the record. Tab will take the user to the next control without replacing the textbox value with the value from the grid. Pressing enter in the textbox replaces the textbox value with the value from the grid.

If the default behaviour doen't suit, it can be easily modified.

In the .InteractiveChange() event of the textbox, the .mFindData() incremental search method of grdCombo is fired. (It's important to note that an indexed lookup table is required for this example)


Why use a SuperCombo?

Comboboxes are notoriously slow and unreliable where serious numbers of records are concerned. They can be visually intrusive - a SuperCombo only appears when the textbox gets focus.

Well constructed SuperCombos utilising incremental searches can greatly speed up the data entry process!

As the list part of the SuperCombo is a grid, it is up to a developer's imagination as to what the grid may contain - checkboxes, images, commandbuttons, memo fields etc.

The largely uncommented code is broken down into 2 sections, cusSuperCombo class code, and a demo form, (you need to substitute your own table), and should be fairly easy to follow and reassemble.


**************************************************
*-- Class:        cussupercombo (c:\supercombo9\supercombo.vcx)
*-- ParentClass:  custom
*-- BaseClass:    custom
*-- Time Stamp:   05/08/02 12:15:10 PM
*

DEFINE CLASS cussupercombo AS custom


    Height = 24
    Width = 24
    nrecno = 0
    Name = "cussupercombo"
    nextrawidth = .F.
    ccmdbuttonname = .F.
    clookupfield = .F.
    clookuptable = .F.
    clookuptablefield = .F.
    clookuptableindex = .F.
    ctextboxname = .F.
    cdisplayfield = .F.


    PROCEDURE mcallgrid
        LPARAMETERS TextBoxName,;
            LookupTableField,;
            LookupTableIndex,;
            ExtraWidth,;
            DisplayField,;
            ColumnsCount

        IF !EMPTY(TextBoxName) AND !EMPTY(LookupTableField)
            WITH THIS
                .cTextBoxName = TextBoxName
                    && Name of textbox

                .cLookupTableField = LookupTableField
&& Table.field
                .cLookupField = SUBS(.cLookupTableField,;
&& field
                    AT([.],.cLookupTableField) + 1,;
                    LEN(.cLookupTableField))
                .cLookupTable         = SUBS(.cLookupTableField    ,;
&& Table
                    1,AT([.],.cLookupTableField) - 1)
                IF !EMPTY(LookupTableIndex)
                    .cLookupTableIndex    = LookupTableIndex
&& Index
                ELSE
                    .cLookupTableIndex    = []
                ENDI

                SET ORDER TO .cLookupField IN .cLookupTable

                IF !EMPTY(ExtraWidth)
&& Extra pixels on width
                    .nExtraWidth    = ExtraWidth
                ELSE
                    .nExtraWidth    = 0
                ENDI
                IF !EMPTY(DisplayField)
                    .cDisplayField    = DisplayField
                ELSE
                    .cDisplayField    = []
                ENDI
                .nRecno                 = RECNO(.cLookupTable)

                
* Get grid positions
                lnLeft     = [THISFORM.]         ;
                    + .cTextBoxName         ;
                    + [.Left]
                lnTop    = [THISFORM.]         ;
                    + .cTextBoxName         ;
                    + [.Top + THISFORM.]     ;
                    + .cTextBoxName         ;
                    + [.Height]
                lnWidth    = [THISFORM.]         ;
                    + .cTextBoxName         ;
                    + [.Width + 16]
                IF !EMPTY(ExtraWidth)
                    lnWidth    = [THISFORM.]     ;
                        + .cTextBoxName     ;
                        + [.Width + 16 + THIS.nExtraWidth]
                ENDI
                * Setup grid
                DO CASE
                CASE ColumnsCount = 1
                    WITH THISFORM.grdSuperCombo
                        .Left                     = EVAL(lnLeft)
                        .Top                    = EVAL(lnTop)
                        .Width                    = EVAL(lnWidth)
                        .Column1.Width            = EVAL(lnWidth)
                        .RecordSource            = THIS.cLookupTable
                        IF !EMPTY(THIS.cDisplayField)
                            .Column1.ControlSource    = THIS.cDisplayField
                        ELSE
                            .Column1.ControlSource    = THIS.cLookupTableField
                        ENDI

                        .Visible = .T.
                    ENDW
                ENDC

                
* Get cmdCOMBO positions
                lnLeft    = [THISFORM.]        ;
                    + .cTextBoxName         ;
                    + [.Left + THISFORM.]    ;
                    + .cTextBoxName         ;
                    + [.Width]
                lnTop    = [THISFORM.]        ;
                    + .cTextBoxName             ;
                    + [.Top  + 2]

                
* Setup cmdCOMBO
                WITH THISFORM.cmdSuperCombo
                    .Left         = EVAL(lnLeft)
                    .Top         = EVAL(lnTop)
                    .Visible     = .T.
                ENDW
            ENDW
        ENDI
    ENDPROC


    PROCEDURE mfinddata
        LPARAMETERS TextBoxValue

        WITH THIS
            lcAlias = ALIAS()
            lcOrder    = ORDER()
            
*
            SELE (.cLookupTable)                        
&& Select lookup table
            IF EMPTY(.cLookupTableIndex)
                SET ORDER TO TAG (.cLookupField)        
&& Select table order
            ELSE
                SET ORDER TO TAG (.cLookupTableIndex)    
&& Select table order
            ENDI
            
*
            lcField = .cLookupTableField                
&& Check out field type
            *

            DO CASE
            CASE VARTYPE(&lcField) = [D]
                SEEK DTOS(TextBoxValue)
            CASE VARTYPE(&lcField) = [C]
                SET NEAR ON
                SEEK UPPE(ALLT(TextBoxValue))
                SET NEAR OFF
            ENDC
            
*
            .nRecNo = RECN(.cLookupTable)
            THISFORM.grdSuperCombo.Refresh()
            
*
            IF !EMPTY(lcAlias)                            
&& Select original table and order
                SELE (lcAlias)
            ENDI
            
*
            IF !EMPTY(lcOrder)
                SET ORDER TO TAG (lcOrder)
            ENDI
        ENDW
    ENDPROC


ENDDEFINE
*
*-- EndDefine: cussupercombo
**************************************************

PUBLIC oform1

SET CLASSLIB TO c:\supercombo9\supercombo.vcx ADDITIVE

oform1=NEWOBJECT("form1")
oform1.Show
RETURN


    **************************************************
*-- Form:         form1 (c:\supercombo9\form3.scx)
*-- ParentClass:  form
*-- BaseClass:    form
*-- Time Stamp:   05/08/02 01:12:11 PM
*

DEFINE CLASS form1 AS form


    Top = 0
    Left = 0
    Height = 251
    Width = 489
    DoCreate = .T.
    Tag = "Grid"
    BorderStyle = 2
    Caption = "Form1"
    WindowState = 0
    Name = "Form1"


    ADD OBJECT command1 AS commandbutton WITH ;
        Top = 204, ;
        Left = 384, ;
        Height = 27, ;
        Width = 84, ;
        Caption = "Close", ;
        TabIndex = 5, ;
        Name = "Command1"


    ADD OBJECT text1 AS textbox WITH ;
        Height = 23, ;
        Left = 12, ;
        TabIndex = 1, ;
        Top = 24, ;
        Width = 100, ;
        Name = "Text1"


    ADD OBJECT text2 AS textbox WITH ;
        Height = 23, ;
        Left = 132, ;
        TabIndex = 2, ;
        Top = 24, ;
        Width = 100, ;
        Name = "Text2"


    ADD OBJECT cussupercombo AS cussupercombo WITH ;
        Top = 84, ;
        Left = 12, ;
        Height = 24, ;
        Width = 24, ;
        Name = "cusSuperCombo"


    ADD OBJECT grdsupercombo AS grid WITH ;
        ColumnCount = 1, ;
        DeleteMark = .F., ;
        GridLines = 0, ;
        HeaderHeight = 0, ;
        Height = 121, ;
        Left = 348, ;
        RecordMark = .F., ;
        ScrollBars = 2, ;
        TabIndex = 6, ;
        TabStop = .F., ;
        Top = 72, ;
        Width = 126, ;
        Name = "grdSuperCombo", ;
        Column1.Width = 131, ;
        Column1.Name = "Column1"


    ADD OBJECT form1.grdsupercombo.column1.header1 AS header WITH ;
        Caption = "Header1", ;
        Name = "Header1"


    ADD OBJECT form1.grdsupercombo.column1.text1 AS textbox WITH ;
        BorderStyle = 0, ;
        Margin = 0, ;
        ForeColor = RGB(0,0,0), ;
        BackColor = RGB(255,255,255), ;
        Name = "Text1"


    ADD OBJECT cmdsupercombo AS commandbutton WITH ;
        Top = 72, ;
        Left = 324, ;
        Height = 20, ;
        Width = 16, ;
        Picture = "smalldnarrow.bmp", ;
        Caption = "", ;
        TabIndex = 7, ;
        TabStop = .F., ;
        Name = "cmdSuperCombo"


    PROCEDURE Load
        SET SAFE OFF
        SET CLASSLIB TO supercombo ADDITIVE
    ENDPROC

    PROCEDURE command1.Click
        THISFORM.Release
    ENDPROC

    PROCEDURE text1.LostFocus
        WITH THISFORM
            DO CASE
            CASE LASTKEY() = 9            ;
                    OR LASTKEY() = 13    ;
                    OR LASTKEY() = 15
                DODEFAULT()
                IF THIS.Name # THISFORM.cusSuperCombo.cTextBoxName
                    .cmdSuperCombo.Left = 1000
                    .grdSuperCombo.Left = 1000
                ENDI
            CASE LASTKEY() = 24    ;
                    AND .cmdSuperCombo.Left # 1000
                .grdSuperCombo.SetFocus()
            ENDC
        ENDW
    ENDPROC


    PROCEDURE text1.GotFocus
        WITH THIS
            IF !USED([make])
                USE ADDBS(GETENV([TEMP]))    ;
                    + [make]                 ;
                    IN 0    && Lookup table
            ENDI
        ENDW
        THISFORM.cusSuperCombo.mCallGrid(THIS.Name,[make.make],[],0,[],1)
        
*!* Change TABLENAME.field parameter to suit
    ENDPROC


    PROCEDURE text1.InteractiveChange
        WITH THISFORM
            IF .grdSuperCombo.Left # 1000
                .cusSuperCombo.mFindData(THIS.Value)
            ENDI
        ENDW
    ENDPROC


    PROCEDURE grdsupercombo.Init
        WITH THIS
            .SetAll([DynamicBackColor]            ,;
                "IIF(RECNO() = THISFORM.cusSuperCombo.nRecNo    ,;
                RGB(0,0,128)                    ,;
                RGB(255,255,255))"                ,;
                [Column])
            .SetAll([DynamicForeColor]            ,;
                "IIF(RECNO() = THISFORM.cusSuperCombo.nRecNo    ,;
                RGB(255,255,255)                ,;
                RGB(0,0,0))"                    ,;
                [Column])
            .Refresh()
        ENDW
    ENDPROC


    PROCEDURE grdsupercombo.AfterRowColChange
        LPARAMETERS nColIndex

        THISFORM.cusSuperCombo.nRecno = RECN()
        THIS.Refresh()
    ENDPROC


    PROCEDURE text1.KeyPress
        LPARAMETERS nKeyCode, nShiftAltCtrl

        WITH THIS
            DO CASE
            CASE nKeyCode =  5    
&& Up arrow
                *
            CASE nKeyCode =  9    
&& Tab
                .Parent.Parent.Visible = .F.
                EVAL([THISFORM.]                             ;
                    + THISFORM.cusSuperCombo.cTextBoxName    ;
                    + [.SetFocus()])
                KEYBOARD [{TAB}]
            CASE nKeyCode = 13    
&& Enter
                .Parent.Parent.Visible = .F.
                lcValue = ([THISFORM.]                         ;
                    + THISFORM.cusSuperCombo.cTextBoxName    ;
                    + [.Value = THIS.Value])
                &lcValue
                EVAL([THISFORM.]                             ;
                    + THISFORM.cusSuperCombo.cTextBoxName    ;
                    + [.SetFocus()])
                KEYBOARD [{TAB}]
            CASE nKeyCode = 24    && Dn arrow
                
*
            ENDC
        ENDW
    ENDPROC


    PROCEDURE text1.Click
        lcValue = ([THISFORM.]                         ;
            + THISFORM.cusSuperCombo.cTextBoxName    ;
            + [.Value = THIS.Value])
        &lcValue

        EVAL([THISFORM.]                             ;
            + THISFORM.cusSuperCombo.cTextBoxName    ;
            + [.SetFocus()])

        KEYBOARD [{TAB}]

        WITH THISFORM
            .cmdSuperCombo.Left = 1000
            .grdSuperCombo.Left = 1000
        ENDW
    ENDPROC


    PROCEDURE cmdsupercombo.Click
        WITH THISFORM.grdSuperCombo
            IF .Visible     = .T.
                .Visible     = .F.
            ELSE
                .Visible     = .T.
            ENDI
        ENDW
    ENDPROC


ENDDEFINE

*
*-- EndDefine: form1
**************************************************

FAQ184-2483 - answering getting answered.
Chris pc2
PDFcommander.com
PDFcommander.co.uk

Back to Microsoft: Visual FoxPro FAQ Index
Back to Microsoft: Visual FoxPro Forum

My Archive

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close