AutoFill in Text Box
Moderator: Rathinagiri
- esgici
- Posts: 4543
- Joined: Wed Jul 30, 2008 9:17 pm
- DBs Used: DBF
- Location: iskenderun / Turkiye
- Contact:
AutoFill in Text Box
Hi all,
I'm experimenting AutoFill feature in text box.
Some friends told about it and some commercial products support it with some high promotions.
After seeing Rathinagiri's wonderful work Combined Search box, the AutoFill concept seems not very complicated, at least it will be easier than CSBox, I thought.
So, first implementation is attached.
It is very primitive stage and needs some fine tunes. fe the two sub functions has repetitive lines and may be shortened.
Also navigation by UP and DOWN keys may be optimized.
Please test and give your comments.
Regards
--
Esgici
I'm experimenting AutoFill feature in text box.
Some friends told about it and some commercial products support it with some high promotions.
After seeing Rathinagiri's wonderful work Combined Search box, the AutoFill concept seems not very complicated, at least it will be easier than CSBox, I thought.
So, first implementation is attached.
It is very primitive stage and needs some fine tunes. fe the two sub functions has repetitive lines and may be shortened.
Also navigation by UP and DOWN keys may be optimized.
Please test and give your comments.
Regards
--
Esgici
- Attachments
-
- AutoFill.zip
- AutoFill in Text Box experimenting
- (2.18 KiB) Downloaded 711 times
Viva INTERNATIONAL HMG
- Rathinagiri
- Posts: 5471
- Joined: Tue Jul 29, 2008 6:30 pm
- DBs Used: MariaDB, SQLite, SQLCipher and MySQL
- Location: Sivakasi, India
- Contact:
Re: AutoFill in Text Box
Just another nice utility Esgici.
I am very much interested to use it immediately in my applications.
Some suggestions:
1. When we use backspace, the selection doesn't change. For example, if we press i, Iceland comes. When we press backspace, it becomes 'celand'
2. As you have rightly said, up/down keys should be optimized. We can use Esc key also to cancel.
Eagerly waiting for the next version.
I had modified a little, to call only with the array parameter. ie., on change autofill(acountries)
I am very much interested to use it immediately in my applications.
Some suggestions:
1. When we use backspace, the selection doesn't change. For example, if we press i, Iceland comes. When we press backspace, it becomes 'celand'
2. As you have rightly said, up/down keys should be optimized. We can use Esc key also to cancel.
Eagerly waiting for the next version.
I had modified a little, to call only with the array parameter. ie., on change autofill(acountries)
Code: Select all
/*
AutoFill in Text Box try
*/
#include "minigui.ch"
PROC Main()
aCountries := HB_ATOKENS( MEMOREAD( "Countries.lst" ), CRLF )
ASORT( aCountries ) // This Array MUST be sorted
DEFINE WINDOW frmAFTest ;
AT 0,0 ;
WIDTH 550 ;
HEIGHT 300 ;
TITLE 'AutoFill in Text Box try' ;
MAIN
ON KEY UP ACTION AFNavigate( 1, "frmAFTest", "txbCountry", aCountries )
ON KEY DOWN ACTION AFNavigate( 2, "frmAFTest", "txbCountry", aCountries )
ON KEY ESCAPE ACTION frmAFTest.Release
DEFINE LABEL lblCountry
ROW 50
COL 50
VALUE "Country :"
RIGHTALIGN .T.
AUTOSIZE .T.
END LABEL // lblCountry
DEFINE TEXTBOX txbCountry
ROW 48
COL 110
ONCHANGE AutoFill(aCountries )
END TEXTBOX // txbCountry
END WINDOW // frmAFTest
frmAFTest.Center
frmAFTest.Activate
RETU // Main()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROC AutoFill( ; // Setting CSBox values
aList ) // Items list
LOCAL cCurval := '' ,;
n1Result := 0,;
cFrmName := thiswindow.name,;
cTxBName := this.name,;
nCarePos := this.caretpos
cCurval := LEFT( GetProperty( cFrmName, cTxBName, "Value" ), nCarePos )
IF !EMPTY( cCurval )
n1Result := ASCAN( aList, { | c1 | UPPER( LEFT( c1, LEN( cCurval ) ) ) == UPPER( cCurval )} )
IF n1Result > 0
cCurval := aList[ n1Result ]
ENDIF n1Result > 0
SetProperty( cFrmName, cTxBName, "Value", cCurval )
SetProperty( cFrmName, cTxBName, "CaretPos", nCarePos )
ENDIF !EMPTY( cCurval )
RETU // SetCSBoxVal()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROC AFNavigate( ; // Navigation by UP/DOWN keys in AutoFill Text Box
nDirect ,; // 1 : Up, 2: Down
cFrmName,;
cTxBName,;
aList ) // Items list
LOCAL nCarePos := GetProperty( cFrmName, cTxBName, "CaretPos" ),;
n1Result := 0
LOCAL cCurval := LEFT( GetProperty( cFrmName, cTxBName, "Value" ), nCarePos )
IF !EMPTY( cCurval )
n1Result := ASCAN( aList, { | c1 | UPPER( LEFT( c1, LEN( cCurval ) ) ) == UPPER( cCurval )} )
IF n1Result > 0
IF nDirect < 2
n1Result -= IF( n1Result > 1, 1, 0 )
ELSE
n1Result += IF( n1Result < LEN( aList ), 1, 0 )
ENDIF
cCurval := aList[ n1Result ]
ENDIF n1Result > 0
SetProperty( cFrmName, cTxBName, "Value", cCurval )
SetProperty( cFrmName, cTxBName, "CaretPos", nCarePos )
ENDIF !EMPTY( cCurval )
RETU // AFNavigate()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
South or North HMG is worth.
...the possibilities are endless.
- Rathinagiri
- Posts: 5471
- Joined: Tue Jul 29, 2008 6:30 pm
- DBs Used: MariaDB, SQLite, SQLCipher and MySQL
- Location: Sivakasi, India
- Contact:
Re: AutoFill in Text Box
Hi Esgici,
Kindly test this code.
I had altered for up/down key problems with other controls and also the backspace problem.
Kindly test this code.
I had altered for up/down key problems with other controls and also the backspace problem.
Code: Select all
/*
AutoFill in Text Box try
*/
#include "minigui.ch"
PROC Main()
aCountries := HB_ATOKENS( MEMOREAD( "Countries.lst" ), CRLF )
ASORT( aCountries ) // This Array MUST be sorted
DEFINE WINDOW frmAFTest ;
AT 0,0 ;
WIDTH 550 ;
HEIGHT 300 ;
TITLE 'AutoFill in Text Box try' ;
MAIN
ON KEY ESCAPE ACTION frmAFTest.Release
DEFINE LABEL lblCountry
ROW 50
COL 50
VALUE "Country :"
RIGHTALIGN .T.
AUTOSIZE .T.
END LABEL // lblCountry
DEFINE TEXTBOX txbCountry
ROW 48
COL 110
ongotfocus autofill_init(acountries)
ONCHANGE AutoFill(aCountries )
onlostfocus autofill_close()
END TEXTBOX // txbCountry
define listbox list1
row 80
col 110
width 200
items {"Item 1","Item 2","Item 3","Item 4","Item 5","Item 6"}
value 1
end listbox
END WINDOW // frmAFTest
frmAFTest.Center
frmAFTest.Activate
RETU // Main()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROC AutoFill( ; // Setting CSBox values
aList ) // Items list
LOCAL cCurval := '' ,;
n1Result := 0,;
cFrmName := thiswindow.name,;
cTxBName := this.name,;
nCarePos := this.caretpos
cCurval := LEFT( GetProperty( cFrmName, cTxBName, "Value" ), nCarePos )
IF !EMPTY( cCurval )
n1Result := ASCAN( aList, { | c1 | UPPER( LEFT( c1, LEN( cCurval ) ) ) == UPPER( cCurval )} )
IF n1Result > 0
cCurval := aList[ n1Result ]
ENDIF n1Result > 0
SetProperty( cFrmName, cTxBName, "Value", cCurval )
SetProperty( cFrmName, cTxBName, "CaretPos", nCarePos )
ENDIF !EMPTY( cCurval )
if ncarepos == 0 .and. len(alltrim(GetProperty( cFrmName, cTxBName, "Value" ))) > 0
if ascan(alist,{ | c1 | UPPER( c1 ) == UPPER( GetProperty( cFrmName, cTxBName, "Value" ) )}) == 0
SetProperty( cFrmName, cTxBName, "Value", '' )
endif
endif
RETU // SetCSBoxVal()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROC AFNavigate( ; // Navigation by UP/DOWN keys in AutoFill Text Box
nDirect ,; // 1 : Up, 2: Down
cFrmName,;
cTxBName,;
aList ) // Items list
LOCAL nCarePos := GetProperty( cFrmName, cTxBName, "CaretPos" ),;
n1Result := 0
LOCAL cCurval := LEFT( GetProperty( cFrmName, cTxBName, "Value" ), nCarePos )
IF !EMPTY( cCurval )
n1Result := ASCAN( aList, { | c1 | UPPER( LEFT( c1, LEN( cCurval ) ) ) == UPPER( cCurval )} )
IF n1Result > 0
IF nDirect < 2
n1Result -= IF( n1Result > 1, 1, 0 )
ELSE
n1Result += IF( n1Result < LEN( aList ), 1, 0 )
ENDIF
cCurval := aList[ n1Result ]
ENDIF n1Result > 0
SetProperty( cFrmName, cTxBName, "Value", cCurval )
SetProperty( cFrmName, cTxBName, "CaretPos", nCarePos )
ENDIF !EMPTY( cCurval )
RETU // AFNavigate()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
function autofill_init(aitems)
local formname := thiswindow.name
local controlname := this.name
ON KEY UP of &formname ACTION AFNavigate( 1, formname, controlname, aitems )
ON KEY DOWN of &formname ACTION AFNavigate( 2, formname, controlname, aitems )
return nil
function autofill_close
local formname := thiswindow.name
release key UP of &formname
release key DOWN of &formname
return nil
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
South or North HMG is worth.
...the possibilities are endless.
Re: AutoFill in Text Box
Hi Esgici & Rathi,
Thanks a lot. Excellent utility!!!
Only one suggestion:
When typing in the textbox if right side of the cursor position is automatically selected, then it will be better for user (I did the same thing in one of my VFP utilities, as suggested by one of my clients)
With best regards.
Sudip
Thanks a lot. Excellent utility!!!
Only one suggestion:
When typing in the textbox if right side of the cursor position is automatically selected, then it will be better for user (I did the same thing in one of my VFP utilities, as suggested by one of my clients)
With best regards.
Sudip
With best regards,
Sudip
Sudip
- Rathinagiri
- Posts: 5471
- Joined: Tue Jul 29, 2008 6:30 pm
- DBs Used: MariaDB, SQLite, SQLCipher and MySQL
- Location: Sivakasi, India
- Contact:
Re: AutoFill in Text Box
Yes Sudip. It can be done by adding the following line after "SetProperty( cFrmName, cTxBName, "CaretPos", nCarePos )"
Don't worry about calling of this internal low level function.
It has some disadvantage also. I think we can not use caret position and selection simultaneously. Tell me about your opinion
Code: Select all
SendMessage ( GetControlHandle(cTxBname,cFrmName) , 177 , ncarepos , len(cCurval) )
It has some disadvantage also. I think we can not use caret position and selection simultaneously. Tell me about your opinion
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
South or North HMG is worth.
...the possibilities are endless.
Re: AutoFill in Text Box
Hi Rathi,
I inserted the line in 2 places.
It works for "selection".
And regarding "worried" about low level function... ha, ha, ha (Thanks to Roberto, yesterday he patiently explained GetTextWidth() function to this "novice" learner )
With best regards.
Sudip
I inserted the line in 2 places.
It works for "selection".
But there is a problem. I can't use BACK SPACE to delete text, left side of the caret. So, you are right. Yes, we can't use caret position and selection simultaneously.rathinagiri wrote: Don't worry about calling of this internal low level function.
It has some disadvantage also. I think we can not use caret position and selection simultaneously. Tell me about your opinion
And regarding "worried" about low level function... ha, ha, ha (Thanks to Roberto, yesterday he patiently explained GetTextWidth() function to this "novice" learner )
With best regards.
Sudip
With best regards,
Sudip
Sudip
- Rathinagiri
- Posts: 5471
- Joined: Tue Jul 29, 2008 6:30 pm
- DBs Used: MariaDB, SQLite, SQLCipher and MySQL
- Location: Sivakasi, India
- Contact:
Re: AutoFill in Text Box
Hi Sudip,
I think I had solved this backspace problem too.
Have a try about this.
I think I had solved this backspace problem too.
Have a try about this.
Code: Select all
/*
AutoFill in Text Box try
*/
#include "minigui.ch"
PROC Main()
aCountries := HB_ATOKENS( MEMOREAD( "Countries.lst" ), CRLF )
ASORT( aCountries ) // This Array MUST be sorted
DEFINE WINDOW frmAFTest ;
AT 0,0 ;
WIDTH 550 ;
HEIGHT 300 ;
TITLE 'AutoFill in Text Box try' ;
MAIN
ON KEY ESCAPE ACTION frmAFTest.Release
DEFINE LABEL lblCountry
ROW 50
COL 50
VALUE "Country :"
RIGHTALIGN .T.
AUTOSIZE .T.
END LABEL // lblCountry
DEFINE TEXTBOX txbCountry
ROW 48
COL 110
ongotfocus autofill_init(acountries)
ONCHANGE AutoFill(aCountries )
onlostfocus autofill_close()
END TEXTBOX // txbCountry
define listbox list1
row 80
col 110
width 200
items {"Item 1","Item 2","Item 3","Item 4","Item 5","Item 6"}
value 1
end listbox
END WINDOW // frmAFTest
frmAFTest.Center
frmAFTest.Activate
RETU // Main()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROC AutoFill( ; // Setting CSBox values
aList) //Items list
LOCAL cCurval := '' ,;
n1Result := 0,;
cFrmName := thiswindow.name,;
cTxBName := this.name,;
nCarePos := this.caretpos
cCurval := LEFT( GetProperty( cFrmName, cTxBName, "Value" ), nCarePos )
IF !EMPTY( cCurval )
n1Result := ASCAN( aList, { | c1 | UPPER( LEFT( c1, LEN( cCurval ) ) ) == UPPER( cCurval )} )
IF n1Result > 0
cCurval := aList[ n1Result ]
ENDIF n1Result > 0
SetProperty( cFrmName, cTxBName, "Value", cCurval )
// SetProperty( cFrmName, cTxBName, "CaretPos", nCarePos )
SendMessage ( GetControlHandle(cTxBname,cFrmName) , 177 , len(cCurval),ncarepos )
ENDIF !EMPTY( cCurval )
if ncarepos == 0 .and. len(alltrim(GetProperty( cFrmName, cTxBName, "Value" ))) > 0
if ascan(alist,{ | c1 | UPPER( c1 ) == UPPER( GetProperty( cFrmName, cTxBName, "Value" ) )}) == 0
SetProperty( cFrmName, cTxBName, "Value", '' )
endif
endif
RETU // SetCSBoxVal()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROC AFNavigate( ; // Navigation by UP/DOWN keys in AutoFill Text Box
nDirect ,; // 1 : Up, 2: Down
cFrmName,;
cTxBName,;
aList ) // Items list
LOCAL nCarePos := GetProperty( cFrmName, cTxBName, "CaretPos" ),;
n1Result := 0
LOCAL cCurval := LEFT( GetProperty( cFrmName, cTxBName, "Value" ), nCarePos )
IF !EMPTY( cCurval )
n1Result := ASCAN( aList, { | c1 | UPPER( LEFT( c1, LEN( cCurval ) ) ) == UPPER( cCurval )} )
IF n1Result > 0
IF nDirect < 2
n1Result -= IF( n1Result > 1, 1, 0 )
ELSE
n1Result += IF( n1Result < LEN( aList ), 1, 0 )
ENDIF
cCurval := aList[ n1Result ]
ENDIF n1Result > 0
SetProperty( cFrmName, cTxBName, "Value", cCurval )
SetProperty( cFrmName, cTxBName, "CaretPos", nCarePos )
ENDIF !EMPTY( cCurval )
RETU // AFNavigate()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
function autofill_init(aitems)
local formname := thiswindow.name
local controlname := this.name
ON KEY UP of &formname ACTION AFNavigate( 1, formname, controlname, aitems )
ON KEY DOWN of &formname ACTION AFNavigate( 2, formname, controlname, aitems )
ON KEY BACK of &formname ACTION autofilldobackspace(formname,controlname,aitems)
return nil
function autofill_close
local formname := thiswindow.name
release key UP of &formname
release key DOWN of &formname
return nil
function autofilldobackspace(formname,controlname,alist)
local nstart := LoWord ( SendMessage( GetControlHandle(controlname,formname) , 176 , 0 , 0 ) )
local nend := HiWord ( SendMessage( GetControlHandle(controlname,formname) , 176 , 0 , 0 ) )
local ccurvalue := getproperty(formname,controlname,"VALUE")
local n1Result := 0
if nstart > 0
n1Result := ASCAN( aList, { | c1 | UPPER( LEFT( c1, nstart-1 ) ) == UPPER( substr(cCurvalue,1,nstart-1 ))} )
IF n1Result > 0
ccurvalue := aList[ n1Result ]
ENDIF n1Result > 0
setproperty(formname,controlname,"VALUE",ccurvalue)
SendMessage ( GetControlHandle(controlname,formname) , 177 , len(ccurvalue),nstart-1 )
endif
return nil
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
South or North HMG is worth.
...the possibilities are endless.
Re: AutoFill in Text Box
Hi Rathi,
Thanks a lot! It works! You are a genius
Again, I saw an "abnormal" behavior. When pressing back space, it selects left character in stead of deleting it.
Is this behavior Ok or we need some changes?
With best regards.
Sudip
Thanks a lot! It works! You are a genius
Again, I saw an "abnormal" behavior. When pressing back space, it selects left character in stead of deleting it.
Is this behavior Ok or we need some changes?
With best regards.
Sudip
With best regards,
Sudip
Sudip
- Rathinagiri
- Posts: 5471
- Joined: Tue Jul 29, 2008 6:30 pm
- DBs Used: MariaDB, SQLite, SQLCipher and MySQL
- Location: Sivakasi, India
- Contact:
Re: AutoFill in Text Box
That you have to tell.
Now, just try Indo for Indonesia and then press backspace.
Now, just try Indo for Indonesia and then press backspace.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
South or North HMG is worth.
...the possibilities are endless.
Re: AutoFill in Text Box
Yes, I tried it. It is not very easy to tell .... Most probably you are correct, this should be the ideal behavior of CSBox control.rathinagiri wrote:That you have to tell.
Now, just try Indo for Indonesia and then press backspace.
Now, I want to explain what I mean with the help from my old app ...
This is HMG forum, but I want to share some of my old codes written in another software tool to mean what I want to say.
Code: Select all
*************************************
InteractiveChange EVENT FOR txtCustnm CONTROL
local mCustnm
ch = lastkey()
* Ignore if Del, Back Space or Space key pressed
if ch = 7 or ch = 127 or ch = 32
return
endif
mCustnm = left(this.value, this.selstart)
if empty(mCustnm)
return
endif
select cust
set order to custnm
locate for upper(custnm) = upper(mCustnm)
if found()
this.value = Custnm
this.selstart = len(mCustnm)
this.sellength = len(custnm) - len(mCustnm)
endif
***************************************
Valid EVENT FOR txtCustnm CONTROL
local mCustnm
select ord
if eof() or bof()
return
endif
select cust
set order to custnm
set exact on
seek upper(alltrim(this.value))
set exact off
if found()
select ord
replace custid with cust.custid
return
else
select ord
replace custid with ""
endif
mCustnm = left(this.value, this.selstart)
select Custnm, upper(Custnm) ;
from Cust ;
where upper(Custnm) = upper(alltrim(this.value));
order by 2 ;
into cursor curTemp
do form frmFind with "curTemp", 1, 1 to mCustnm
if !empty(mCustnm)
this.value = mCustnm
endif
use in curTemp
select cust
set order to custnm
set exact on
seek upper(alltrim(this.value))
set exact off
if found()
select ord
replace custid with cust.custid
else
select ord
replace custid with ""
endif
Above code is not generic and I never used that code later.
Thank you again for sharing this code. I am very happy with this team work
With best regards.
Sudip
With best regards,
Sudip
Sudip