I've been having an issue with maxLength on <TextInput/>in ReactNative and I'm pretty sure its only happening on iOS.
The problem:
If the last character of an input is an emoji, and that emoji puts you over the maxlength number then it deletes the entire input! An example of it is if the maxLength is set to 5 and the input is "xxxx" (4 characters) and then you add an emoji the entire input text gets deleted. I'm sure this has something to do with emojis mostly being 2 characters but I can't seem to find an "eloquent" work around!
Snack to see exactly what I'm talking about:
(I've only been able to replicate it in iOS)
https://snack.expo.io/#sararan/textinput
Things I've tried:
Adding an onKeyPress event (that gets hit before the onChangeText event) that calls e.stopPropagation() and e.preventDefault() (both for good measure ;) ). But it doesn't actually stop the event and I'm thinking it has to do with how react handles events and maybe that it's already bubbled up by this time?
Taking out maxLength altogether and creating my own rules that splices the input if its over the length I want and then replaces any special characters something like...
const onChangeText = (value) => {
if (value.length > 5) {
value = value.slice(0, 30).replace(/[^\w\s]/gi, '');
}
setText({ value });
};
but this solution seems to cause the flickering that we all hate with these types of solutions.
I'm wondering if anyone might have run into this before and might have a more eloquent solution? Thank you for your help!
Related
I am working on a Vaadin (7) server-side application, and i need to use a TextArea or a RichTextArea that will analyze word-by-word the typed input, and will highlight words of a certain type, for example - dates and times.
My problem is that a RichTextArea does not have a TextChangeListener, and a regular TextArea does not have a highlighting option because it does not support HTML tags...
I tries using ShortcutKeyListener for RichTextArea and analyze the text after every Space key, but it was too slow and had also some other problems.
Is there anything else i can do?
Is there an option to analyze the text on real time when using RichTextArea? or is there any add-on youre familiar with that can do that?
Or is there a way to highlight text in TextArea after analyzing it?
Thank you!
My suggestion is a bit strange, but anyway, take a look on Vaadin AceEditor. It supports text mode and SelectionChangeListener:
ed.addSelectionChangeListener(new SelectionChangeListener() {
#Override
public void selectionChanged(SelectionChangeEvent e) {
int cursor = e.getSelection().getCursorPosition();
Notification.show("Cursor at: " + cursor);
}
});
See details here: Vaadin AceEditor
When I'm binding text to an input on iOS, my setter is called each time a character is added, on iOS, but not on Android.
If I put a breakpoint on a property that is binded to a TextField in iOS, each time a character is entered, the property setter will be called, but not on an Android EditText.
It makes more complex ViewModels with several input attached to getter/setter tested on iOS completely useless on Android since it cannot be used.
Is there a way to make the "MvxBind="Text SomeProperty" acting like iOS on Android?
Events like "AfterTextChanged" (any binding to a command) aren't property-friendly, and would break my ViewModel. I don't want to have a platform-dependent workaround.
[Edit]
// Droid. It calls the TotalAmount setter once the editing is done.
<EditText local:MvxBind="Text TotalAmount,
Mode=OneWayToSource; Text TotalAmountString, Mode=OneWay" />
// Touch. It calls the TotalAmount setter on key press.
set.Bind(MyTotalAmountTextField)
.For(v => v.Text)
.To(vm => vm.TotalAmount).OneWayToSource();
set.Bind(MyTotalAmountTextField)
.For(v => v.Text)
.To(vm => vm.TotalAmountString).OneWay();
By the way, the displayed property is always formatted with a dollar sign, that's why I'm using an half-duplex approach for binding.
Appart from this live (iOS) versus after-edit (Droid) problem, the bindings are working well.
The default behaviour for TwoWay Text binding on both Android and iOS is to do per character binding.
You can see this behaviour in, for example, the N=0 video at 18:43 - http://youtu.be/_DHDMNB_IeY?t=18m43s
If you are not seeing this behaviour in your EditText then I guess it might be down in some way to your app or perhaps to a bug (e.g. perhaps in OneWayToSource binding somehow - this certainly isn't as commonly used as other binding modes).
To workaround this, I can only think to suggest:
Log it as an issue with a reproducible case (github repo) on GitHub/MvvmCross - someone there might be able to help - or you might be able to fix it yourself.
Try TwoWay binding instead
Try creating your own custom binding or your own custom control - this is actually very easy to do - see the tutorials N=28 and n=18 on http://mvvmcross.blogspot.com - for example you could try inheriting from EditText to create something like;
public class MyEditText : EditText {
public MyEditText(Context c, IAttributeSet a) {
this.AfterTextChanged += (s,e) => MyTextChanged.Raise(this);
}
public event EventHandler MyTextChanged;
public string MyText {
get { return Text; }
set { Text = value; }
}
}
I'm using AIR 2.0 (soon will be updating to 3.3 with Flash CS6) to create an iPad app. We have textfields (Classic, dynamic) which sometimes contain one or multiple htmlText links which need to be clickable. In the desktop version of the program, all text is selectable and the links are easily accessed. My problem is that it takes me mashing the link like 20 times on the iPad before it will recognize that there's a link and navigate to it in Safari. The other strange thing is that none of the text appears to be selectable - I can't get the iPad cursor, copy/paste menu, etc. to show up.
I think, from reading other threads, that the hit area for the URL is only the stroke on the text itself... if that's true, what can I do to increase the hit area? Or make text selectable? It was suggested elsewhere to put movieclips behind the URLs but that's not really possible as this is all dynamic text from XML files.
I've read about StageText but I gather this is only used for input fields, which is not the case here.
I'm reasonably advanced in AS3 but I'd prefer an easy solution over re-writing large chunks of code. At the moment the only thing I can think to do is get the URL and make it so that as soon as you touch anywhere on the textfield, it navigates to the link. But this would break down if there were more than 1 URL in a given textfield.
Any ideas?
I had this exact same issue, and it's had me flummoxed for a while.
Here's what I did to get the desired behaviour:
1) Instead of using a listener for TextEvent.LINK, listen for MouseEvent.CLICK (or TouchEvent.TAP) on the TextField.
eg.
var tf:TextField = new TextField();
tf.addEventListener(MouseEvent.CLICK, linkClicked);
2) In the linkClicked() handler, you use getCharIndexAtPoint() to determine the index of the character that was clicked, and then from that determine the URL from the TextFormat of the character. This is adapted from a post by Colin Holgate on the Adobe Forums (http://forums.adobe.com/thread/231754)
public function linkClicked(e:MouseEvent):void {
var idx:int = e.target.getCharIndexAtPoint(e.localX, e.localY);
trace("Tapped:",idx);
var tf:TextFormat = e.target.getTextFormat(idx);
if(tf.url != "" && tf.url != null) {
var linkURL:String = tf.url;
trace(linkURL);
// Hyperlink processing code here
dispatchEvent(new UIEvent(UIEvent.LINK_TAPPED,tf.url));
}
}
3) The last line (dispatchEvent()) is sending a custom event to another function to process the link, but you could easily inline your code here.
I've tested on an iPad 3 running iOS6.1, building with AIR3.5. Links are much more responsive, and I don't find myself mashing the screen trying to hit the stroke of the text!
Here are the codes I have to dynamically create and enhance a page. The similar pattern has been working for many other kinds, such as text field, button, grid-view, etc. But I found it cannot work with a listview.
$(document).bind("pagebeforechange", function route(e, data) {
...
$content = $page.children(":jqmData(role=content)");
var markup = '<ul id="calendarList" data-role="listview"><li>HELLO</li></ul>';
$content.html(markup);
$page.trigger('create');
$.mobile.changePage($page);
});
I would always get an error message like,
Cannot read property 'jQuery16409763167318888009' of undefined
Through debugging using Chrome, I found it always fails on the line of $page.trigger('create');
I found the solution myself. It works fine if I replaced the line,
$page.trigger('create');
with,
$page.page();
$content.find( ":jqmData(role=listview)" ).listview();
However, I still don't understand why. I thought the former was a newer, simpler syntax to replace the latter. A single call of $page.trigger('create'); can enhance the entire page at one shot. Does anyone know the difference of these two?
I was wondering if there is a way to get the current value of a on the keydown or the keypress event. To define "current value" in a better way, I mean, by this, the value of the textarea, including the "just inserted" character. By default on these events the value does not change. If this is not possible i would like to know if there is a cross browser way to get the just inserted value of the key that I pressed (I don't need the keycode, because e.g. this does not define, supposing that I enter a characterm if the character entered is Uppercase or Lowercase).
You'll have to wait for the keyup event to fire before the actual value changes.
Otherwise, for keydown or keypress, you have to map the character code on the event (and this is different per browser unless you use some JS library like jQuery which standardizes it) and determine the cursor position and modify the value that way. This can get a little tricky especially around browser support unless you use a JS library to do this.
I wrote a module that translates keypress, keydown, and keyup events into characters and keys respectively. https://github.com/fresheneesz/keysight
Example:
textarea.addEventListener("keydown", function(event) {
var character = keysight(event).char
if(character === 'w') {
console.log("got lower case w")
} else if(character === 'W') {
console.log("got upper case w")
}
})