Scan inputs with Opera Mobile 10 - javascript

We have chosen the Opera Mobile for one PDA application, everything went well until we hit a problem with regards to taking a scanned input to one of the text fields.
The general way you'd approach this problem is by setting one textBox to have focus when the scan operation is performed.
UNFORTUNATELY, intentionally or unintentionally Opera is not supporting this. The focus is no-where when you enter in to the screen and there is no way of explicitely setting it. Worst comes next, you cannot detect the key-press events too, which makes it virtually impossible to take the input event from the scan operation.
I have no clue why Opera, one of the best acclaimed mobile browsers, does not support this.
These are the places the same question is asked over and over again,
http://dev.opera.com/forums/topic/255066
http://dev.opera.com/forums/topic/650332
http://dev.opera.com/forums/topic/384311
We have posted in the Opera Dev forum as well and it seems that they (so far) have no solution for this. If anyone has tried a workaround, we would be interested to hear the solution.
And please note that the solution in here is not working in Opera Mobile 10. I have not tried it in the proposed 9.X version.

I found it myself. And here is how to do it.
Have a hidden button in the form
input type="button"
id='myHiddenButton' visible='false'
onclick="javascript:doFocus();"
width='1px' style="display:none"
Have a javascript to get fired on the click event of the hidden button.
function doFocus() {
var focusElementId = "MyTextBox"
var textBox = document.getElementById(focusElementId);
textBox.focus();
}
Have the button clicked using a javascript at the end of the document
function clickButton() {
document.getElementById('myHiddenButton').click();
}
setTimeout("clickButton()", 100);

Related

jQuery $.post() inside w2ui .reload() makes TEXTAREA silently lose focus in Chrome

Note: this question is probably too specialized. The solution (if I ever find one) is unlikely to help anyone but myself. Nonetheless, I believe the workaround described below to apply to several borderline Chrome/jQuery focus loss scenarios.
Scenario:
I have an input TEXTAREA to enter some text.
Meanwhile, a timer makes periodical AJAX calls to the server (one per minute).
What happens:
In Firefox, everything is hunky dory and the user can type away to his heart's content.
On Chrome, when the AJAX request fires, the input focus is lost. It goes... nowhere, apparently. window.activeElement returns nothing, and the cursor indeed disappears from the textarea, until the user clicks it again with the mouse.
What I expected:
Well, for the focus to stay there.
Attempts:
One - I have tried setting an event handler on the textarea's [.focusout()][1], only to discover that the event does not fire. It does fire when the user clicks somewhere else, but that doesn't help.
Two - I have then tried a less elegant - say rather, brutal - approach:
var hasFocus = document.activeElement;
if (hasFocus) {
var focusKeeper = window.setInterval(function(){
hasFocus.focus(); // JUST. STAY. THERE.
$(hasFocus).css("background-color", "red");
}, 10);
}
The field goes red, so the handler is firing at least. Except that the focus does not come back. It's just as if Chrome isn't even trying.
Again, everything works as expected in Firefox. I'll try next on Safari to confirm whether this is a Webkit-related thing.
Research and more attempts:
I've found several posts on how to overcome focus loss, or how to set the focus in the first place, even on newly created fields (which mine isn't), but my case seems different enough that they either offered no clue, or just plain didn't work. The documentation states that
element.focus();
is necessary and sufficient, yet sufficient quite clearly it is not. Someone has suggested setting focus using a zero-delay timeout; I tried, but this did not seem to help.
Could this be related to the fact that Chrome maybe runs XHR requests in a different process, so that the "focus" is going to the hidden XHR window? (Haven't tried with the --process-per-site commandline switch, it just occurred to me - I will now give it a try).
Could this be a bug? There was something like it, but bug 27868 was related to Flash objects, not TEXTAREAs - that's a completely different animal AFAIK.
The strange thing is that this behaviour (or one amazingly similar) was noted on Firefox and the bug reporter says explicitly, focus should remain on the same input control like in other browsers, so he did not observe it on Chrome.
JSFiddle - not exhibiting the behaviour, thus supplying a clue
I made a fiddle, and... it works. So the issue seems to be more with the function called in the timer, which is a w2ui grid.reload(). I still do not understand why the focus doesn't come back using focus(), as it should.
Acceptable workaround
Inspired by amphetamachine's comment, I've tried combining several of the tricks in the posts above. I've come up with a combination that works... sort of.
The elements needed (whichever I remove, the trick stops working) are:
re-set the focus manually where it was
do this inside a setInterval timer
blur the focus before re-setting it
unset and reset the focus inside a short, but not zero, setTimeout delay.
// Save focus.
hasFocus = document.activeElement;
w2ui.myGrid.reload(function() { // Callback, called after reloading.
// If there was no focus, we just return.
if (hasFocus) {
// We DON'T do anything directly, but use setTimeout.
window.setTimeout(
function() {
// And before setting the focus, we truly remove it.
hasFocus.blur();
hasFocus.focus();
}, 5); // A timeout of 0 does not work.
}
});
The "con" of this solution is that the cursor visually "shivers", and any key that was pressed during the second part of the grid.reload(), after the unknown event that loses the Chrome focus, will of course get lost.
Obsolete: just update the libraries.
The strange behaviour disappeared by upgrading w2ui to 1.4.2 on the latest Chrome (actually, I did not try on previous Chromes because I didn't think to keep copies of the previous versions).

Form event incompatibilities between browsers, how to address?

I have a textarea on a html page, on google chrome, well I don't know what version because the user interface is deviously hidden, but on chrome the onChange="code" event isn't firing but on Firefox 11.0 1.0 (according to help->about) it is firing. Then instead I start playing around with the events onkeydown="same_function()", onpaste="same_function()" and oninput="same_function()", in order to be absolutely sure to capture at least one event. But now the problem is that I'm getting too many events, and when I check the textarea_dom_object.value of the textarea after getting a keydown event the key that was pressed isn't included in the value that I'm reading; if I have "abc" in the textfield and I press 'd', that generates a keypressed, but I'm still getting only "abc", not "abcd".
Is there a compatible way, or at least a way that works on most browsers, to get an event every time a textarea changes, but preferably only one event? I don't like the kind of ugly code I would have to write if I had to first test if I've already listened to an event and so forth. All I want is one event each time the text in the textarea changes.
Here's the thing about why jQuery is so amazing. It understands the need to gracefully degrade the code between browsers that don't support newer functionality. JavaScript in and of itself does not offer this support stand alone. By enhancing JavaScript's core capabilities in using jQuery, you are generally going to be more successful with cross browser support.
That being said...
There are still plenty of scenarios where you need to identify what device/browser you're working with so that you can perform the expected operations.
The most important thing to remember is that there is no 100% cross-support library in existence.
you can do this. just make sure you give the textarea an id tag
$(document).ready(function(){
$('.addtitle').keyup(function(event) {
if(event.keyCode==13) {
}
});
});
in my case here, im firing the function on the enter key (like facebooks functions).
EDIT: also if you have more then one textarea on a page, you should do this:
$(document).ready(function(){
$('textarea[name=mynamevalue]').keyup(function(event) {
if(event.keyCode==13) {
}
});
});

Can a `range.insertNode` be undone using browser's undo, in a contenteditable div?

I am working on a contenteditable div to make a simple RichText-Editor. One of the requirement I have is to be able insert html chunk at cursor postion on a button event.
I was able to get that part working fine by using range, selection, range.insertNode(nodeHTML) or range.pasteHTML(nodeHTML) based on browser. But I couldn't get two things, which ideally I would like to have
To be Able to undo the inserted node, using browser's undo. Somehow, browser ignores above actions.
To move the cursor at the end of inserted node. So that user can start writing after
I know I can use something out of many editors available, which does this very well, but If I get this I would not have to. Any help or even suggestions are welcome.
Thanks.
Answer rewritten August 2013
Unfortunately not, although things are improving. Programmatic DOM mutations other than those triggered by document.execCommand() do not go on the browser's built-in undo stack. However, there have been two recent developments:
IE 11 has new ms-beginUndoUnit and ms-endUndoUnit commands
There is a spec in the works for an undo stack available to web developers, parts of which have been implemented in WebKit and Firefox (note: it's disabled by default in Firefox and apparently also in WebKit).
Until the situation improves, you could use document.execCommand("InsertHTML", false, "<b>Some html</b>"); but this is not supported in IE.

Multiple checkboxes check as in Gmail

I'm trying to copy the behavior of Gmail with the checkboxes, selecting a whole range click on one and then shift-clicking another, the checkboxes in between these will change.
However, I'm having a compatibility issue between Firefox and Chrome as clicking the checkboxes works just fine, but clicking the labels somehow it's handled very differently, as Firefox will apparently not trigger the change when shift-clicking.
You can check and test my code here.
Obviously there's a trouble with Firefox and the label, I've tried triggering the checkbox's change(), but it works backwards the behavior of the checkbox, I've tried 'resetting' the label events with preventDefault() and then triggering the change() event and the issue seems to be the same, but now Chrome has this bug (which I think it's somehow the correct way, first homologizing).
The easy way is detecting browsers, but every web developer guru tells us that it's better to identify the problem rather than the browser, so what would be a good fix for this? Also, it doesn't work in IE because it doesn't support indexOf().
Thanks!
For some reason the tag is working differently when highlighting text in Firefox. I think the reason it is failing is because when you hold down shift and click on the label, it doesn't check the box and thus doesn't fire the labeled event.
Check out this: http://jsfiddle.net/xerf/Prxdn/10/
This works both in webkit and FireFox. I changed the labels to span tags. With a bit of CSS, you can fix the padding.

Detecting drop into textarea with Javascript

All I need is to be able to detect when text is dropped into a Textarea. I then take that text and do stuff with it and clear the textarea. There may be many of these textareas and very high UI expectations, so polling is a last resort.
For IE, "onfocus" does the trick, since this event is fired after the user drops stuff into the textarea.
For Firefox, I can't find an event that works. I've tried onmouseup and onchange.. don't know what else to try from there. I'd hate to have to poll the textarea for content. Help much appreciated. Thanks.
Edit: For clarification, "dropped" means the user selects text (usually) from the page, but it doesn't matter where, drags it, and drops it into the textarea. This is not the same as Ctrl+V, or right click pasting (which take two different methods of detection, BTW), or (obviously) typing into the textarea. Specifically, it is the "drop" aspect of drag and drop. I really don't know how else to phrase it.
I feel this question was stated rather accurately. To humor me, assume that I meant any of the other operations on a textarea that you all have chosen to share. If I meant "pasting", don't you think I would have mentioned something about pasting in the title or content of my question? Same goes for typing in a textarea. But, perhaps, you all just don't know me well enough to know that I type what I mean, rather than mistakingly typing things only somewhat related to what I mean.
For Firefox, this works for me:
window.addEventHandler("dragdrop", function(event) {alert("Drop it like it's hot!")}, true)
Does not work in Safari, however. Haven't tried IE.
Polling seems to be the only way to go.
When a Drag+Drop operation is started within the browser, it seems to cancel out everything else that's going on. You can witness this by putting "onmouseover" events on something on the page, then starting a DnD operation and dragging over it. The events will not fire.
It seems only a coincidence of how the browser internally handles "drag and drop" that it causes onfocus() to be fired for the textarea in IE and Safari. I doubt there is much defined in the W3 specification... not that it matters, W3 is crap, and besides nobody adheres to it completely.
In my question I stated the luxury of emptying out the textarea after each use, so I feel that polling for: textarea.value.length>0 is hardly any cost and shouldn't be much of a performance concern.
But, alas, it specifically has to do with dropping content into a textarea.
Down-mod away to sooth your pain.
If you want your textarea to react to text being dropped, pasted or typed, your only solution would be a button. Even a timer polling the content will not help you.
You mention that you want the user to be able to type text in the textarea. And you mention that you want to clear the text whenever the event is fired. There is no possible way for the browser to know that the user has finished typing. You must rely on a specific action.
Now for the drop or paste, you can rely on the mouseup and keyup events in order to detect that.
What do you mean by "dropped"? Are you talking about a paste (^V) operation? If so Aron's answer is indeed correct, you will get keydown/keyup (and the value will be readable in keyup).
A generic callback that will happen on any update to an input is 'onchange' - you could try that. Note that when typing, it doesn't get called until you finish and unfocus the input, so if you need instant updates on both typing and other forms of input, you still need 'onkeyup' as well.
Edit re clarification: IMO 'onchange' should be fired when a drag-and-drop causes content to be added to a text area; I consider it a browser bug that it is not (in Firefox at least). I can only concur in this case that polling is all you have left.

Categories

Resources