Is there any to make the left arrow behave like the tab button (set focus to the next focusable item) and the right arrow behave like a shift+tab (set focus to the previous focusable item)?
I've gotten this far:
$().keypress(function(e) {
if (e.keyCode == 37) {
alert('I want to do a shift-tab');
}
else if (e.keyCode == 39) {
alert('I want to do a tab');
}
});
But google isn't being that helpful so I thought I'd put a quick post up here while I google some more.
Thanks!
Oh, and it's purely for FF3.0 so I don't need to worry about other browser nuisances.
What you have so far seems fine.
You could keep a list of 'focusable' items and just iterate through the list keeping a pointer to the current one:
// or $('input')..depends what you want to focus on
var nodes = $('.focusable'), idx = -1;
$().keypress( function(e) {
if (e.keyCode === 37) {
nodes.get(++idx).focus();
}
else if (e.keyCode === 39) {
nodes.get(--idx).focus();
}
});
This is just a rough outline though. You'd need to check the idx before doing something to make sure you don't slip past the beginning or end of the focusable elements array. You'll also need to be careful about calling this when the user is inside of a textbox.
Related
I'm making a minesweeper clone, left click reveals the cell and right click is supposed to flag the cell.
I'm using the function mouseClicked() - this allows me to reveal on left click and also reveal on right click.
I tried using
if(mouseIsPressed) {
if(mouseButton === LEFT) {
reveal
}
if(mouseButton === RIGHT) {
flag
}
}
This registers once every frame that the button is held down. I just want a single right click. I imagine there is something simple that I'm missing, but I really can't find anything in the documentation or anyone asking about it online.
TL;DR - I just want to be able to right click in p5.js.
The mouseClicked() event only occurs once when the mouse button is pressed.
Set a state flag when the event occurs:
var rightPressed = false;
function mouseClicked() {
if(mouseButton === RIGHT) {
rightPressed = true;
}
}
Reset the flag when the action which is triggered by the event was handled:
function draw() {
if (rightPressed) {
rightPressed = false
// do somthing
// ...
}
}
Use the mouseClicked() function and pass the event.
Then using event.button you can determine if it is a right click like so:
function mouseClicked(event){
if(event.button === 2){
// Right click
}
}
Trying to create a minesweeper game, where a right click would add a flag. The right click event, however, is currently not working, i.e, not able get the value of event.which for right and middle mouse button. Just getting contextMenu.
Sample JS:
var trig = function (event) {
if(event.which==1){
//do something on left click
}
else if(event.which === 3)
{
event.preventDefault();
console.log(event.isDefaultPrevented());
//Do something on right click.
}
}
$('.block').click(trig);
Can anyone please tell, a plausible reason why that is happening?
preventDefault was only added as the conextmenu was becoming annoying.
MouseEvent.button
0 for Left mouse button, 1 for Wheel button or middle button (if present) and
2 for Right mouse button.
Internet Explorer 8 and earlier has different values:
1 for Left mouse button, 2 for Right mouse button and
4 for Wheel button or middle button (if present).
Change
else if(event.which === 3)
To
else if(event.which === 2 || event.which === 3)
OR: For IE <= 8
else if(event.which === 2 || event.which === 4)
I have been struggling with this for a couple of days. I am pretty sure it's something simple, but I just can't see it.
On this page there is a form that users can use to send a message. Click on the grey Contact icon to see it.
The form used to work fine, but now I cannot type into any fields. Selecting an autocomplete value works though.
I have tried disabling some Javascript, adding a z-index value to the fields, but to no avail.
Can someone please take a look and tell me what might be the problem?
Thanks in advance.
You are too eager to restrict the user..
This code is the problem:
$(document).keydown(function(e){
if (e.keyCode == 39) {
//(...)
toggleArrows();
}
return false;
});
If the button IS NOT keyCode 39, you deny the button functionality.
Just remove the return false and your problem will be gone.
Edit: I just noticed you have 2 keydown events, one checking for keycode 37 and one for 39. Don't do that! You should do it this way:
$(document).keydown(function(e){
if (e.keyCode == 39) {
//(...)
}
else if (e.keyCode == 37) {
//(...)
}
});
And, again, get rid of the return false;.
JSFiddle to show the result: http://jsfiddle.net/xr2stb0k/
First checkbox is restricted with return false (except for the letter "a"), second one isn't.
I recently added some predictive text input fields to the web-app I am supporting.
Big deal, right? Not really, seems like if your web-app doesn't do this -- you are already behind the times and your end-users are complaining. (At least that's how it is over here).
So, my question has to do with the "up" arrow key.
The predictive textbox has a onkeyup listener.
The handler segregates the key strokes and does something depending on the character the user entered.
The up arrow key allows the user to navigate in a div I created loaded with "suggestions."
I have several variables tracking indexes, etc...
Basically, when the user hits the up arrow I will change the id of the div to an id that has some css associated with it that will make the div appear as though it is selected. Additionally I will grab the value in that div and assign it to the textbox where the user is able to type.
The problem is an aesthetic one. Inherently with all text boxes I am learning, the up arrow key will reset the cursor position. This is happening just before I am writing the new value to the text field.
So, on each up arrow stroke, the user is seeing a jumping cursor in the textbox (it will jump to the beginning and immediately it will appear at the end).
Here's the code -
if (event.keyCode === 38 && currentUserInput.length > 0) {
// user has toggled out of the text input field, save their typing thus far
if (currentToggledIndex == -1) {
currentToggledIndex = autoFillKeywordsList.length-1;
savedKeywordUserInput = currentUserInput;
}
else {
// revert currently selected index back to its original id
document.getElementById("kw_selected").id = "kw_" + currentToggledIndex ;
// user has toggled back into user input field
if (currentToggledIndex == 0) {
currentToggledIndex = -1;
}
// user has toggled to the next suggestion
else {
currentToggledIndex--;
}
}
// 2. Determine next action based on the updated currentToggledIndex position
// revert the user input field back to what the user had typed prior to
// toggling out of the field
if (currentToggledIndex == -1) {
element.value = savedKeywordUserInput;
}
// mark the toggled index/keyword suggestion as "selected" and copy
// its value into the text field
else {
document.getElementById("kw_"+currentToggledIndex).id = "kw_selected";
element.value = autoFillKeywordsList[currentToggledIndex];
}
// 3. Determine what the user can do based on the current value currently
// selected/displayed
displayAppropriateButtonActions(element.value);
}
The funny thing is - the "down" arrow works perfectly since by default the down arrow key will place the cursor at the end of the string currently located in the textbox.
Ok, so things that I have already tried -
event.preventDefault();
event.stopPropogation();
I also tried to set the cursor position PRIOR to setting the new value to no avail using a setCursorPosition function I found on another post here. (Yeah, I was reaching with this one)
I tagged this as JavaScript and Jquery. I prefer to use JavaScript, but open to suggestions in Jquery too!
As Ryan suggested. how I achieved this in angular 4.x is
.html
<.. (keydown)="keyDownEvent($event)" >
.ts
keyDownEvent(event: any){
if (event.keyCode === 38 && event.key == "ArrowUp")
{
event.preventDefault();
//logic..
}
I think what you can do is when they move the cursor, grab that and find out what element it is ... then store it in a variable and focus() it and erase it and then put the value you stored back into it.
var holdme = $("#myelement").val();
$("#myelement").focus().val('').val(holdme);
This works for me when having weird cursor issues in jquery/javascript most of the time. Give it a try and if it doesn't work, let me know and I'll see what else might be wrong.
I found that it worked well to capture the caret position, blur, restore the caret position, then focus again.
myTextInput.onkeydown = function(e){
//some other code
if(e.key == "ArrowDown" || e.key == 40 || e.key == "ArrowUp" || e.key == 38){
var caretPos = this.selectionStart;
//do your stuff with up and down arrows
e.preventDefault();
this.blur();
this.selectionStart = caretPos;
this.selectionEnd = caretPos;
this.focus();
}
}
The caret will very briefly disappear, but I think you have to be incredibly observant to notice.
How do you make the $(this) selector focus on current element? In this jsfiddle, I've mounted it only goes in a specified element, so you cant press enter to activate the button you 'are in'. http://jsfiddle.net/mathzarro/gd6Ep/1/
Heres the tricky part: $("button:first").trigger('focus');
Ps. I've said I mounted as an expression! The original coder was Ian, here it is the link.. thanks #Ian! http://jsfiddle.net/Vtn5Y/
The real problem was mentioned by HazMat, you were focusing on the wrong element (always the first button using $("button:first").trigger('focus');.
Calling liSelected.trigger('focus'); at the end of your keydown handler and removing the other calls to $("button:first").trigger('focus'); will fix the problem.
You also have another problem
$("button:eq(1)").click(function () {
// Why are you calling this? Remove this line
$("button:eq(0)").trigger('click');
update($("span:last"));
});
Here's a working example
Also, the jsfiddle is great but you should post the code relevant code here too.
Improvement suggestion
The code you posted suffers from brittle queries, internal coupling, that is, it's not very flexible to changing HTML structures. I've re-worked your code so that it's in better shape. Here are the main features
Doesn't break if you tab
Works for as many buttons as you need
No hardcoding for first or last div (smart wrap around)
No hardcoding of the output divs, all handled in one place, by relying on the fact that it's the nth button being clicked.
Up/right go forwards, down/left go backwards
No need to track the element yourself, that's what document.activeElement is for
Each section of code is separated
Add class to selected button (CSS only) (so it doesn't need to add a "selected" class to buttons.
Update output
Set focus on the next buttons
Here's the code
var buttons = $('button');
var spans = $('span');
// Update the span when button is clicked
buttons.click(function(e){
var span = $(spans[Array.prototype.indexOf.call(buttons, document.activeElement)]);
span.text(parseInt(span.text(), 10) + 1);
});
// Handle the navigation, set focus on the next element
$(window).keydown(function(e){
var isLeft = e.which === 38 || e.which === 37,
isRight = e.which === 40 || e.which === 39;
if(isLeft || isRight){
var currentButtonIndex = Array.prototype.indexOf.call(buttons, document.activeElement);
var nextButtonIndex;
if (currentButtonIndex === -1) {
nextButtonIndex = 0;
} else {
var toAdd = isLeft ? -1 : 1;
nextButtonIndex = (currentButtonIndex + toAdd + buttons.length) % buttons.length;
}
buttons[nextButtonIndex].focus();
}
});