RN TextInput: don't let user more than maxLength when TextInput already exceeds it

Summary:
We had a classic integer underflow problem here. Before we would let you type endlessly when the text already exceeded the TextInput maxLength, now we only let you erase characters.

There is still a small problem with the TextInput: how do you handle when the value (set from JS) exceeds the maxLength? This could happen pragmatically, just by passing in a very large value or when changing maxLength (e.g. when changing from 4 to 3 digits in the case of a AMEX security code -> VISA security code).

Me and achen1 discussed firing onChange in these cases and truncating the number manually (to ensure JS's data model) was aware of the change but it seemed fraught with bugs and general weirdness in what the caller would expect to happen.

Reviewed By: javache

Differential Revision: D3991210

fbshipit-source-id: dc401c4a7aefe09fa749cd1168d36343d39dc196
This commit is contained in:
Mehdi Mulani 2016-10-18 08:01:00 -07:00 коммит произвёл Facebook Github Bot
Родитель 7762f374d5
Коммит 40e8d8904b
2 изменённых файлов: 38 добавлений и 2 удалений

Просмотреть файл

@ -832,5 +832,41 @@ exports.examples = [
</View>
);
}
}
},
{
title: 'TextInput maxLength',
render: function() {
return (
<View>
<WithLabel label="maxLength: 5">
<TextInput
maxLength={5}
style={styles.default}
/>
</WithLabel>
<WithLabel label="maxLength: 5 with placeholder">
<TextInput
maxLength={5}
placeholder="ZIP code entry"
style={styles.default}
/>
</WithLabel>
<WithLabel label="maxLength: 5 with default value already set">
<TextInput
maxLength={5}
defaultValue="94025"
style={styles.default}
/>
</WithLabel>
<WithLabel label="maxLength: 5 with very long default value already set">
<TextInput
maxLength={5}
defaultValue="9402512345"
style={styles.default}
/>
</WithLabel>
</View>
);
}
},
];

Просмотреть файл

@ -41,7 +41,7 @@ RCT_EXPORT_MODULE()
if (textField.maxLength == nil || [string isEqualToString:@"\n"]) { // Make sure forms can be submitted via return
return YES;
}
NSUInteger allowedLength = textField.maxLength.integerValue - textField.text.length + range.length;
NSUInteger allowedLength = textField.maxLength.integerValue - MIN(textField.maxLength.integerValue, textField.text.length) + range.length;
if (string.length > allowedLength) {
if (string.length > 1) {
// Truncate the input string so the result is exactly maxLength