fbpx
Welcome, Guest
Username: Password: Remember me
Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET
  • Page:
  • 1

TOPIC:

Delay EditChange while the user is still typing into SLE (search string) 29 Apr 2021 09:59 #18235

  • jonhn's Avatar

  • jonhn

  • Topic Author


  • Posts: 27
  • 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.

    Please Log in or Create an account to join the conversation.

    Last edit: by jonhn. Reason: Clarifying my question slightly

    Delay EditChange while the user is still typing into SLE (search string) 29 Apr 2021 16:21 #18238

  • Terry's Avatar

  • Terry


  • Posts: 228
  • 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

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 29 Apr 2021 17:10 #18241

  • ic2's Avatar

  • ic2


  • Posts: 935
  • 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

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 29 Apr 2021 19:56 #18249

  • Karl-Heinz's Avatar

  • Karl-Heinz


  • Posts: 642
  • 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

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 29 Apr 2021 21:04 #18251

  • jonhn's Avatar

  • jonhn

  • Topic Author


  • Posts: 27
  • 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!)

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 02 May 2021 10:35 #18261

  • Terry's Avatar

  • Terry


  • Posts: 228
  • 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

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 03 May 2021 15:05 #18266

  • Karl-Heinz's Avatar

  • Karl-Heinz


  • Posts: 642
  • Hi Jonathan,

    i played with a timer, and that' s the result :woohoo:

    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 
    	

    Additionally you need a OnTimer() owner method.
    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  
    

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 03 May 2021 15:56 #18268

  • robert's Avatar

  • robert


  • Posts: 2174
  • Karl-Heinz,
    Good solution. One recommendation:
    Move the check for the Ontime method to the constructor and add a field:
    PROTECTED lOwnerHasTimer as LOGIC

    And in the constructor
    SELF:lOwnerHasTimer := IsMethod ( SELF:Owner , #OnTimer )

    And then check for field.
    IF SELF:lOwnerHasTimer

    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
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 03 May 2021 17:37 #18274

  • ic2's Avatar

  • ic2


  • Posts: 935
  • 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

    Please Log in or Create an account to join the conversation.

    Last edit: by ic2.

    Delay EditChange while the user is still typing into SLE (search string) 03 May 2021 21:48 #18283

  • jonhn's Avatar

  • jonhn

  • Topic Author


  • Posts: 27
  • 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.

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 03 May 2021 21:50 #18284

  • jonhn's Avatar

  • jonhn

  • Topic Author


  • Posts: 27
  • Thanks Robert, and Dick (and the others!) for the additional suggestions.

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 04 May 2021 00:37 #18288

  • Chris's Avatar

  • Chris


  • Posts: 2495
  • jonhn wrote: maybe it was as long ago as 2001 I recall you posting this in the comp.lang.clipper.VO group!


    Yeah, Karl-Heinz has been providing such solutions in the newsgroups/forums since more than 20 years ago! I remember I was so impressed about how he seemed to know absolutely everything in the Windows API and this triggered me to read tons and tons of help files so I could also be able to provide solutions like his! It payed off :)
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 04 May 2021 07:26 #18290

  • Karl-Heinz's Avatar

  • Karl-Heinz


  • Posts: 642
  • robert wrote:
    And in the constructor

    SELF:lOwnerHasTimer := IsMethod ( SELF:Owner , #OnTimer )

    And then check for field.
    IF SELF:lOwnerHasTimer

    Robert


    that's a very good idea !

    thanks
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Delay EditChange while the user is still typing into SLE (search string) 04 May 2021 07:38 #18291

  • Karl-Heinz's Avatar

  • Karl-Heinz


  • Posts: 642
  • jonhn wrote: 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.


    nope.

    You can be assured that i wrote the code yesterday and not 20 years ago ;-)

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Last edit: by Karl-Heinz.

    Delay EditChange while the user is still typing into SLE (search string) 04 May 2021 13:40 #18298

  • g.bunzel@domonet.de's Avatar



  • Posts: 45
  • ...and maybe it's better, to stop the timer first and then SEND(..) the notification to the owner. To not have more notifications - if the SEND-Method needs more time to be finished...

    CASE oEvent:message == WM_TIMER

    IF IsMethod ( SELF:Owner , #OnTimer )

    SELF:StopTimer()

    Send ( SELF:Owner , #OnTimer , SELF:NameSym )

    ENDIF

    ENDCASE

    regards
    Gerhard

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1