Combobox dropdown style - search

demont frank
Posts: 167
Joined: Thu Mar 22, 2007 11:24 am

Re: Combobox dropdown style - search

Post by demont frank »

Otto wrote:Hello Frank,

As I can’t get working incremental search in combobox I would like to test your solution with xBrowse.
Would you be so kind to send me following functions:
MAKE2DIM
NM_ALFA
MAKEGETBOX

Thanks in advance
Otto
Ok , it was send

Frank
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Combobox dropdown style - search

Post by Antonio Linares »

Dear Otto,

First, you have to remove CBS_SORT from the RC or the order in the aItems array is not the same as the displayed in the combobox.

Second, besides James suggestion to set oCbx:lIncSearch := .T., you have to set this line:

Code: Select all

   REDEFINE COMBOBOX oCbx VAR cItem ITEMS aItems ;
      ID 110 OF oDlg          ;
      ON CHANGE ( oSayItem:cTitle := oCbx:GetText() ) ;
      VALID ( MsgBeep(), .t. )
 
   oCbx:lIncSearch := .T.
   oCbx:oGet:bKeyChar = { | nKey | oCbx:KeyChar( nKey ) }  // this one!
 
As you are using a CBS_DROPDOWN (that uses a GET) instead of a CBS_DROPDOWNLIST (that does not uses a GET).

With these changes, your example is working fine here :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: Combobox dropdown style - search

Post by Otto »

Antonio,

I changed the code but it does not work.
The changes you suggest make a DROPDOWNLIST behavior out of the DROPDOWN box.

You can’t insert a new text.
I need the dropdown behavior this means you can select an item or you can insert a new one.

Thanks in advance
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Combobox dropdown style - search

Post by Antonio Linares »

Otto,

Ok, I see what you want. Please make this change in Class TComboBox Method KeyChar:

Code: Select all

...
      if Empty( uItem ) 
         if nNewAt == 0 
            nNewAt = AScan( ::aItems, {|x| Upper(x) = Upper( ::cSearchKey ) } )
            // if nNewAt > 0 .and. Len( ::aItems ) <= nNewAt 
            //   uItem = ::aItems[ nNewAt ] 
            // endif 
            uItem = If( nNewAt > 0, ::aItems[ nNewAt ], ::cSearchKey )
         else 
            uItem = ::aItems[ Max( nNewAt, 1) ] 
         endif  
      endif 
      ::Set( If( ValType( Eval( ::bSetGet ) ) == "N", AScan( ::aItems, uItem ), uItem ) ) 
      ::oGet:SetPos( Len( ::cSearchKey ) + 1 )
   endif   
...
 
Please keep this line:
oCbx:oGet:bKeyChar = { | nKey | oCbx:KeyChar( nKey ) }
We may need a new DATA to select this new behavior.

Please download the EXE from here to test it:
http://www.mediafire.com/?sharekey=f67b ... 6e282a0ee8
Type "antonio" and see how it behaves. Then delete char by char :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Combobox dropdown style - search

Post by Antonio Linares »

> We may need a new DATA to select this new behavior.

We can avoid it if we check if oCbx:oGet is != nil
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Combobox dropdown style - search

Post by Antonio Linares »

Otto,

This modified Class TComboBox Method KeyChar() seems to work fine, respecting spaces and evaluating ON CHANGE :-)

Code: Select all

METHOD KeyChar( nKey, nFlags ) CLASS TComboBox 

   local nNewAT := 0, nOldAT := ::nAT, uItem 

   if Len( ::aItems ) == 0 
      return 0 
   endif

   if ::lIncSearch
      do case 
         case nKey = 32   // VK_DELETE do not work! 
              if ::oGet == nil
                 ::cSearchKey = "" 
                 nNewAt = 1 
                 uItem  = ::aItems[ nNewAt ]
              else    
                 ::cSearchKey += " "
              endif   
            
         case nKey = VK_BACK 
              ::cSearchKey = Left( ::cSearchKey, Len( ::cSearchKey ) - 1 ) 
            
         case nKey = 190 
              nKey = 0 
              ::cSearchKey += "." 
            
         otherwise 
              ::cSearchKey += Chr( nKey ) 
      endcase 
    
      if Empty( uItem ) 
         if nNewAt == 0 
            nNewAt = AScan( ::aItems, {|x| x = ::cSearchKey } ) 
            if ::oGet == nil
               uItem = ::aItems[ If( nNewAt > 0, nNewAt, Max( ::nAT, 1 ) ) ] 
            else   
               uItem = If( nNewAt > 0, ::aItems[ nNewAt ], ::cSearchKey )
            endif   
         else 
            uItem = ::aItems[ Max( nNewAt, 1) ] 
         endif  
      endif 
      ::Set( If( ValType( Eval( ::bSetGet ) ) == "N", AScan( ::aItems, uItem ), uItem ) ) 
      if ::oGet != nil
         ::oGet:SetPos( Len( ::cSearchKey ) + 1 )
      endif   
   endif   

   if ::bChange != nil 
      if ::oGet != nil .or. ( nNewAT != nOldAt .and. nNewAt != 0 ) 
         Eval( ::bChange, Self, ::VarGet() ) 
      endif   
   endif 

   if nKey == VK_RETURN 
      return ::oWnd:GoNextCtrl( ::hWnd ) 
   endif 
   
return If( ::lIncSearch, 0, nil )
 
Here you have the EXE to test it:
http://www.mediafire.com/?sharekey=414c ... 0a1ae8665a
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Combobox dropdown style - search

Post by Antonio Linares »

To avoid case sensitive make this change in the proposed Method KeyChar():

Code: Select all

nNewAt = AScan( ::aItems, {|x| Upper( x ) = Upper( ::cSearchKey ) } ) 
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Combobox dropdown style - search

Post by James Bott »

Antonio,

May I suggest also modifying TCombobox so that incremental searching works when the style is DROPDOWN (and lIncSearch=.t.). According to Otto, this is not working.

Regards,
James
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Combobox dropdown style - search

Post by Antonio Linares »

James,

Thats is what we are doing. It only works when lIncSearch is .T. and the style is dropdown.

According to Otto tests, we are close to get it fully functional. Still there are some behaviors to solve.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Combobox dropdown style - search

Post by Antonio Linares »

Otto,

This is a modified Method KeyChar() that provides support for VK_TAB. Here it is working fine.

I appreciate your feedback, thanks :-)

Code: Select all

METHOD KeyChar( nKey, nFlags ) CLASS TComboBox 

   local nNewAT := 0, nOldAT := ::nAT, uItem 

   if Len( ::aItems ) == 0 
      return 0 
   endif

   if ::lIncSearch
      do case 
         case nKey = 32   // VK_DELETE (DO NOT WORK!) 
              if ::oGet == nil
                 ::cSearchKey = "" 
                 nNewAt = 1 
                 uItem  = ::aItems[ nNewAt ]
              else    
                 ::cSearchKey += " "
              endif   
            
         case nKey = VK_BACK 
              ::cSearchKey = Left( ::cSearchKey, Len( ::cSearchKey ) - 1 ) 
            
         case nKey = 190 
              nKey = 0 
              ::cSearchKey += "." 
              
         case ::oGet != nil .and. nKey = VK_TAB
              if ! GetKeyState( VK_SHIFT )
                 ::oWnd:GoNextCtrl( ::hWnd )
              else   
                 ::oWnd:GoPrevCtrl( ::hWnd )
              endif
              return 0   
            
         otherwise 
              ::cSearchKey += Chr( nKey ) 
      endcase 
    
      if Empty( uItem ) 
         if nNewAt == 0 
            nNewAt = AScan( ::aItems, {|x| x = ::cSearchKey } ) 
            if ::oGet == nil
               uItem = ::aItems[ If( nNewAt > 0, nNewAt, Max( ::nAT, 1 ) ) ] 
            else   
               uItem = If( nNewAt > 0, ::aItems[ nNewAt ], ::cSearchKey )
            endif   
         else 
            uItem = ::aItems[ Max( nNewAt, 1) ] 
         endif  
      endif 
      ::Set( If( ValType( Eval( ::bSetGet ) ) == "N", AScan( ::aItems, uItem ), uItem ) ) 
      if ::oGet != nil
         ::oGet:SetPos( Len( ::cSearchKey ) + 1 )
      endif   
   endif   

   if ::bChange != nil 
      if ::oGet != nil .or. ( nNewAT != nOldAt .and. nNewAt != 0 ) 
         Eval( ::bChange, Self, ::VarGet() ) 
      endif   
   endif 

   if nKey == VK_RETURN 
      return ::oWnd:GoNextCtrl( ::hWnd ) 
   endif 
   
return If( ::lIncSearch, 0, nil )
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: Combobox dropdown style - search

Post by Otto »

Hello Antonio,

VK_TAB is working now.
Thanks again,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: Combobox dropdown style - search

Post by Otto »

Hello Antonio,

in your last change of the method you didn't include the change
//nNewAt = AScan( ::aItems, {|x| x = ::cSearchKey } )
nNewAt = AScan( ::aItems, {|x| Upper( x ) = Upper( ::cSearchKey ) } )

Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: Combobox dropdown style - search

Post by Otto »

Antonio,

http://www.atzwanger.info/kartei2/kartei2.htm

Please help me with this problem. I want to edit the field "briefanrede". But the changes go away.
Thanks in advance
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: Combobox dropdown style - search

Post by Otto »

Hello Antonio,

As a workaround for I changed the KeyChar method in TGet.

I inserted a
return Super:KeyChar( nKey, nFlags )
at the beginning of the method.

Now search in combobox is working.
I take the original combobox without the suggested changes. The changes I made only in TGet.

As I don’t be aware what other disadvantages the change has I copied Tget and call from combobox the copy with the changes.

Best regards,
Otto



METHOD KeyChar( nKey, nFlags ) CLASS TGet

local nHi, nLo
local lAccept
local bKeyAction := SetKey( nKey )
local nDefButton

return Super:KeyChar( nKey, nFlags )
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: Combobox dropdown style - search

Post by Otto »

Hello Antonio,

Why do we need a TGet with CBS_Dropdown? Is this only for the TAB order?

If I commend out the following lines searching works but the Tab order is false.

Regards,
Otto

Code: Select all

if lAnd( ::nStyle, CBS_DROPDOWN )
      #ifdef __XPP__
         #undef New
      #endif
      ::oGet := TGet():ReDefine( nil,    ;  // ID not used
                              ::bSetGet, ;  // bSETGET(uVar)
                              Self,      ;  // oDlg
                              ::nHelpID, ;  // Help Context ID
                              cPict,     ;  // Picture
                              nil,       ;  // Valid is handled by the CBx
                              ::nClrText,;
                              ::nClrPane,;
                              ::oFont,   ;  // <oFont>
                              nil,       ;  // <oCursor>
                              cMsg,      ;  // cMsg
                              nil,       ;  // <.update.>
                              nil,       ;  // <{uWhen}>
                              bEChange,  ;  // {|nKey,nFlags,Self| <uEChange>}
                              .F.        )  // <.readonly.> )
      ::oGet:bKeyChar = { | nKey | If( ( nKey == VK_TAB .and. ! GetKeyState( VK_SHIFT ) ) .or. ;
                                         nKey == VK_RETURN,;
                                       ( ::oWnd:GoNextCtrl( ::hWnd ), 0 ),;
                                       If( nKey == VK_TAB .and. GetKeyState( VK_SHIFT ),;
                                       ( ::oWnd:GoPrevCtrl( ::hWnd ), 0 ),) ) }
   endif
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
Post Reply