Setting a class for selected list <li>

I m creating a form.

It contains a table with 2 columns.

The first column contains the list<li> of the names of the categories.

Depending on the category clicked in the first column, the second column is populated (im using ajax(get) here).

Now the first column is a list. I want to create a class for the clicked category.
Say, there are 5 categories listed in the first column. And the user clicks on the 3rd category. Here i want to create a class so that i can give a background image for the selected category(3rd).

I will set the background image in css. But how do i set a class for the selected item from the list ??

Please help.

Thanks.

post the code you have so far.

I dont know how to set a class automatically for the selected item from the list … i dont have the code.

I need help with the code.

Here are the standard class handling functions


function hasClass(ele,cls) {
	return ele.className.match(new RegExp('(\\\\s|^)'+cls+'(\\\\s|$)'));
}
 
function addClass(ele,cls) {
	if (!this.hasClass(ele,cls)) ele.className += " "+cls;
}
 
function removeClass(ele,cls) {
	if (hasClass(ele,cls)) {
    	var reg = new RegExp('(\\\\s|^)'+cls+'(\\\\s|$)');
		ele.className=ele.className.replace(reg,' ');
	}
}

So you can do things like:


for (i = 0; i < els.length; i += 1) {
    removeClass(els[i], 'active');
}
addClass(selected, 'active');

Thanks for your reply pmw57 !

Im sorry fr being so stupid, but i did nt get it.

I did nt undrstnd whr exactly do i add a function to add class. I already have a function for the items of the list. The function is “showUser”.

This is my list :


 <ul>
       <li> <a href="#" id="1" onclick="showUser(this.id)" > cat 1</a> </li>
       <li> <a href="#" id="2" onclick="showUser(this.id)" > cat 2</a> </li>
       <li> <a href="#" id="3" onclick="showUser(this.id)" > cat 3</a> </li>
       <li> <a href="#" id="4" onclick="showUser(this.id)" > cat 4</a> </li>
       <li> <a href="#" id="4" onclick="showUser(this.id)" > cat 5</a> </li>
     </ul>

And my function :



function showUser(str)
{
if (str=="")
  {
  document.getElementById("subcat").innerHTML="";
  return;
  }
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("subcat").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","getcats.php?q="+str,true);
xmlhttp.send();
}


Please help.

Thank you.

Before you can be helped, your HTML code needs to be consistent.


<ul>
       <li> <a href="#" id="1" onclick="showUser(this.id)" > Electronics</a> </li>
       <li> <a href="#" id="2" onclick="showUser(this.id)" > Jobs</a> </li>
       <li> <a href="#" id="3"onclick="showUser(this.value)" > Real Estate</a> </li>
       <li> <a href="#" id="4"onclick="showUser(this.value)" > Matrimony</a> </li>
       <li id="5"> <a href="#" onclick="showUser(this.value)" > Pets</a> </li>
     </ul>

Problems:

[list][]inconsistant attribute spacing
[
]this.id or this.value? Why are they different?
[*]id is placed on different elements
[/list]

I changed that.

It was my old code. I apologize for it. I corrected code :


 <ul>
       <li> <a href="#" id="1" onclick="showUser(this.id)" > cat 1</a> </li>
       <li> <a href="#" id="2" onclick="showUser(this.id)" > cat 2</a> </li>
       <li> <a href="#" id="3" onclick="showUser(this.id)" > cat 3</a> </li>
       <li> <a href="#" id="4" onclick="showUser(this.id)" > cat 4</a> </li>
       <li> <a href="#" id="4" onclick="showUser(this.id)" > cat 5</a> </li>
     </ul>

Thank you.

Be sure to also fix the last id, from 4 to 5.

The showUser function can call another function that we create, called showActive.
Currently the showUser functionreceived the id attribute as the str variable, so we need to pass that on to showActive


showActive(str);

The showActive function will accept the id attribute, and from there it will remove the active class from all other ones, and set the selected one as active.


function showActive(id) {

}

Question: What are you going to add the class name to? To the LI element or the A element?

Thanks for the reply pmw57 !!

Question: What are you going to add the class name to? To the LI element or the A element?

What do u suggest? I think adding the class to <li> would be good

I want to add a background image for the selected item from the list.
The second div is where i fetch the subcats to.

I m sorry, but i still dont get the solution.

My code for function showUser() is :


function showUser(str)
{
if (str=="")
  {
  document.getElementById("subcat").innerHTML="";
  return;
  }
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("subcat").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","getcats.php?q="+str,true);
xmlhttp.send();
}

 

You suggested to create a function showActive(str);

I dont know where i include this function in the showUser() function.

Thank you.

Okay, the LI element it is.

The start of the showUser function is a good place to put it.


function showUser(str) {
    showActive(str);
    ...
}

Now to prepare for the showActive function:

The first thing you’ll need to do is to remove the “active” class from all of the list items. Why? Consider this scenario. The third item is currently active, then someone selects the last item. How is the scripting to know to remove the class from the third item?

The script doesn’t know which one was active previously, and solutions such as using getElementsByClassName are very unweildy due to requiring compatibility code for web browsers such as IE that don’t support it. The best solution is to remove the class from all of the items.

So, we need to put together a list of all list items. To get that list we can go up the parent elements from the clicked link, until we reach a UL element. To help prevent any scripting error, if we get to the BODY element we’ll stop processing things.

Once we get to the UL element, from there we can get all of the LI tag names, and then we can remove the active class from them. But first, don’t forget to also include the class handling functions


function hasClass(ele,cls) {
	return ele.className.match(new RegExp('(\\\\s|^)'+cls+'(\\\\s|$)'));
}
 
function addClass(ele,cls) {
	if (!this.hasClass(ele,cls)) ele.className += " "+cls;
}
 
function removeClass(ele,cls) {
	if (hasClass(ele,cls)) {
    	var reg = new RegExp('(\\\\s|^)'+cls+'(\\\\s|$)');
		ele.className=ele.className.replace(reg,' ');
	}
}

Now to get the list items, which is my next post.

Did you fix Cat 5 so that it’s id=“5” yet?

Yes i fixed it.

Its id=“5” now.

Many thanks.

Awaiting …

Okay, first you find the UL element. If it walks on up to the BODY without finding a UL element, it just returns out. No harm no foul.


function showActive(id) {
    var el = document.getElementById(id);
    while (el.nodeName !== 'UL' && el.nodeName !== 'BODY') {
        el = el.parentNode;
    }
    if (el.nodeName === 'BODY') {
        return;
    }
    ...
}

Then, you get all of the LI elements from that UL element. Loop through them and remove the “active” class name. And finally add the “active” class name to the LI of the clicked link.


...
items = el.getElementsByTagName('li');
for (i = 0; i < items.length; i += 1) {
    removeClass(items[i], 'active');
}
addClass(li, 'active');

Here it is all put together:


function showActive(id) {
    var el = document.getElementById(id),
        li = el.parentNode,
        items,
        i;
    while (el.nodeName !== 'UL' && el.nodeName !== 'BODY') {
        el = el.parentNode;
    }
    if (el.nodeName === 'BODY') {
        return;
    }
    items = el.getElementsByTagName('li');
    for (i = 0; i < items.length; i += 1) {
        removeClass(items[i], 'active');
    }
    addClass(li, 'active');
}

Then you can use something like this CSS to target the active item:


li.active {
    background: lightgreen;
}

Did not work.

Its me. Im doing a basic error somewhere.

If i understand u properly, :

I listed the categories :


<div class="categories" id="categories">
     <ul>
       <li> <a href="#" id="1" onclick="showUser(this.id)" > Cat1</a> </li>
       <li> <a href="#" id="2" onclick="showUser(this.id)" > Cat2</a> </li>
       <li> <a href="#" id="3"onclick="showUser(this.id)" > Cat3</a> </li>
       <li> <a href="#" id="4"onclick="showUser(this.id)" > Cat4</a> </li>
       <li> <a href="#" id="5"onclick="showUser(this.id)" > Cat5</a> </li>
     </ul>
</div>

Now my showUser function :


function hasClass(ele,cls) {
    return ele.className.match(new RegExp('(\\\\s|^)'+cls+'(\\\\s|$)'));
}

function addClass(ele,cls) {
    if (!this.hasClass(ele,cls)) ele.className += " "+cls;
}

function removeClass(ele,cls) {
    if (hasClass(ele,cls)) {
        var reg = new RegExp('(\\\\s|^)'+cls+'(\\\\s|$)');
        ele.className=ele.className.replace(reg,' ');
    }
}

function showUser(str)
{
function showActive(id) {
    var el = document.getElementById(id),
        li = el.parentNode,
        items,
        i;
    while (el.nodeName !== 'UL' && el.nodeName !== 'BODY') {
        el = el.parentNode;
    }
    if (el.nodeName === 'BODY') {
        return;
    }
    items = el.getElementsByTagName('li');
    for (i = 0; i < items.length; i += 1) {
        removeClass(items[i], 'active');
    }
    addClass(li, 'active');
}

if (str=="")
  {
  document.getElementById("subcat").innerHTML="";
  return;
  }
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("subcat").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","getcats.php?q="+str,true);
xmlhttp.send();
}



Is this how its supposed to be?
I just dnt understand where to include the showActive(id) function and how to call it when a category from the list is selected.

I apologize mate, kindly bear with me.
thank you.

This is your problem:


function showUser(str) {
function showActive(id) {
    ...
}
...
}

It should be instead:


function showActive(id) {
    ...
}

function showUser(str) {
    showActive(str);
    ...
}

You are a star!

Thanks a million for all the help.

It works absolutely how i want it to. I will study it properly now.

Thanks a lot. :beer: :beer: :beer:

God Bless You pmw57!!

how to add background color to the selected item from the select list and also add a image ?? i also want to populate some items depending on the selected item.

will u help me too?

You can use something like this CSS to target the active item:


li.active {
    background: lightgreen url(/images/image.png);
}

That’s a very different topic from this thread. You’ll be best to start a new thread about it.