Read the original article:How to Solve TextInput Input Restriction Abnormality Issues
Context
In HarmonyOS, the $$ two-way binding symbol can synchronize state variables with the internal state of system components. When using the TextInput component for text input, you can perform operations such as limiting input content in the onChange event.
Description
Adding restriction conditions to TextInput component to only allow input of numbers within a certain range. Implementing specific logic in onChange callback, but it doesn't take effect after running. Two issues occur:
- Set input range in callback, but can still input numbers beyond the range
- After adding $$ two-way binding to text, range restriction works but cannot input decimal points, resulting in only integer input
Problem code:
@Entry
@Component
struct TextInputPage {
@State inputValue: string = '';
build() {
Column() {
TextInput({
text: this.inputValue, // Cannot input decimal points after adding two-way binding symbol $$
placeholder: 'Please enter a number between -50 and 150.'
})
.type(InputType.NUMBER_DECIMAL)
.onChange((value: string) => {
// Convert to number for range judgment
let numValue = parseFloat(value) ;
if (numValue <= -50) {
this.inputValue = '-50';
}else if (numValue >= 150) {
this.inputValue = '150';
}else {
this.inputValue = numValue.toString()
}
})
}
}
}
Problem analysis:
- Check whether $$ two-way binding symbol is used when passing values to TextInput component's text parameter
- Trace the source of final displayed numeric values, check if there are operations limiting decimal point input or if decimal points are lost during data conversion
Root cause:
- Not using $$ two-way binding symbol when passing values to TextInput text parameter, causing state variable changes unable to synchronize with TextInput component
- Decimal points lost after conversion through parseFloat() and toString() methods, causing input failure
Solution
Fix Recommendations:
- Add $$ two-way binding symbol to TextInput component's text parameter
- Use original string value - onChange event's value is already string type, use value directly for text display instead of converting parseFloat() result back to string
- Use inputFilter for negative decimals - When type is set to InputType.NUMBER_DECIMAL, negative decimals are not supported. Use inputFilter to implement negative decimal input
Corrected code:
@Entry
@Component
struct TextInputPage {
@State inputValue: string = '';
build() {
Column() {
TextInput({
text: $$this.inputValue,
placeholder: 'Please enter a number between -50 and 150.'
})
.onChange((value: string) => {
// Convert to number for range judgment
let numValue = parseFloat(value) ;
if (numValue <= -50) {
this.inputValue = '-50';
}else if (numValue >= 150) {
this.inputValue = '150';
}else {
this.inputValue = value
}
})
.inputFilter('^-?\\d*\\.?\\d{0,2}$', (val) => { // Use regex to limit input content
return 0
})
}
}
}
Key Takeaways
- Two-way Binding: Use $$ symbol for TextInput text parameter to synchronize state changes
- Data Type Handling: Avoid unnecessary type conversions that cause decimal point loss
- Input Validation: Use inputFilter with regex for complex input restrictions like negative decimals
- Range Limitations: InputType.NUMBER_DECIMAL doesn't support negative numbers; use inputFilter as alternative
- Performance: Direct string usage is more efficient than parseFloat() + toString() conversion chain
Top comments (0)