Javascript Changing the selected Menu items class - javascript

Assume that I have such menu
<ul id="leftMenu">
<li class="selected">Foo1</li>
<li>Foo2</li>
<li>Foo3</li>
<li>Foo4</li>
<li>Foo5</li>
<li>Foo6</li>
</ul>
Now via javascript, I want to change the highlighted one thus remove the "selected" from the current one and add to the next one
What I need is, first remove the class from the currently selected one, than add to the next.
How can this be achieved?
EDIT: I use this for an embedded system WITHOUT mouse or jquery but remote control and plain javascript so up and down are my only options, no hover allowed :S

Using javascript for this would be an overkill in this day and age.
Since you tagged this css, may I suggest the following CSS-only method, also known as the :hover pseudo-class:
ul#leftMenu li:hover {
color: red;
}

If it were me, and I knew the menus weren't monstrously huge, I'd remove the class from all the <li> elements and then add it to the one I wanted.
var lis = document.getElementById('leftMenu').getElementsByTagName('li');
for (var i = 0; i < lis.length; ++i)
lis[i].className = lis[i].className.replace(/\bselected\b/g, '');
Now, as to how to put the class back, well that depends on how you've found your new favorite <li>. If it's in an event handler, then the event object will refer to it as the "target". You'd thus just append "selected" to the class name.

Related

Accessing a reference to the onclick event from a li a click

This is the first time I’ve thought about moving my events outside of the normal HTML onClick=”” event but I cant seem to find any references as to how I would do this with a li list.
Basically I’m trying to get the number associated with the scrollToArtical(#) in to myElement.onclick. How would you rewrite this so that the event is in the .js file.
I’ve tried variations of to get at the element but these don’t work:
var objScrollToNav = document.getElementById("id_ScrollToNav").children;
var objScrollToNav = document.querySelector("#id_ScrollToNav a");
Any help would be greatly appreciated – CES
My old code is:
<ul id="id_ScrollToNav" role="list">
<li class="sectionNavOff"><a onclick="scrollToArticle(0)" role="link">•</a></li>
<li class="sectionNavOn"><a onclick="scrollToArticle(1)" role="link">•</a></li>
<li class="sectionNavOff"><a onclick="scrollToArticle(2)" role="link">•</a></li>
</ul>
Use document.querySelectorAll to get an array-like list, then loop over them. To keep a reference to the index, make sure you also pass the index into a new closure (the addEvent function below creates a new closure).
function scrollToArticle(index) { console.log("Scrolling to:", index); }
// Select all the elements.
var links = document.querySelectorAll("#id_ScrollToNav a");
// This function adds event listener, and holds a reference to the index.
function addEvent(el, index) {
el.addEventListener("click", function() {
scrollToArticle(index);
});
}
// Loop over the elements.
for (var i = 0; i < links.length; i++) {
addEvent(links[i], i);
}
<ul id="id_ScrollToNav" role="list">
<li class="sectionNavOff"><a role="link">•</a></li>
<li class="sectionNavOn"><a role="link">•</a></li>
<li class="sectionNavOff"><a role="link">•</a></li>
</ul>
Since your li elements can be gathered up into an array and arrays have indexes, you really don't need to pass a hard-coded number to your function. You can just pass the index of the li that is being clicked to the function.
Also, don't use <a> elements when they are not directly navigating you anywhere. This can cause problems for people who use screen readers. Instead, set up the click event directly on the li elements and eliminate the a elements completely.
Lastly, don't use inline HTML event attributes (onclick). That is how we did event handlers 20 years ago and, unfortunately, this technique just won't die. There are many reasons not to use them. Instead, follow modern standards and separate your JavaScript from your HTML.
// Get all the li elements into an array
var items = Array.prototype.slice.call(document.querySelectorAll("#id_ScrollToNav > li"));
// Loop over the list items
items.forEach(function(item, index){
// Assign each item a click event handler that uses the index of the current item
item.addEventListener("click", function(){ scrollToArticle(index) });
});
// Just for testing
function scrollToArticle(articleNumber){
console.log(articleNumber);
}
#id_ScrollToNav > li {
cursor:pointer;
}
<ul id="id_ScrollToNav" role="list">
<li class="sectionNavOff" role="link">•</li>
<li class="sectionNavOn" role="link">•</li>
<li class="sectionNavOff" role="link">•</li>
</ul>
To add to the above, use data- attributes to separate css styles from javascript (meaning, html class tags should be used for html/css things only).
<li data-element="sectionNavOff">
<li data-element="sectionNavOn">
There are some minor downsides to using data- tags, mainly speed, but many enterprise applications and frameworks (e.g. Bootstrap) tend to believe the upside to separating styles from javascript completely outweighs the downsides. If I knew whether or not you use jQuery I could give you a detailed usage example.

Create unique buttons dynamically

I'm new to jQuery and am trying to create jQuery UI buttons dynamically and them to a list. I can create one list item but no more are appended after it. What am I doing wrong?
$('#buttonList').append('<li><button>'+ username + '</button>')
.button()
.data('type', userType)
.click(function(e) { alert($(this).data('type')); })
.append('<button>Edit</button></li>');
<div>
<ul id="buttonList">
</ul>
</div>
This only creates one list item with two buttons (although the second button seems to be encased in the first one, but I can probably figure that issue out). How do I get it to create multiple list items with their own unique 'data' values (i.e. I can't do a find() on a particular button class and give it data values as all buttons would then have the same data)?
I suggest to exchange the position of what you are appending and where you are appending to. This way, you retain the appended object, and should be able to work with it as a standard jQuery selector. From your code i commented out the .button() and the .append() lines, because i'm not sure what you want to do with them. Should you need help adding those lines, just drop a comment to my answer ;)
Oh, i almost forgot: i use var i to simulate different contents for username and userType data.
A JSFiddle for you is here: http://jsfiddle.net/cRjh9/1/
Example code (html part):
<div>
<p id="addButton">add button</p>
<ul id="buttonList">
</ul>
</div>
Example code (js part):
var i = 0;
$('#addButton').on('click', function()
{
$('<li><button class="itemButton">'+ 'username' + i + '</button></li>').appendTo('#buttonList')
//.button()
.find('.itemButton')
.data('type', 'userType'+i)
.click(function(e) { alert($(this).data('type'));
})
//.append('<button>Edit</button></li>')
;
i++;
});
You need complete tags when you wrap any html in a method argument. You can't treat the DOM like a text editor and append a start tag, append some more tags and then append the end tag.
Anything insterted into the DOM has to be complete and valid html.
You are also not understanding the context of what is returned from append(). It is not the element(s) within the arguments it is the element collection you are appending to. You are calling button() on the whole <UL>.
I suggest you get a better understanding of jQuery before trying to chain so many methods together
Just a very simplistic approach that you can modify - FIDDLE.
I haven't added the data attributes, nor the click function (I'm not really sure I like the
inline "click" functions - I generally do them in jQuery and try to figure out how to make
the code efficient. Probably not very rational, but I'm often so).
JS
var names = ['Washington', 'Adams', 'Jefferson', 'Lincoln', 'Roosevelt'];
for( r=0; r < names.length; r++ )
{
$('#buttonList').append('<li><button>'+ names[r] + '</button></li>');
}
$('#buttonList').append('<li><button>Edit</button></li>');

Highlight item in menu that has href="#" option in "a" tag

I want to make menu that will filter list on main page.
For example:
<div id="filters">
Все
Топ-40
Топ-20
Топ-10
</div>
So, the problem is that how I can highlight active item in this menu.
Help me or if there is another aproach to do it, please show.
Thanks for any advices!
You can somewhat achieve this with the :focus state.
#filters a:focus {
color: red;
}
Here is a JSFiddle as a quick example. It isn't perfect though
How do you define "active"?
If you mean the one you are currently hovering over, you can do so by
applying a #filters a:hover rule.
If you mean the currently selected page, you can only do so manually
by adding a class name to the "active" link, or setting the ID / class
of the <body> (that way, you can style multiple things based on the
"current" page).
Update: Here's a way to select links using JavaScript.
<script type="text/javascript">
function select (x)
{
var a = document.getElementById ("filters").getElementsByClassName ("active");
for (var i = 0; i < a.length; ++i)
a[i].className = "";
x.className = "active";
}
</script>
Foo
Baz
Bar
It doesn't seem clear what you actually want to achieve. I seem to understand that you have a menu that changes content on the page, so no page reloads are happening, correct? But it remains not clear to me if the menu filters (shows less or more) content or if it switches content. In the second case, http://jqueryui.com/tabs/ seems to me an easy option (but this is also possible with less code).
Hereby an demo of contents that gets filtered with a menu: http://codecanyon.net/item/jquery-sort-and-order-portfolio-plugin/full_screen_preview/2669205
I hope you can figure it out or can give more information.
More inspiration: http://api.jquery.com/toggleClass/
$("#filters a").click(function () {
$(this).toggleClass("active");
});

How does one determine the number of a list item in an ordered list using JavaScript?

Given an ordered HTML list, is there any way, given the list element, of determining it's number in JavaScript, besides looking at its location in the list?
For example, suppose I have a list
<ol start="4" type="i">
<li>First</li>
<li>Second</li>
</ol>
which is rendered as
iv. First
v. Second
What is the best way using JavaScript (including jQuery) that, given on of the LI, to find out it's number?
The naive way is to look at the item's index, add the start value, and translate the type. But I am wondering if there's a better way.
an example is to add an index property to the list item:
lets say your list has an id='ordered'
var ol = document.getElementById('ordered');
// select the list items
var lists = ol.getElementsByTagName('li');
// now loop through the items and set a custom property 'index'
var l = lists.length; // total items
for (var i=1;i<=l;i++){
list[i].index = i;
}
now your list item will have an index property that you can access through javascript to determine its position.
<ol id='ordered'>
<li index='1'>First</li>
<li index='2'>Second</li>
</ol>
Looking at http://www.w3.org/TR/html-markup/li.html I'd say using the value member.
note: this is in HTML5. in HTML4.01 both ol.start and li.value were deprecated. This means that this solution will probably work reliably only on browsers with HTML5 support.
The MDC documentation for the <li> element mentions the value attribute, which is supposed to do just that. It was deprecated in HTML 4 but has been reintroduced in HTML 5. If your browser supports it, you should be able to write:
$("li").prop("value"); // jQuery 1.6 and higher
$("li").attr("value"); // jQuery 1.5 and lower
I was, however, unable to use that attribute in Firefox 3.6 (it always returns -1). I created a fiddle if you want to test your browser's support for that feature.
Nice questions :)
I would say, better to inject data into each li elements, you could put some HTML attributes inside the li but I am afraid when you do HTML validation, it will reject it.
So this is the code,
var lis = $("ol li").each(function(i, el)
{
$(this).data("index", i);
});
and when you render your lovely number, do this:
$(this).data("index");
:)

JS: Specifying current element in the menu

I have a menu:
<ul>
<li id="active">Головна</li>
<li>Про компанію</li>
<li>Діяльність</li>
<li>Ініціативи</li>
<li>Статті</li>
</ul>
Can you suggest a way to change id=active attribute for this list. If for example I clicked on about, I want this li element to be marked as active.
Thanks
There is an elegant css method of styling the currently active navigation state without any javascript or server side support. Basically one id (e.g. as body id attribute) that uniquely identifies the navigation state is enough to create css selectors that highlight the active state.
Use class, not id. The reason is that id is for identifying elements, which in this case would mean that the only element in the page identified by "active" would be this one, even if you have other contexts needing an "actiuve" distinction. Using class lets you have several "active" elements in different context, and is more semantically correct.
If your menu had an id, let's say "xpto", the onclick of each link could trigger a function like this:
onclick="setActiveId(this);"
functionSetActiveId(newActiveElem){
var allElems = document.getElementById('xpto').childNodes;
for(var i = 0; i < allElems.length; i++){
allElems[i].id = '';
}
newActiveElem.id = 'active';
}
To be correct, you should use class, not id to do this. (See http://css-discuss.incutio.com/?page=ClassesVsIds for more explanation. Basically ids should be unique to the page.)
You can modify the class using jQuery's built in attribute modifying functions:
http://docs.jquery.com/Attributes
Look under "Class"

Categories