How can I allow the tab key only inside a specific div?

Discussion in 'Web Design and Development' started by sk3pt1c, Feb 8, 2013.

  1. macrumors 6502a

    sk3pt1c

    Joined:
    Nov 29, 2005
    Location:
    a simulacrum
    #1
    I have a form that is broken down into several tabs/pages to make it easier for the user to fill.

    The thing is, there are buttons to go from page to page but if you keep pressing the tab key you will go to the next page but it breaks the form.

    I want to be able to allow the tab key only inside each and prevent it from skipping from one to the next.

    Setting the tabindex to -1 won't work because i actually want the users to navigate the pages with the tab key properly.

    I've also tried adding tabindex="-1" to the div but it doesn't seem to work.

    So i'm guessing jQuery?

    The form has basic text boxes, dropdowns and radios and it's wrapped in a codaslider content sliding plugin.
     
  2. macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #2
    It is wise to manually specify tabindex="x" in each form element using positive integers in the order you want them to be focused as sometimes browsers don't respect the flow order. But what will also help you is to know to use value 0 to skip any element (i.e. next/prev page buttons outside of the form as you noted). Not negative.

    The tabindex attribute can also be used with <a>, <textarea>, <select>, and <button> elements, FYI when you design forms.

    On a side note if you want to force a form field (i.e. the first one) to be focused then assign it an ID and in Javascript:

    Code:
    var field = document.getElementById("foobar");
    field.onblur = function() {
        field.focus();
    }
    
    -jim
     
  3. thread starter macrumors 6502a

    sk3pt1c

    Joined:
    Nov 29, 2005
    Location:
    a simulacrum
    #3
    Hello and thanks for your reply.

    The problem is that my form encompasses divs and i don't want the user to tab from one div to the next.

    So it's like this

    <form>
    <div>
    Page 1 fields
    </div>
    <div>
    Page 2 fields
    </div>
    </form>

    i want the users to be able to tab from one field to the next in each page, but not from the last field of one page to the first field of the next. so in essence i want the tab key to work only inside the divs and not from one to the next.
     
  4. macrumors 6502

    Joined:
    Jun 8, 2009
    #4
    Maybe adding validation rules so that a user can't proceed would probably accomplish what your looking to do.
     
  5. macrumors regular

    Joined:
    Mar 27, 2009
    Location:
    Skipton, UK
    #5
    I'm assuming that you are mixing up "page" and "div" here.

    If you don't want users to be able to move from the end of one div to the start of the next, why have them in the same form? Are there mandatory fields in each part of the form? Why does tabbing between divs "break the form"?

    Without knowing what you are aiming to achieve in a system wide sense it's hard to give any clues.
     
  6. thread starter macrumors 6502a

    sk3pt1c

    Joined:
    Nov 29, 2005
    Location:
    a simulacrum
    #6
    because the divs are how the scroller breaks up the form into "pages", they're the slider's panels.

    the form encompasses all the panel divs.

    there are "next" buttons that do the validation of any required fields when clicked (not all panels have required fields) but if you tab from the last field of one panel you go to the first field of the next, effectively breaking the validation and the slider layout because it doesn't slide to the next panel.
     
  7. macrumors regular

    Joined:
    Mar 27, 2009
    Location:
    Skipton, UK
    #7
    OK, but why is the form so big that you need it on different panels? (let's use panels here rather than pages)

    As someone else has suggested, add the validation code to the transition, not the button, so it doesn't matter how the user moves from one panel to the next.
     
  8. macrumors 68000

    SrWebDeveloper

    Joined:
    Dec 7, 2007
    Location:
    Alexandria, VA, USA
    #8
    Should have posted that first ;)

    Others offered the proper advice (re: validation code, i.e. rules as to when to submit) but I am as confused as others when you say PAGE. I think you meant panel, i.e. region, whatever you want to call each div but clearly by your code above there is one page and one form. If not, you need to include a link to this page so we can see for ourselves as my original advice still stands, applying tabindex 1,2,3 etc. to all form elements on the page and 0 for your next/prev which traditionally are <a> and <button>. This means a user can cycle from the top to bottom, then submit button, but they must CLICK the next/prev. Set the form focus to first element in the first region as a I noted and users really appreciate that kind of stuff. The validation rules are for the submit and you can also check if next/prev were clicked and prevent submit.

    I covered it all here, I think. Happy coding. :D
     
  9. thread starter macrumors 6502a

    sk3pt1c

    Joined:
    Nov 29, 2005
    Location:
    a simulacrum
    #9
    OK, I have confused you guys with the "pages", "tabs" and "panels", here is some code:

    Code:
    <form action="" method="post">
    
    <div id="slider-id-wrapper" class="coda-slider-wrapper">
    
    <!--this is the slider panel navigation-->
    <div class="coda-nav">
    <ul>
    </ul>
    </div>
    
    <div class="coda-slider"  id="slider-id">
    
    <!--Panel 1-->
    <div id="panel1">
                                                        
    various form fields here
    													
    <a id="panel1nextButton" class="next-btn" href="#2" data-ref="slider-id">Next Step</a>
    </div>
    
    <!--Panel 2-->
    <div id="panel2">
                                                        
    various form fields here
    													
    <a class="previous-btn" href="#1" data-ref="slider-id">Previous Step</a>
    <a id="panel2nextButton" class="next-btn" href="#3" data-ref="slider-id">Next Step</a>
    </div>
    
    <!--Panel 3-->
    <div id="panel3">
                                                        
    various form fields here
    													
    <a class="previous-btn" href="#2" data-ref="slider-id">Previous Step</a>
    <a id="panel2nextButton" class="next-btn" href="#4" data-ref="slider-id">Next Step</a>
    </div>
    
    <!--Panel 4-->
    <div id="panel4">
                                                        
    various form fields here
    													
    <a class="previous-btn" href="#3" data-ref="slider-id">Previous Step</a>
    <a id="panel2nextButton" class="next-btn" href="#5" data-ref="slider-id">Next Step</a>
    </div>
    
    <!--Panel 5-->
    <div id="panel5">
                                                        
    various form fields here
    													
    <a class="previous-btn" href="#4" data-ref="slider-id">Previous Step</a>
    <!--Submit button-->
    <input type="submit" id="form-submit-button" name="Submit" value=""/>
    </div>   
                                                     
    </div>
    <!--end of .coda-slider-->
    
    </div>			
    <!--end of slider-id-wrapper-->
    
    </form>
    <!--end of form-->
    
    The form has to be in panels because it has many fields.
    The validation has been rigged to the "Next" links.
    When you tab from the last field of panel1, even if the "Next" link has a tabindex of 0 or -1, it will skip that element
    and move on to the next available field, which is in panel2, hence the validation and form layout breaks.
    The way the slider works is it creates panels and puts them side by side to make a really wide container which it slides to the left everytime you hit the "Next" button.

    I want the tab key to work inside each panel but not have the user be able to tab from the end of one to the beginning of another panel.
     
  10. Dunmail, Feb 12, 2013
    Last edited: Feb 12, 2013

    macrumors regular

    Joined:
    Mar 27, 2009
    Location:
    Skipton, UK
    #10
    What you can do (and there are potential usability issues) is capture the tab keyevent and cancel the default behaviour then add your own.

    Code:
    function stop_tab(e){
        if(e.target.id === 'lastInput'){
            if(e.keyCode === 9){
                e.preventDefault();
            }
        }
    }
    
    You'd have to attach this, or something like it, to the last input field on each div.
    Is this what you are after?
     
  11. thread starter macrumors 6502a

    sk3pt1c

    Joined:
    Nov 29, 2005
    Location:
    a simulacrum
    #11
    i've tried something like that but this works like a tabindex of 0 or -1 in practice, it just skips that element and moves to the next one which is on the second panel (unless i'm doing something horribly wrong of course).

    i guess there's some logic i'm missing in how to properly allow/disallow the tab key... :(
     
  12. macrumors regular

    Joined:
    Mar 27, 2009
    Location:
    Skipton, UK
    #12
    You don't just cancel the default action you need to give it an action like moving focus to the "Next" button. The "Next" button should also handle the tab key so that if the user presses "TAB" or "ENTER" or clicks the button then the validation and moving to the next panel takes place.

    Basically you need to ensure that focus moves from the last input field on each panel moves to the "Next" button and that the "Next" button handles the tab key.
     
  13. thread starter macrumors 6502a

    sk3pt1c

    Joined:
    Nov 29, 2005
    Location:
    a simulacrum
    #13
    That makes sense but how would i go about implementing that?

    At the moment i'm hijacking the content slider's function for links inside the panels and doing the validation when the link is clicked. If invalid, i disable the href of the link and mark the invalid fields. If valid, i enable the href and let the slider slide to the next panel
     
  14. macrumors regular

    Joined:
    Mar 27, 2009
    Location:
    Skipton, UK
    #14
    I'm afraid I don't know about codaslider. Where you say that you are "hijacking the content slider's function" Then this is the event handler for the button. What you need to do is attach event handlers to the last input field on each panel to disable the tabbing, so using the previous function.

    Code:
    <input onclick=stop_tab id='last_field'> ... </input>
    
    Is the old way of doing it.
     

Share This Page