In Javascript, how do you detect if the document is in direct focus. By direct focus, I mean you're on the document, but no form elements are focused.
What I'm trying to do here is opposite of Stackoverflow's WYSIWYG editor. Stackoverflow bolds the text when you hit CTRL+B while focus is on the textarea. I want to execute a command when the user is NOT filling out any form on the page. For example, SHIFT+N goes to the next step in my application, but still allows writing capital Ns on form textareas.
I use the Prototype framework, BTW.
There is no need to track focus, it is overcomplicating things and that doesn't pass the common sense smell test... something could go wrong if you missed just one event.
If you observe the root element of a page (document or document.body) then all events which aren't explicitly stopped will reach there and you'll be able to filter out those that started on a form element.
document.observe('keypress', function(event, element) {
if (event.findElement('input, select, textarea') == document) {
// No input was typed on.
}
});
This example doesn't filter out anchors but could do easily by adding a to the findElement call.
Why don't you use a global javascript variable as a flag ?
var isFocusedOnElement = false;
And assign an onfocus trigger to all text areas,input boxes which change it to true onfocus, and false on onBlur.
Then you can check this flag whenever you encounter they keystrokes.
Related
I have an input element which I do not control
for example:
<input tabindex="2" onkeypress="if(NotReady_Key())return;fnKeyPressNum(this,'N',0);"onkeydown="if(NotReady_Key())return;fnKeyDownNum(this,9,0);" id="someElement"/>
In internet explorer 8 and 9, I am trying to find a way to make the element perform as if the "enter" button has been pressed upon the input,
I failed to find a JS way to simulate the press
but I was thinking, is it possible to grab the inline method:
onkeydown="if(NotReady_Key())return;fnKeyDownNum(this,9,0);"
from the element, obtain the element by elementById,
and execute it as if the event actually happened?
here is what I tried so far(I am using jquery):
//get dom element
var element = $("#someElement")[0];
//simulate the event
//insert element as "this"
(function(){
fnKeyDownNum(this,9,0);
}).call(element);
but it doesn't seem to work as excpected, did I forget something?
I think that I also need to make sure other system variables are simulated other than this, to fully simulate the "ENTER" event.
what can i do?
option 2 is of course to simulate a real key press of "ENTER" right on the input, but i failed to find a way to do so in IE8/9 so far, any way would be accepted even using VBS if thats an option.
please note, I specifically need IE8 and IE9 support.
If you just need to call fnKeyDownNum with an element, give this a try:
fnKeyDownNum(document.getElementById('someElement'),9,0);
But if you need to really simulate a keypress (because, a keypress can add input to a field, and if you press enter on a form element it also has the effect of submitting the form) you will have to manage that separately.
Chrome's native spell check won't work on a contenteditable <div> unless the user clicks into the <div>, which makes sense. But if I'm adding a contenteditable <div> dynamically, is there a way to replicate a user clicking into the <div>> so that the spell check will work? I tried using jQuery:
$('#div-id').click();
and
$('#div-id').trigger('click');
but these didn't work. Any help? jQuery or JavaScript works for me.
As a comment mentioned, bringing focus to the element programmatically will work to enable spellcheck. But this might be undesirable due to the focus now being changed to another element. So here is a complete solution (not using jQuery but will still work with it):
var oldFocus = document.activeElement;
div.focus();
if (oldFocus) {
oldFocus.focus();
} else {
div.blur();
}
This saves the previously focused element before focusing the div in order to enable spellcheck. Then, the focus is returned to the old element (if there was one that already had focus), otherwise it makes nothing focused.
I have to do automated tests on a website and I want to use CasperJS to learn. For proprietary reasons I can not give too much code.
Here is the example of the input that I am trying to fill:
<input data-bind="value: firstname, valueUpdate: ['blur'], css: {valid:(firstname.isValid() )} " title="" class="valid" aria-required="true" id="firstname" name="firstname">
As you can see, this input is not of type text and has no value attribute. Therefore, I can not use the casper.fill() method. Furthermore, if I enter the web page scope using evaluate() and change the input value using document.querySelector, the change will not be permanent as of the events attached to the text change on the input will not be triggered.
Here is my code:
this.waitForSelector('#memberTitle', function then(){
var testname = 'thisIsNotPermanent';
this.evaluate(function(testname){
document.querySelector('#firstname').value = testname;
}, testname);
});
If I capture the screen right after, I will see my text written in the input box. However, if I wait 500ms and take another capture, the text is gone as, I suppose, the events are triggered or just cleaned because it actually failed to trigger correctly.
The events attached to the input are of Blur, Change and Keypress.
Using CasperJS, how could I go to the lowest level possible to mimic a user using his keyboard and fully use the website's functionalities already in place?
The whole point of those tests are to work with what is in place. The idea is to not have to manually go through the JavaScript of the web site.
That's exactly what the casper.sendKeys(selector, keys) function is for which will send native keypresses and (hopefully) trigger the events on that text element:
this.waitForSelector('#memberTitle', function then(){
var testname = 'thisIsNotPermanent';
this.sendKeys('#firstname', testname);
}).wait(20, function(){
this.capture('screenshot.png');
});
<input> elements without a type attribute default to Text type.
This answer is here to complete the question from another angle. As Artjom B. mentionned, the correct way to fill an input and to trigger its events is by using the sendKeys() function. However, if you ever have a case, like mine, where the events will not trigger or will take a certain amount of time, know that you can trigger those manually.
If you use the firefox inspector tool, you will see that your input or tag will have an event attached to it marked as ev. If you select it, you will have a breakdown of all the events, in order, that are triggered.
You can see that the jQuery click() event will be called. In casperjs, from the evaluate scope you can now do this :
this.evaluate(function(){
$(".discard-answer").click();
})
From there, you can chain jQuery events, like in my case where I had to .blur().change().click();
It is important to know if the event is jQuery or not.
Hope this helps.
I've been struggling with getting a field working properly. This field displays a lot of data, and the user wants to select and copy a large portion of it. The data is basically a big list and the user wants to select all entries below a certain point. The way that they achieve the selection is by highlighting a word or two in the first entry they want then pressing ctrl+shft+end to select everything to the bottom. This was working until a new feature on the page was added below the contents of the list. Now the hot key select also selects the contents of the rest of the page.
The current implementation is simply :
<div id='diff-contents'>[content here]</div>
<div id='trailing-content'>blah blah blah...</div>
I have tried a read-only input field:
<input id='diff-contents' value='[content here]' readonly/>
This works in Firefox to some extent however the contents contains HTML, and the input field show html literally, not rendered. In addition to that Chrome doesn't show a blinking caret and the hot keys do nothing, so the input field is sadly not viable for me in this situation.
How can I make a selectable field that maintains focus for the cursor and shows a blinking caret but is not editable using javascript, CSS, HTML, or JQuery?
Edit: jsfiddle example that should clarify a bit.
Look at these questions how to determine the current selection: Getting selected text in a browser, cross-platform
The next step is to create a new range which starts at the end tag of #diff-contents. With this information, you should be able to extend/modify the existing selection.
I suggest to either add a button to the UI or use JavaScript with a key-press handler to trigger this code.
With that, the correct amount of HTML should be selected. Users can then copy that into the clipboard with Ctrl+C.
#Aaron Digulla mentioned key listeners, and that got me thinking about simply stopping the events.
The diff-content element is still a div but it is set to editable. This gives both HTML rendering and a blinking caret.
$(this).keydown(function (event) {
if (document.activeElement.id == 'diff-content') {
if (!allowedKeys(event.keyCode)) {
//The only other key presses that should be processed are ctrl+c (keycode 67) and ctrl+a (65)
if (!event.ctrlKey || !(event.keyCode == 67 || event.keyCode == 65)) {
event.preventDefault();
}
}
}
});
The javascript adds a keydown event listener to the entire page. This is necessary since if you just add it to the element, the event has already propagated through the rest of the page and will still be processed, and this was causing funny issues for me. Next we check if it's the diff-content that is active since we want other input elements to still operate normally. Then we check if the key event is an allowed key (tab, home, end, arrows). And finally, check for ctrl+c and ctrl+a and allow those too. I tried event.stopPropogation() and event.stopImmediatePropogation(), and neither of those worked, but preventDefault did.
Lastly, I added style="outline-style:none" to the element so that the blue border would not appear when the element has focus.
The only issue that I have yet to resolve is that since it is editable, the browser still allows you to select and then right click to either cut or paste, which will allow you to alter the text.
Here is the final jsfiddle for what I am using: http://jsfiddle.net/wh3nzmj8/12/
I am looking for a way to bind a function to a text box that executes when the text of the text box changed. I want to avoid the use of keyup or keypress, and other similar things. I don't want it to fire when I lose focus of it, just when the text changes. This needs to definitely work in IE browsers, and preferably work in other browsers.
Does anyone know which is the event to do this?
Thanks.
You might be able to try a setTimeout handler that just checks the value of that textbox every so often and will detect when it changes by comparing the current value to the last value.
I see that you've found a workaround but I just wanted to offer this anyways. Much more granular control.
$('#searchbox').on('keyup, keydown, change', function(e) {
if(e.keyCode!= 9 || e.keyCode!= 16 || e.keyCode!= 17 || e.keyCode!= 18){
//Find keys that you don't want triggering your event and add them in the IF statement above
//http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
//Put code here that calls AJAX
}
});