Combo control
Combo control
We need to improve the way we find records in a table and select them to fill in a field on a form.
Ideally we are looking for a 'combo' type control with 'Google type' functionality.
i.e. after the user clicks-on (or tabs-into) a field and starts typing, the characters entered are used to look for matches in a table, either:
a) from the beginning of the field.
b) against any part of the field string.
When the user types the first character, a drop down list of matching records should appear under the field.
As more characters are typed, the list of matching records should shrink.
When only one record matches, then this is becomes the field value.
Our solution:
We currently achieve this by displaying a browse below a input field.
The problem:
Using two controls, a DCGET() and DCBROWSE() creates a workable but 'disjointed' solution where the focus can switch between the controls if the user (say) stops typing and clicks on the browse.
Is there an Express++ 'combo' type control, or some sample code that might help us do this more efficiently?
Thx
Michael
Ideally we are looking for a 'combo' type control with 'Google type' functionality.
i.e. after the user clicks-on (or tabs-into) a field and starts typing, the characters entered are used to look for matches in a table, either:
a) from the beginning of the field.
b) against any part of the field string.
When the user types the first character, a drop down list of matching records should appear under the field.
As more characters are typed, the list of matching records should shrink.
When only one record matches, then this is becomes the field value.
Our solution:
We currently achieve this by displaying a browse below a input field.
The problem:
Using two controls, a DCGET() and DCBROWSE() creates a workable but 'disjointed' solution where the focus can switch between the controls if the user (say) stops typing and clicks on the browse.
Is there an Express++ 'combo' type control, or some sample code that might help us do this more efficiently?
Thx
Michael
Re: Combo control
Michael -
The below code is from the "Scoped Dropdown" sample in Sample Group 6 of Xdemo.
The below code is from the "Scoped Dropdown" sample in Sample Group 6 of Xdemo.
Code: Select all
FUNCTION XSample_187()
/* This example demonstrates how to use the KEYBLOCK clause
and COMBO clause @..DCSAY..GET to drop down a list of
valid names and scope the list based on the characters
entered. If names are in a database, use dbSeek() and
DC_SetScope() in place of Ascan(). */
LOCAL GetList[0], GetOptions, cName, aNames, cPerformer, lImmediate
cPerformer := Space(30)
aNames := PerformerNames()
@ 0,0 DCSAY 'Enter Performer Name' GET cPerformer ;
SAYSIZE 0 SAYBOTTOM ;
KEYBLOCK {|a,b,o|DropDownNames(a,b,o,@cPerformer,aNames)} ;
COMBO HEIGHT 10 DATA aNames
lImmediate := DC_GetComboImmediate(.t.)
DCREAD GUI FIT TITLE 'Scoped Drop-Down' MODAL
DC_GetComboImmediate(lImmediate)
RETURN nil
* -----------
STATIC FUNCTION DropDownNames( nKey, mp2, oGet, cPerformer, aNames )
LOCAL nFound, cName, nLen := Len(cPerformer), aPerformers
IF Chr(nKey) < 'A' .OR. Chr(nKey) > 'z'
RETURN nil
ENDIF
oGet:getData()
cName := Alltrim(Upper(cPerformer))
ASize(aNames,0)
aPerformers := PerformerNames()
nFound := AScan( aPerformers, {|c|Alltrim(Upper(c)) = cName} )
IF nFound > 0
DO WHILE nFound <= Len(aPerformers) .AND. Alltrim(Upper(aPerformers[nFound])) = cName
AAdd( aNames, aPerformers[nFound])
nFound++
ENDDO
oGet:comboData := aNames // store scoped array to datasource
PostAppevent(xbeP_Activate,,,oGet:popupButton) // popup scoped dropdown
DC_CompleteEvents()
ENDIF
oGet:comboData := aPerformers // store full array to datasource
IF Empty(aNames)
AAdd(aNames,'')
ENDIF
RETURN nil
The eXpress train is coming - and it has more cars.
Re: Combo control
Thanks Roger, will give it a go.
Michael
Michael
-
- Posts: 605
- Joined: Thu Jan 28, 2010 9:11 pm
- Location: Steven Point, Wisconsin USA
- Contact:
Re: Combo control
I also use the following, to keep control always in the separate input dcget. You can navigate the browse with the cursor or mouse, but focus always returns to the seek box.
Code: Select all
@ .2,1 DCSAY 'Enter Secured Party' GET cSeek ;
SAYRIGHTBOTTOM PICTURE '@!' ; // defines seek key for auto seek
GETOBJECT d_oSeekkey ;
PARENT d_oTabstatic1 ;
SAYSIZE 0 ;
EDITPROTECT {|| .F.} ;
LOSTFOCUS {|| cSeek := space(20), d_oSeekkey:setdata() } ;
KEYBLOCK {|a,b,o| iif(LB_CheckForPlusMinus(a,b,o),NIL, ;
DC_BrowseAutoSeek(a,o,d_oBrowse,,,'', ;
{|a| iif(empty(a),'',LB_RightAdj(a,4,'0',,.T.))}))}
@ 1.3,.4 DCSTATIC TYPE XBPSTATIC_TYPE_RECESSEDBOX OBJECT d_oPagegroup1 ;
SIZE nTPWidth-1.2,nTPHeight-2.9 PARENT d_oTabstatic1 ;
COLOR GRA_CLR_BLACK,m->G_nBGColor
@ .2,.5 DCBROWSE d_oBrowse ALIAS 'TEMPLATE' SIZE nTPWidth-2,nTPHeight-3.4 ;
EVAL {|o| LB_VisualStyle(o,.T.) } ;
HEADLINES 1 ;
PARENT d_oPagegroup1 ;
PRESENTATION DC_BrowPres() ;
FIT ;
CURSORMODE XBPBRW_CURSOR_ROW ;
GROUP 'BROWSE' ;
ID 'OBROWSE' ;
NOHSCROLL ;
GOTFOCUS {|| SetAppFocus(d_oSeekkey)} ;
ITEMMARKED {|| d_oDialog:SetTitle(d_cTitle+' - '+TEMPLATE->sec_name), ;
DC_GetRefresh(GetList,,,,{'TOOLBAR'})} ;
ITEMSELECTED {|| PostAppEvent(xbeP_Keyboard,xbeK_F3,,d_oDialog)}
Re: Combo control
Thanks Cliff
Was going to ask about how to keep focus on the dcget after we have opened the browse.
When we dropped the list in our old control, focus changed so the user could not continue typing into the dcget.
Michael
Was going to ask about how to keep focus on the dcget after we have opened the browse.
When we dropped the list in our old control, focus changed so the user could not continue typing into the dcget.
Michael
Re: Combo control
Cliff
Would you please clarify these externals, are they trapping keys:
Thanks
Michael
Would you please clarify these externals, are they trapping keys:
Code: Select all
LB_CheckForPlusMinus
LB_RightAdj
Michael
Re: Combo control
Cliff
one more thing..
... is the browse part of the same dialogue ... or is it a pop-up?
Michael
one more thing..
... is the browse part of the same dialogue ... or is it a pop-up?
Michael
Re: Combo control
Cliff / Roger
This looks like a good fit for what we are trying to do provided the dcbrowse() appears as a "pop-up".
If the browse element is not a pop-up ... can the code be amended to do so... without changing the way the focus stays with the DCGET()?
I can see another external ... LB_VisualStyle... any more info on this, so we can get this working?
Thanks, again
Michael
This looks like a good fit for what we are trying to do provided the dcbrowse() appears as a "pop-up".
If the browse element is not a pop-up ... can the code be amended to do so... without changing the way the focus stays with the DCGET()?
I can see another external ... LB_VisualStyle... any more info on this, so we can get this working?
Thanks, again
Michael
-
- Posts: 605
- Joined: Thu Jan 28, 2010 9:11 pm
- Location: Steven Point, Wisconsin USA
- Contact:
Re: Combo control
Did you get the information I emailed you.
Cliff
Cliff
Re: Combo control
Cliff
Yes thankyou, I got the attachments when I got back from my trip.
The way you keep the focus on the dcget() seems to be just what we are looking to achieve.
I can see from your screenshot that you have the 'parent' dcget() & 'child' dcbrowse() on the same form.
The difference we see to our needs, is we are looking to have the dcbrowse() appear as a modal "pop-up" object...
... this raises the question of if/how the focus can be returned to the dcget() on the original form.
Michael
Yes thankyou, I got the attachments when I got back from my trip.
The way you keep the focus on the dcget() seems to be just what we are looking to achieve.
I can see from your screenshot that you have the 'parent' dcget() & 'child' dcbrowse() on the same form.
The difference we see to our needs, is we are looking to have the dcbrowse() appear as a modal "pop-up" object...
... this raises the question of if/how the focus can be returned to the dcget() on the original form.
Michael