How To Prevent Focus on a Disabled Edittext Box

Mahares

Expert
Licensed User
Longtime User
I have 2 columns of edittext views, one column has all enabled boxes properties, the second to the right of it has all disabled edittext views. When the keyboard cursor is moved using 'next' from one box to the other, I do not want focus on any disabled boxes, but the disabled views get focus anyway. How do I skip focus on the disabled edittext views. I wish there was something like a TabStop property in B4A. Any workaround?
Thank you
 

Mahares

Expert
Licensed User
Longtime User
I use the IME library in this project. It does not have a feature like you are talking about from I can see. If it does I am not aware. Can you share some code sample.
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
B4X:
IME.AddHandleActionEvent(usernameTxt)
IME.AddHandleActionEvent(passwordTxt)

B4X:
Sub IME_HandleAction As Boolean
   Dim edtTxt As EditText
   
   edtTxt = Sender
   
   If edtTxt = usernameTxt Then
      passwordTxt.RequestFocus
      Return True ' Keep Keyboard Open
   Else
      nextBtn_Click
   End If
End Sub

For your need- Test sender to see what box it would go to then test if it is disabled and jump to next, etc.
 
Last edited:
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Also, on your disabled edit boxes. Is there a reason for using edit boxes? Does the user need to select text to copy/paste somewhere, or could they be labels that focus wouldn't go to and no issue to begin with?

You could also try adding all the enabled boxes to the activity/panel first then the disabled. This may make the flow go to the boxes you want.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
The disabled boxes are previous record data for display and for calculations using the current data. I could have probably used labels, but the app is already built a while back with many boxes. I would have to change the whole project. But if you can do calculations with labels, then it is a good idea for next project.
I would like to implement what you have in the previous code, but I am not sure what you would put in:
IME.AddHandleActionEvent(usernameTxt)
IME.AddHandleActionEvent(passwordTxtThanks

Do you have to have AddhandlActionevent for each of 40 or 50 textboxes
Thanks
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
There would need to be a IME.AddHandleActionEvent(eachEditBoxName) for each Enabled edit box (assuming the others are jumped over they won't need one) to tell it that box needs special processing, but all of the processing goes through one Sub IME_HandleAction. Were the forms/activities created in the designer or in code? If the format for the .bal files are known somewhere you may be able to modify all the disabled boxes and convert to labels (Sounds like something I may end up making in the future if the format is published somewhere). If in code you could try shifting the order they are added like I mentioned above (I'm not seeing a way to change the order in the Designer other than clicking each and shifting with bring to front/send to back). Other than that it will be a pretty manual process either way of adding all the handling functions or modifying the design.
 
Last edited:
Upvote 0

Mahares

Expert
Licensed User
Longtime User
@Roger: All the views were designed in the designer and not by code, unfortunately. I am going to try the code snippet you posted. If I have success with it. If it does not work out, I can start thinking of changing the edittext boxes to labels. I wish there was a quick way in B4A to convert an edittext to labels as it is done in VBA.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
I still need help. I tried to implement Roger's code snippet, but I could not get it to work. I have several editetxtboxes, some are enabled and some are disabled. I want to skip focus on the disabled ones and only go to the enabled boxes. When I click next on the keyboard, the keyboard cursor moves to the disabled and enabled alike . I searched for information in the IME library that could help me with this situation, but found none.
Thanks
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
B4X:
'Activity module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.

End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim IME As IME
   Dim edit1, edit2, edit3 As EditText ' edit1 and edit3 are enabled, edit2 is disabled
End Sub

Sub Activity_Create(FirstTime As Boolean)
   IME.Initialize("IME")
   IME.AddHandleActionEvent(edit1)
   IME.AddHandleActionEvent(edit3)
End Sub

Sub IME_HandleAction As Boolean
   Dim edtTxt As EditText
   
   edtTxt = Sender
   
   If edtTxt = edit1 Then
      edit3.RequestFocus
      Return True
   End If
End Sub
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
@Roger: I did exactly what you had in the latest code except that my boxes use different name. There was no effect at all. If you tested your code and it worked for you, then the problem is on my end. If you did not test it, then you might want to give it a try on your end. I will keep trying as long as you are determined to solve it.
Thanks
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Tried this?

B4X:
Sub EditTextDisabled_FocusChanged (HasFocus As Boolean)
   If HasFocus=True Then EditTextNext.RequestFocus 
End Sub

where editTextDisabled, a disabled text box, and editTextNext, then next txtBox in the tab sequence. Worked for me.
 
Upvote 0

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Just created an app with code from Post #11 and it worked. Not sure why it isn't for you. I did try a few other things too like setting the InputType to 0 (NONE) in the Designer. It aborted the keyboard when it got focused from the previous...you can still longpress the menu button to get the keyboard back though and type. It is odd for Android to even let it type. I've noted other weirdness like it to Erel about passwords not hiding like other apps (fixed with setting InputType to 129 instead of using the built-in password mode). Perhaps there is something similar to that for this.

Your last post sparked something in my brain though. It would be nice if there was a real function called EditTextNext. Closest thing I can think of is making a For loop and using Activity.GetView and .NumberOfViews to find the view you are on then if there is another view after it to focus it (Assuming the order they are in the Activity's list of views is how Android navigates). This would allow all your disabled views to use the same FocusChanged function (Same Event Name in Designer) and jump to the next.
 
Last edited:
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Just created an app with code from Post #11 and it worked. Not sure why it isn't for you. I did try a few other things too like setting the InputType to 0 (NONE) in the Designer. It aborted the keyboard when it got focused from the previous...you can still longpress the menu button to get the keyboard back though and type. It is odd for Android to even let it type. I've noted other weirdness like it to Erel about passwords not hiding like other apps (fixed with setting InputType to 129 instead of using the built-in password mode). Perhaps there is something similar to that for this.

Your last post sparked something in my brain though. It would be nice if there was a real function called EditTextNext. Closest thing I can think of is making a For loop and using Activity.GetView and .NumberOfViews to find the view you are on then if there is another view after it to focus it (Assuming the order they are in the Activity's list of views is how Android navigates). This would allow all your disabled views to use the same FocusChanged function (Same Event Name in Designer) and jump to the next.

You mean something like this?

B4X:
'Activity module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
Type tabStop(nextStop As Int)
End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout ("txtBoxes")
loadTxtBoxes
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub





Sub loadTxtBoxes
For k=0 To 9
   Dim a As Int 
   a=Rnd(0,3)
   If a>0 Then
      Dim txtB As EditText 
      txtB.Initialize ("txtBox")
      Dim en As Boolean 
      If Rnd(0,2)=0 Then en=True Else en=False
      txtB.Enabled =en
      txtB.SingleLine =True
      Activity.Addview (txtB,0,Activity.Height/10*k,Activity.Width /2,Activity.Height/10-5dip)
   Else
      Dim lmb As Label
      lmb.Initialize ("")
      lmb.Text="just a label"
      Activity.Addview (lmb,0,Activity.Height/10*k,Activity.Width /2,Activity.Height/10-5dip)
   End If

Next

For k=0 To Activity.NumberOfViews -1
   Dim loopPoint As Int 
   Try
      Dim temptextBox As EditText 
      Dim nextFound As Boolean 
      nextFound=False
      temptextBox=Activity.GetView (k)
      Dim tempTab As tabStop 
      tempTab.Initialize
      For l=0 To Activity.NumberOfViews -2
         loopPoint=(k+l+1) Mod Activity.NumberOfViews 
         If nextFound=False Then
            Try
               Dim temp2 As EditText 
               temp2=Activity.GetView (loopPoint)
               tempTab.nextStop =loopPoint
               nextFound=True
            Catch
            'not a text box
            End Try
         End If
      Next
      If nextFound=False Then tempTab.nextStop =k
      temptextBox.Tag =tempTab
   Catch
   ' not a text box
   End Try
Next
End Sub

Sub txtBox_FocusChanged(HasFocus As Boolean )
Dim tb As EditText 
tb=Sender
If HasFocus=True AND tb.Enabled =False Then
   Dim tempTab As tabStop
   tempTab.Initialize 
   tempTab=tb.Tag 
   Activity.GetView (tempTab.nextStop).RequestFocus  
End If
End Sub
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Yeah, something like that. A little more code than I expected and harder to follow. I pictured it sort of like a linked list structure. Should have been able to populate the .tag values with next item in one loop/pass. If it works though, that is all that counts.
I've test it, though not very much, it works. But surely, there should be a more ellegant way of doing this, I think it can be done :)
 
Upvote 0

Mansour01

Member
Licensed User
Longtime User
I solved this issue by the following code :

B4X:
Sub txtACEdit1_FocusChanged (HasFocus As Boolean)
Dim ve As ViewExtender  ' ViewExtender Library
ve.initialize("txtInfo", txtInfo) ' initialize txtInfo that should be disabled
        If ve.hasFocus = True Then txtACEdit1.RequestFocus ' if txtInfo has focused then return the focus to txtACEdit1
End Sub
 
Upvote 0
Top