I'm trying to create a TextField in Jetpack Compose for users to enter their first and last name.
Is there a way to allow ONLY letters and whitespaces ([a-zA-Z\s]) as input? I've tried every single option available, including KeyboardType.Text, KeyboardType.Ascii, KeyboardType.Uri, but they all show numbers!
Am I missing something obvious? Honestly, I'm kind of shocked that Google doesn't offer this option out of the box.
Try this:
val pattern = remember { Regex("[a-zA-z\\s]*") }
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = {
if (it.matches(pattern)) {
text = it
}
}
)
In Android it's not possible to show a keyboard containing only letters (and it's not related to compose). Keyboard apps don't support it either.
There are other kinds of keyboards (like number-only keyboard), but the view of the keyboard is still controlled by the keyboard app.
It's best to filter the given input based on the needed criteria. For example:
onValueChange = {
text = it.letters()
}
private fun String.letters() = filter { it.isLetter() }
Related
Using TextField in Compose, I found that looks like a bug.
When I change the textfield value , focus out and in again,
onValuseChange method is called even there is no change.
this is not What I want, So I write some defending code for this comparing prev value.
But I want to know another nice solution.
here is my code.
onValueChange = { _inputText ->
if(_inputText.text != countState.value){
}
},
TextField is Android Jetpack Compose Material component which (as part of Material suite) is described in https://material.io/components/text-fields/android and whose reference is on page https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary (on should use right-side menu of components to position this fairly large page at the right place). While this documentation is good and it explaids modifier and keyboardOptions (e.g.), it does not provide list of events, e.g., there is no documentation about onValueChange, see the following code which uses very varied events from different structures:
TextField(
value = uiState.scannedAmount.toString(),
onValueChange = { orderViewModel.handleScannedAmountString(it) },
//keyboardActions = KeyboardActions(onDone = { orderViewModel.handleScannedAmountDone() }),
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
modifier = Modifier.focusRequester(focusRequester)
.onKeyEvent { if (it.nativeKeyEvent.keyCode == KeyEvent.KEYCODE_ENTER){
orderItemViewModel.handleScannedAmountDone()
true
} else {
orderItemViewModel.handleKeyEvent(it.nativeKeyEvent.keyCode.toString())
}
false }
)
So, how can I know that TextField has onValueChange event and what else events it can have?
Specifically - my TextField is trying to listen to and to catch Enter events from the virtual keybord with keyboardType = KeyboardType.Number. The device has Android 8. I can not catch this event using the above code. However this code catched Enter from virtual keyboard that is displayed on emulator. So, I hope that there may be some on... that hears Enter from virtual numeric keyboard on real (Android 8) device. This is motivation, but the original question is just about method to see all the available events.
I have a register View controller. I have text field for the phone number, and another text field for the country number.
i need the country code text field to be on the left and behind it, we should have the phone number.
this is working when the app is on English lang, but when the user changes the language to Arabic, we will get the phone number text field on the left not the country code on the left.
so, i tried to re-arrange the stack view. and it worked, but the size of the stack just changed!
let language = getObjectFromUserDefault(forKey: userDefaultKeys.getLanguageKey) as? String
if KLanguageCode.Arabic.rawValue == language
{
self.mobiStack.removeArrangedSubview(self.mobiStack.arrangedSubviews.first!)
self.mobiStack.removeArrangedSubview(self.mobiStack.arrangedSubviews.first!)
self.mobiStack.setNeedsLayout()
self.mobiStack.layoutIfNeeded()
self.view.layoutIfNeeded()
self.mobiStack.insertSubview(self.txtMobile, at: 0)
self.mobiStack.insertSubview(self.countryCode, at: 1)
self.mobiStack.setNeedsLayout()
self.view.layoutIfNeeded()
}
You can simplify your code like this:
// properly unwrap optional
guard let v = self.mobiStack.arrangedSubviews.last else {
return
}
self.mobiStack.insertArrangedSubview(v, at: 0)
Notes:
when adding arranged subviews, you do NOT need to remove them first.
the above code will swap the two views.
You may want to explicitly set the order (instead of just swapping them)... So, you might use a function like this:
func orderFields(_ rtl: Bool) -> Void {
if rtl {
self.mobiStack.addArrangedSubview(self.txtMobile)
self.mobiStack.addArrangedSubview(self.countryCode)
} else {
self.mobiStack.addArrangedSubview(self.countryCode)
self.mobiStack.addArrangedSubview(self.txtMobile)
}
}
You can call that when you setup your views --
The fields will be ordered as instructed... adding them if they are not already arranged subviews, or re-ordering them if they are.
Also, unless you have something else going on that you have not shown us, there is no need to be calling:
self.mobiStack.setNeedsLayout()
self.view.layoutIfNeeded()
I need to prevent users from entering a caret ("^") into a notes field that is implemented in a UITextView. I found this question: prevent lower case in UITextView, but it's not clear to me when/how often the shouldChangeTextInRange method will be called. Is it called for each keystroke? Is it named this way because it will be called once for a paste? Instead of preventing the entire paste operation, I'd rather strip out the offending carets, which it doesn't look like that method can do.
Our main application (written in C++Builder with VCL components) can filter keystrokes, so that if ^ is pressed, it beeps and the character is not added to the text field. I would like to replicate that behavior here.
Is there any way to do that sanely in Xamarin? I'm doing iOS first, and might be asking about Android later.
Thanks for your help!
Are you using Xamarin.Forms to build your UI? If you're going to be targeting Android, I highly recommend doing so.
If that is the case, then you can easily do this with a custom Entry subclass:
public class FilteredEntry : Entry
{
private string FilterRegex { get; set; }
public FilteredEntry (string filterRegex)
{
// if we received some regex, apply it
if (!String.IsNullOrEmpty (filterRegex)) {
base.TextChanged += EntryTextChanged;
FilterRegex = filterRegex;
}
}
void EntryTextChanged (object sender, TextChangedEventArgs e)
{
string newText = e.NewTextValue;
(sender as Entry).Text = Regex.Replace (newText, FilterRegex, String.Empty);
}
}
Usage:
// The root page of your application
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
new FilteredEntry(#"\^")
}
}
};
A typed ^ will be stripped out of the Entry's Text.
I am working with IOS by using xamarin ,I am new to technology I have one requirement ,That is I don't want to allow any special character in my text box .How can I do this any one help me
thanks
What you can do is use ShouldChangeCharacters delegate.
Using it you can decide weather or not to update the text of the UITextField.
For example lets say you have a UITextField named textField:
textField.ShouldChangeCharacters = (textField, range, replacementString) => {
if (isSpecialCharacter) {
return false;
} else {
return true;
}
};