Hi guys,
I have a product lookup screen - the user enters some characters in a SLE and the browser is filtered to show the results in realtime.
The user can type A...B...C... backspace... backspace...C...B... (8 keypresses to process)
I want to give the user the opportunity to type a few keys before setting the scope/filter so if they type fast enough, EditChange only sees ACB as the filter string.
I want the SLE to wait until the user has stopped typing before invoking the Edit Change and subsequent browser activity.
The SLE inherits from Willies' RightSLE -
This was discussed in the forums around 2004~8 on and off, but I can't find the discussions.
Thank you. BR Jonathan.
Delay EditChange while the user is still typing into SLE (search string)
Delay EditChange while the user is still typing into SLE (search string)
Jonathon
It is a long time since I looked closely at VO, so cannot give you code.
But, I suggest what you are trying to do would be better achieved by NOT trying to trigger a new filter for every keypress.
Instead, only trigger a new filter when the user has typed in an acceptable string. This means adding some conditional logic to your EditChange Event.
See if you could perhaps initialise a string (field) when focus changes to your SLE. (EditFocusChange if I remember correctly), allowing each keypress to build up the string.
Doing it your way would be quite arbitrary - the user could easily stop halfway through typing and go for a cup of tea.
Terry
It is a long time since I looked closely at VO, so cannot give you code.
But, I suggest what you are trying to do would be better achieved by NOT trying to trigger a new filter for every keypress.
Instead, only trigger a new filter when the user has typed in an acceptable string. This means adding some conditional logic to your EditChange Event.
See if you could perhaps initialise a string (field) when focus changes to your SLE. (EditFocusChange if I remember correctly), allowing each keypress to build up the string.
Doing it your way would be quite arbitrary - the user could easily stop halfway through typing and go for a cup of tea.
Terry
Delay EditChange while the user is still typing into SLE (search string)
Hello Jonathan,
We have an auto complete for an e-mail address, with a character typed the first e-mail address matching this is displayed with all characters except the first one selected. That means when the user types the 2nd character overwriting the selected text, it will display the first e-mail address matching the first 2 typed characters, with character 3 and above selected, and so on.
I would say that moving through a bBrowser can be accomplished too. But we do not use RightSLE. If you want I can mail you the code.
If you want the user to complete a more meaningful keyword, as Terry suggests, you may prefer to use a key for that. In recent W10 updates, searching in the File Explorer starts when you press the white arrow in the blue background, which appears after 1 character was typed. I personally prefer that to the earlier Explorers, starting to fill with every keystroke, while I normally always want the opposite of what Microsoft think is good for us
Dick
We have an auto complete for an e-mail address, with a character typed the first e-mail address matching this is displayed with all characters except the first one selected. That means when the user types the 2nd character overwriting the selected text, it will display the first e-mail address matching the first 2 typed characters, with character 3 and above selected, and so on.
I would say that moving through a bBrowser can be accomplished too. But we do not use RightSLE. If you want I can mail you the code.
If you want the user to complete a more meaningful keyword, as Terry suggests, you may prefer to use a key for that. In recent W10 updates, searching in the File Explorer starts when you press the white arrow in the blue background, which appears after 1 character was typed. I personally prefer that to the earlier Explorers, starting to fill with every keystroke, while I normally always want the opposite of what Microsoft think is good for us
Dick
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Delay EditChange while the user is still typing into SLE (search string)
Hi Jonathan,
do you really need a filter ? Is there no index available ? if so, i would set a (fast) scope each time a char is added to the sle. If you really need a complex filter, i would add next to the sle e.g. a [search] pushbutton where such a filter is evaluated.
regards
Karl-Heinz
do you really need a filter ? Is there no index available ? if so, i would set a (fast) scope each time a char is added to the sle. If you really need a complex filter, i would add next to the sle e.g. a [search] pushbutton where such a filter is evaluated.
regards
Karl-Heinz
Delay EditChange while the user is still typing into SLE (search string)
Thanks for the ideas guys,
I want to wait for 300~400ms after the last keypress in the SLE before starting the setfilter/scope setting.
It is a product lookup screen - the user can type A...B...C... backspace... backspace...C...B... (8 keypresses to process)
I want to give the user the opportunity to type a few keys before setting the scope/filter so if they type fast enough, the EditChange only sees ACB as the filter string.
This search function has been working ok for 15+ years, and is usually really fast, but it starts to lag after a few searches... just trying to tidy up some loose ends to "sign off" the VO version of my app before starting the move to X# (again!)
I want to wait for 300~400ms after the last keypress in the SLE before starting the setfilter/scope setting.
It is a product lookup screen - the user can type A...B...C... backspace... backspace...C...B... (8 keypresses to process)
I want to give the user the opportunity to type a few keys before setting the scope/filter so if they type fast enough, the EditChange only sees ACB as the filter string.
This search function has been working ok for 15+ years, and is usually really fast, but it starts to lag after a few searches... just trying to tidy up some loose ends to "sign off" the VO version of my app before starting the move to X# (again!)
Delay EditChange while the user is still typing into SLE (search string)
Jonathon
Thanks for clarrification. However, you cannot "slow things down" or "speed them up" in the manner you suggest. Within the context of a Control that is simply impossible.
Instead you must think of a different strategy:
Eg:
Firstly subscribe to the MouseDown and MouseUp events which will tell you when the user presses and releases a Key.
Then:
Initialise some buffer // Say a (field) string when focus changes to your SLE (EditFocusChange?)
Read User Input // from KeyDown event
Adjust the buffer according to pressed key // Include processing of backspaces etc so buffer records user intent
Check buffer holds "acceptable string" // Do this on the KeyUp event
Finally please remember my first sentence; whatever you code, however complex it gets, it is for the purpose of controlling underlying electronics. This will stand you in good stead for your journey into .Net
Terry
Thanks for clarrification. However, you cannot "slow things down" or "speed them up" in the manner you suggest. Within the context of a Control that is simply impossible.
Instead you must think of a different strategy:
Eg:
Firstly subscribe to the MouseDown and MouseUp events which will tell you when the user presses and releases a Key.
Then:
Initialise some buffer // Say a (field) string when focus changes to your SLE (EditFocusChange?)
Read User Input // from KeyDown event
Adjust the buffer according to pressed key // Include processing of backspaces etc so buffer records user intent
Check buffer holds "acceptable string" // Do this on the KeyUp event
Finally please remember my first sentence; whatever you code, however complex it gets, it is for the purpose of controlling underlying electronics. This will stand you in good stead for your journey into .Net
Terry
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Delay EditChange while the user is still typing into SLE (search string)
Hi Jonathan,
i played with a timer, and that' s the result :woohoo:
Additionally you need a OnTimer() owner method.
regards
Karl-Heinz
i played with a timer, and that' s the result :woohoo:
Code: Select all
CLASS sleInputTimer INHERIT SingleLineEdit
PROTECT _lTimerActive AS LOGIC
PROTECT _nInterval := 400 AS DWORD
METHOD Destroy() CLASS sleInputTimer
SELF:StopTimer()
SUPER:Destroy()
RETURN NIL
METHOD Dispatch ( oEv ) CLASS sleInputTimer
LOCAL oEvent := oEv AS Event
DO CASE
CASE oEvent:message == WM_KEYUP
SELF:StartTimer()
CASE oEvent:message == WM_KEYDOWN
SELF:StopTimer()
CASE oEvent:message == WM_KILLFOCUS
SELF:StopTimer()
CASE oEvent:message == WM_TIMER
IF IsMethod ( SELF:Owner , #OnTimer )
Send ( SELF:Owner , #OnTimer , SELF:NameSym )
SELF:StopTimer()
ENDIF
ENDCASE
RETURN SUPER:Dispatch ( oEvent )
METHOD SetTimerInterval ( n ) CLASS sleInputTimer
_nInterval := n
RETURN SELF
METHOD StartTimer() CLASS sleInputTimer
IF ! _lTimerActive
IF SetTimer(SELF:Handle(), 222 , _nInterval , NULL_PTR) == 222
_lTimerActive := TRUE
ENDIF
ENDIF
RETURN _lTimerActive
METHOD StopTimer() CLASS sleInputTimer
IF _lTimerActive
IF KillTimer ( SELF:Handle() , 222 )
_lTimerActive := FALSE
ENDIF
ENDIF
RETURN ! _lTimerActive
Code: Select all
METHOD OnTimer ( symControl ) CLASS <yourWindow>
LOCAL STATIC cLast AS STRING
LOCAL cCurrent AS STRING
?
? "OnTimer() triggered"
IF symControl == #<YourSleName>
cCurrent := RTrim ( oDCSleSeek:textvalue )
IF cCurrent != cLast
? "changed value: " , cCurrent
cLast := cCurrent
ENDIF
ENDIF
RETURN NIL
Karl-Heinz
Delay EditChange while the user is still typing into SLE (search string)
Karl-Heinz,
Good solution. One recommendation:
Move the check for the Ontime method to the constructor and add a field:
And in the constructor
And then check for field.
Explanation:
IsMethod() is a relatively expensive method (it needs to retrieve metadata). There is no need to do that more than once per control.
Robert
Good solution. One recommendation:
Move the check for the Ontime method to the constructor and add a field:
Code: Select all
PROTECTED lOwnerHasTimer as LOGIC
Code: Select all
SELF:lOwnerHasTimer := IsMethod ( SELF:Owner , #OnTimer )
Code: Select all
IF SELF:lOwnerHasTimer
IsMethod() is a relatively expensive method (it needs to retrieve metadata). There is no need to do that more than once per control.
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
Delay EditChange while the user is still typing into SLE (search string)
EDIT regarding my remark below):
-----------
I realized after posting this that this is necessary for how we apply it (autocomplete e-mail addresses) but you can of course just read the current content of the control, when the timer calls your "time out" method
-----------
With the timer solution you would need one class variable which keeps track of what has been typed so far. Then it should stop the previous timer, if any, and start a new one.
If a timer exceeds your 0,4 seconds it starts doing your filter job (and stops itself again).
And make sure that you adapt the typed string when a user deletes something, with code like this in the EditChange:
dwLastKey := oControl:LastKey // saved by Dispatch() of the control
DO CASE
CASE dwLastKey == KEYBACKSPACE
CASE dwLastKey == KEYDELETE
CASE dwLastKey == KEYENTER
ENDCASE
Dick
-----------
I realized after posting this that this is necessary for how we apply it (autocomplete e-mail addresses) but you can of course just read the current content of the control, when the timer calls your "time out" method
-----------
With the timer solution you would need one class variable which keeps track of what has been typed so far. Then it should stop the previous timer, if any, and start a new one.
If a timer exceeds your 0,4 seconds it starts doing your filter job (and stops itself again).
And make sure that you adapt the typed string when a user deletes something, with code like this in the EditChange:
dwLastKey := oControl:LastKey // saved by Dispatch() of the control
DO CASE
CASE dwLastKey == KEYBACKSPACE
CASE dwLastKey == KEYDELETE
CASE dwLastKey == KEYENTER
ENDCASE
Dick
Delay EditChange while the user is still typing into SLE (search string)
Thank you Karl-Heinz! This is exactly the thing I had in my dusty memory - maybe it was as long ago as 2001 I recall you posting this in the comp.lang.clipper.VO group!
You've made my day.
You've made my day.