How to Tab List Items Cyclically - javascript

I am trying to make tabbing cyclical within a dropdown menu.
Here's my JSFiddle: https://jsfiddle.net/Lc7saks3/
<nav id="primary_nav_wrap">
<div>
<ul>
<li tabindex="0">Menu
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
<li>Option 5</li>
</ul>
</li>
</ul>
</div>
<br />
<br />
<input type="text" />
</nav>
Click on the Menu element and then tab through the options.
Currently, the tabbing goes through the 5 options within the dropdown menu and then moves on to the input element.
How can I make it such that the dropdown options are tabbed again,
cyclically, from option 1, once the last option (option 5) is reached?

You would need to use script listen for the Tab key while on the last item and, when pressed, immediately move focus back to the first item (or dynamically adjust tabindex values when you get to the last item).
However, DO NOT DO THIS as it constitutes a keyboard trap and is a failure of WCAG 2.0 item 2.1.2, No Keyboard Trap. There is a lengthy technique for handling this that essentially says to not do what you are trying to do: G21: Ensuring that users are not trapped in content
Finally, I suggest you take the tabindex off the li as that is not an interactive / actionable control and no place for a tabindex.

Related

How do I move item from 1 list to another list in HTML

Hi, I'm trying to implement something like this where the user can click on an item and move it from left to right div or list and vice versa (refer to attached image). The list of items needs to be tracked so I'm able to use javascript to do some processing. I saw some websites done this before but not sure what this is called, is there any terminology for this? I'm don't really know what to search on google so I'm a bit stuck currently. Greatly appreciated it if anyone can help with this, thanks.
You can add a click event listener to both lists that appends the event target to the other list and deletes the event target.
row1.addEventListener('click', function(e){
if(e.target != this){
row2.appendChild(e.target.cloneNode(true));
e.target.remove()
}
})
row2.addEventListener('click', function(e){
if(e.target != this){
row1.appendChild(e.target.cloneNode(true));
e.target.remove()
}
})
.row {
display: flex;
}
<div class="row">
<ul id="row1">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<ul id="row2">
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</div>
There is no real formal name dedicated for this, but you can find many things resembling what you are looking for with 'multi list', 'multi select list' and 'multi select box'. Angular Material also has a CDK for this called 'droplist', but they seem to be the only one really using the term.

Aligning two elements with javascript

I have two elements, a <button> and a <ul>. There are multiple of the button, and they all do the same thing. When you click a button, I want to move the ul to the button (aligned at the top right). The buttons don't have IDs.
The menu (UL) will be absolute positioned. They are not siblings/parents/children of each other. When you click the button, it calls a function. I hope this function can move the UL to the location of the button that you clicked.
HTML:
<button class="download" onclick="showDownloadMenu()"><i class="fa fa-download" aria-hidden="true"></i></button>
<ul id="download-menu">
<h1>Downloads</h1>
<button id="download-close-button" onclick="hideDownloadMenu()"><i class="fa fa-times" aria-hidden="true"></i></button>
<li>option 1</li>
<li>option 2</li>
<li>option 3</li>
<li>option 4</li>
<li>option 5</li>
</ul>
JavaScript:
option 1 - this makes sense in my head... the right side of the menu equals the right side of the button..
downloadMenu.right = (clickedButton.right)+'px';
kind of works on buttons on the left...
but the buttons on the right go even further left, something is definitely wrong
option 2 - closest to working but instead of the right side of the menu aligning with the right side of the button, the left side of the menu is. these at least are consistant, but it's not in the right place.
downloadMenu.left = (clickedButton.right)+'px';
option 3 - not sure, but it was the last thing to try
downloadMenu.left = (clickedButton.left)+'px';
once again this is consistant, and even closer, but now the left side of the button and the left side of the menu are aligned.
so you'd think making it right/right would do the opposite, but as seen above thats not the case.
I did a quick fiddle, hope that is what you meant.
$('button').click(function(){
$('ul').insertAfter($(this))
})
button {display: block; margin-top: 20px;}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<button>one</button>
<button>two</button>
<button>three</button>
<button>four</button>
<ul>
<li>xxx</li>
</ul>

Jquery show next and hide prev issue

Trying to hide the previous element and then show the next element however the code is not working. It needs to be that every .quiz-group show the next but also hide the previous when the more button is clicked.
Code is:
x=1;
$('.quiz-group:lt('+x+')').show();
$('.more').click(function(e) {
e.preventDefault();
x= (x+3 <= quiz_groups) ? x+3 : quiz_groups;
$('.quiz-group:lt('+x+')').slideDown();
$('.quiz-group').not(':lt('+x+')').slideUp();
$('.back').show();
});
HTML is:
<div class="quiz-group">
<ul class="question-single">
<li>
<p>text?</p>
<ul class="answer">
<li>Answer 1</li>
<li>Answer 2</li>
<li>Answer 3</li>
</ul>
</li>
</ul>
</div>
The code iterates through each third question and adds the quiz-group div wrapper.
Currently it appends the quiz group to the existing (not hiding the previous one).
Thanks

Keep div entirely within viewport

As the title, I need to create an html tag and if the tag is hidden by the edge of the browser, it will automatically show back on the opposite side to no longer be hidden by the other. For example, it's like the options of facebook status:
http://i.imgur.com/RR8poBf.png
Because I don't know how to explain it to everybody to understand, so I had captured a photo here: http://i.imgur.com/SwpePxp.png
This is html content:
<div class="status-options">
<span class="status-options-list btn btn-default glyphicon glyphicon-chevron-down"></span>
<ul class="u-1">
<li>Option 1 aaaaaaaaaaaaaaaa</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
</div>
Any suggestions for a workaround?

Avoid reflow of css3 columns after they have been drawn

I am using css3 columns to display an unordered list in 3 columns. The list items contain lists as well that can be shown or hidden by clicking on the title using jQuery.
The html looks like (with class names to describe the layout and interactions):
<ul class="i-display-in-3-columns">
<li>
<h3 class="slide-toggle-sibling-list-on-click">column title 1</h3>
<ul class="i-am-initially-hidden">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
<li>
<h3 class="slide-toggle-sibling-list-on-click">column title 2.</h3>
<p>This can be very long with perhaps an additional paragraph as well.</p>
<ul class="i-am-initially-hidden">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</li>
/* some more items */
</ul>
This works, but every time a sub-list is opened or closed, the columns get redrawn.
I would like to freeze the columns after they have initially been drawn to avoid this reflow so that every item stays in the column it is initially drawn in.
I can of course write a masonry-like solution in javascript to convert my list in 3 lists that are displayed next to each other, but I was hoping that there was an easier solution, preferably in just css or in javascript that keeps my list as a list.
Is that possible or would I just have to rewrite the DOM?
I don't think you can achieve that with CSS columns. There is the option to toggle visibility instead of display of the child lists, but I'm assuming you don't want that.
Another possible CSS solution is using the flexbox module (and deal with the browser support issues). For example, I believe this might be what you want (working on Chrome 29):
.i-display-in-3-columns {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.i-display-in-3-columns>li {
flex: 1 1 200px; /* 200px is the column width */
}
Demo

Categories

Resources