0

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/

matt_zarro
  • 147
  • 6
  • ps. up and down arrows navigate through buttons – matt_zarro Mar 28 '13 at 17:48
  • `$("button:first")` will always be the first button, obviously. Why not `liSelected.trigger('focus')`? – gen_Eric Mar 28 '13 at 17:57
  • 2
    You have non-`li` elements as children of `ul`. This isn't allowed. – Jeff B Mar 28 '13 at 18:01
  • I know Hazmat, im not that dumb.. haha the thing is when i was using $(this).trigger('focus'); it wasnt working so i preferred to let the button:first so people could 'feel' what was the problem.. you've answered my question, thanks a lot! – matt_zarro Mar 28 '13 at 18:08
  • And Jeff, I forgot to delete that (i imported from another js).. thanks for your help! – matt_zarro Mar 28 '13 at 18:10
  • Hi man, I did a different version of your code: check this out: http://jsfiddle.net/GQv26/ – Joqus Mar 28 '13 at 18:13
  • Hey @Joqus, thats also an interesting approach..but how would make it capable of support the down arrow(or any other arrow) too? – matt_zarro Mar 28 '13 at 18:40
  • 1
    @Joqus It's a little improvement, but hard coding the fact that there are two buttons is still not great, also still doesn't work if you tab. See http://jsfiddle.net/GQv26/2/, you can have as many buttons as you want – Ruan Mendes Mar 28 '13 at 19:09
  • @matt_zarro You just need to check for the key code. Check the code of Juan – Joqus Mar 28 '13 at 19:21
  • @JuanMendes nice code. I tried to change as less as possible to make the example work. – Joqus Mar 28 '13 at 19:26
  • 1
    @Joqus Sometimes I get excited when I see poor code with lots of room for improvement. There are lots of techniques in there that every one could be using when handling keyboard navigation on your own. Hopefully a few people will learn a few tricks from it – Ruan Mendes Mar 28 '13 at 19:28

1 Answers1

2

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();
    }
});
Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • Muchas gracias Juan, that was great! Im independetly developing a keyboard supported version of openerp that will help a lot of people that cant afford touchscreen hardware.. do you mind to look my other question and tell how do i connect the jsfiddle of this question to the xml file mentioned in the other question? Thanks! http://stackoverflow.com/questions/15683251/how-to-use-arrow-keys-to-navigate-through-elementsand-highlight-them – matt_zarro Mar 28 '13 at 18:28
  • @matt_zarro I looked at the other question and it was pointing back to this question??? I don't really understand what you want there that is different from here. Please don't ask the question again here, fix that question, adding the knowledge you got from this question. This is how posts stay useful at SO. If I try to help your problem specifically (through comments here), the posts are less useful to others. – Ruan Mendes Mar 28 '13 at 19:21
  • That was remarkable @Juan, and sorry for the confusion. I will explain better the situation. The main file of openerp we are working is an xml. I've added an html and a script tag to enter the scripts developed so far. And now I've tried also that last brilliant code of yours, but it's not working in the xml context. I think if you take a look at the xml file you'll have a better picture of what is going on. Here it is: http://matheus25.site90.net/pos.xml – matt_zarro Mar 28 '13 at 19:58
  • Also, this is point of sale in action, if you want to use 'inspect element'. https://demo1.openerp.com/#view_type=form&model=pos.session.opening&action=687 – matt_zarro Mar 28 '13 at 20:04
  • @matt_zarro When I go to the page, it gets treated as XML, not HTML I can only see its source. The problem you will encounter is that the element must be able to receive focus. Therefore, you can use `tabindex="-1"` to your button like tags so that the fields are focusable. See http://jsfiddle.net/Vtn5Y/391/ – Ruan Mendes Mar 28 '13 at 21:28
  • You've did more than your part man , but after hours i still can't get it to work on the actual xml file (the file you saw it's the actual file im working in). Any further than this would be private consulting which obviously is not the aim of SO, still if you have any other insights just prompt me here. – matt_zarro Mar 29 '13 at 04:21