Passing dynamically created IDs in slideToggle callback - javascript

I am creating a tree type navigation structure using jQuery. I have a html unordered list where there are categories and sub-lists inside those. When a user clicks a category the list items under that category slideToggle on and off. It works great until a user creates his own category. Then I need to activate the slideToggle method for that new category and sub-category.
The html structure looks something like this:
<ul>
<li> <span id="userCat_1">Cat 1</span>
<ul id="subCat_1>
<li> Button A </li>
<li> Button B </li>
<li> Button C </li>
</ul>
</li>
<li> <span id="userCat_2">Cat 2</span>
<ul id="subCat_2>
<li> Button Z </li>
</ul>
</li>
</ul>
This is my most recent attempt at adding the slideToggle functionality to all "categories" in the list. Here I'm trying to use the objects' IDs (userCat_x and subCat_x) to control the slideToggle.
categoryArray= ["1", "2", "3"]
function activateToggle(){
for (var i=0; i<categoryArray.length; i++){
$("#userCat_" + categoryArray[i]).click(function(i){
$("#subCat_" + categoryArray[i]).slideToggle();
});
}
}
I'm sure im missing some concept. Spent time looking for the answer and this question seemed to move me in the right direction. Toggle worked for new objects but it resulted in toggling other categories not the clicked on categories sub-categories.

You'll probably avoid the whole headache by just using event delegation and a shared class:
$(document).on('click', '.my-menu-class', function() {
$(this).children('ul').slideToggle();
});
<ul>
<li class="my-menu-class"> <span id="userCat_1">Cat 1</span>
<ul id="subCat_1">
<li> Button A </li>
<li> Button B </li>
<li> Button C </li>
</ul>
</li>
<li class="my-menu-class"> <span id="userCat_2">Cat 2</span>
<ul id="subCat_2">
<li> Button Z </li>
</ul>
</li>
</ul>

Related

Add active_section class to section of menu

I've got an html menu as below...
<ul class="menu" id="menu">
<ul class='section' id='section_1'>
<li><span id='section_title_1' class='section_title'><a href='#' id='section_link_1'>Against the odds.</a></span>
<ul>
<li id='exhibit_1' class='exhibit_title'> → Introduction
</li>
<li id='exhibit_2' class='exhibit_title'><a href='../against-the-odds/deriving-functions'> → Deriving functions</a>
</li>
<li id='exhibit_3' class='exhibit_title'><a href='../against-the-odds/exploiting-odds'> → Exploiting odds</a>
</li>
<li id='exhibit_4' class='exhibit_title'><a href='../against-the-odds/betting_history'> → Betting history</a>
</li>
</ul>
</li>
</ul>
<ul class='section' id='section_2'>
<li><span id='section_title_2' class='section_title'><a href='http://themathsproject.co.uk' id='section_link_2'>Remembering everything.</a></span>
<ul>
<li id='exhibit_104' class='exhibit_title'><a href='#'>black swans</a>
</li>
</ul>
</li>
</ul>
<ul class='section' id='section_5'>
<li><span id='section_title_5' class='section_title'><a href='http://themathsproject.co.uk' id='section_link_5'>Running faster.</a></span>
<ul>
<li id='exhibit_107' class='exhibit_title'><a href='#'>possible areas to explore</a>
</li>
<li id='exhibit_108' class='exhibit_title'><a href='#'>developing the model</a>
</li>
<li id='exhibit_109' class='exhibit_title'><a href='#'>performance</a>
</li>
</ul>
</li>
</ul>
<ul class='section' id='section_4'>
<div class='bot'>
<p>twitter
<br />
facebook
</p>
</div>
</ul>
</ul>
It's composed of several "sections" which house links (relevant to the section). Each section has a main title (e.g. Against the odds.) and several sub-sections (which are stored in another ul) like "deriving functions". The subsections are set to display: none by default (I have jQuery which opens the sub-sections if the user wishes to).
The problem:
Once the user clicks on a sub-section link (e.g. www.themathsproject.co.uk/against-the-odds/deriving-functions), I want the sub-section which houses the link (in the case id=section_1) to be open on the page reload so that the user can easily navigate to other links in the section. The other sub-sections would remain closed.
I would like to write a jQuery function which compares the current page url to the links in each section, and, if it finds a match, assign the "active_section" class to the relevant section. Unfortunately, I don't know how to do this.
I've been stuck on this all day and have made little headway.
I would greatly appreciate any help,
Jack
Your post is a little chaotic, so I will try to give you a general tips.
To get last element of your url use
var name = window.href.substr(this.href.lastIndexOf('/') + 1)
Now you can get all your subsections and iterate over them (for example using jQuery):
$('.sub-section').each(function() {
if ($(this).attr('id') === name) {
$(this).addClass('active');
}
});
If your ID's are different than names in url, you can create dictionary to map your equivalents:
var sectionMap = { "section-name-1": "sectionID1" };
And after you get url using first line of code I have provided, you can do:
name = sectionMap[name];

Collapsing nested lists in a hiearchy-structure with jQuery

I have a very annoying problem, which might be a product of my poor knowledge of javascript and jQuery.
I have a list that uses recursion to enable a hierarchy-structure, it looks as follows
$(function (){
$('#foo').click(function() {
$(this).children('ul').slideToggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id='foo'>A
<ul>
<li id='foo'>B
<ul>
<li>
Sub-sub
</li>
</ul>
</li>
</ul>
</li>
</ul>
I'm trying to accomplish a collapse function, so that when the user clicks on 'A' all the children elements collapses, and if she clicks the 'B' node all of 'B's children collapses. But however I try I always end up having all of the lists with id = 'foo' collapsing.
In my eyes, $(this).children('ul').slideToggle(); will collapse the children, since $(this) points to the list element clicked...?
Been at this for far to long now, would love some help!
Here you go... No change in HTML. But like other suggested, you need to have unique ID's
$(function (){
$('li').click(function(event) {
event.stopPropagation();
$(event.target).children('ul').slideToggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li id='foo'>A
<ul>
<li id='foo'>B
<ul>
<li>
Sub-sub
</li>
</ul>
</li>
</ul>
</li>
</ul>

on click 'toggle' firing all classes with the name instead of the one clicked

I am currently having a fairly classic problem in jquery. When a class is clicked (within a ul) all elements with that class name are being toggled. I really only want the the elements to toggle to be the the element that is click, here is some of my code:
js:
$(function(){
var list = $('.lists');
list.on({
'click': function(){
$('.list-display').toggle('slow');
}
});
});
html:
<ul class ='lists'>
<li> Soccer
<ul class='list-display'>
<li> Kick </li>
<li> Dribble </li>
<li> Pass </li>
</ul>
</li>
<li> Basketball </li>
<ul class='list-display'>
<li> Shoot </li>
<li> Dribble </li>
<li> Pass </li>
</ul>
<li> Baseball </li>
<ul class='list-display'>
<li> Catch </li>
<li> Throw </li>
<li> Hit </li>
</ul>
</ul>
When I click any li in the main ul (Soccer, Basketball, Baseball) all of the uls embedded in their category toggle. I only want the one clicked to toggle. How can I re arrange my function to only toggle the one clicked? I imagine I have to use the 'this' keyword but am unfamiliar with using it.
Try
list.on({
'click': function(){
$('.list-display', this).toggle('slow');
}});
I looks for .list-display items inside the currently clicked element.
Use this (Example):
$('.lists').on('click', 'li', function(){
$('ul.list-display', this).toggle('slow');
});
Also, you have wrong HTML, use something like this:
<ul class ='lists'>
<li> Soccer
<ul class='list-display'>
<li> Kick </li>
</ul>
</li>
<li> Basketball
<ul class='list-display'>
<li> Shoot </li>
</ul>
</li>
</ul>
You didn't put all uls inside li, you have two uls like this:
<li> Basketball</li>
<ul class='list-display'>
<li>...</li>
</ul>
<li> Baseball</li>
<ul class='list-display'>
<li>...</li>
</ul>

How to add class dynamically using ajax.?

When i click on any name I have to add class "active" for selected name's anchor tag and as well as department names of that user.
<ul id="orglistingid">
<li>
<a>Sales </a> <!--Deparemtn Name -->
<ul id="dId">
<li>
<a>Rahul </a> <!--User -->
</li>
<li>
<a>Nitin </a>
</li>
</ul>
</li>
</ul>
<ul id="orglistingid">
<li>
<a class="active">Development</a>
<ul>
<li id="dId">
<a class="active">Rokesh </a>
</li>
<li>
<a>Preeti</a>
</li>
</ul>
</li>
</ul>
I am using below code, can anyone tell what correction i need to do..?
if (orgID != null && orgID == 'dId') {
$("#dId li a").removeClass("orglistactive");
$(this).attr("class","orglistactive");
var parentID = $(e.target).parent().parent().parent().attr("id");
alert($(e.target).parent().parent().parent().attr("id"));
$("#"+parentID+" a").attr("class","orglistactive");
}
Looks like you are trying to achieve something as shown below:
<script type="text/javascript">
var orgID = $('#dId');
if(orgID.attr('id') == 'dId'){
orgID.find('>li>a').addClass("orglistactive");
var parentID = orgID.attr("id");
alert(orgID.attr("id"));
}
</script>
But couple of things are found, are not correct from html and jquery perspective.
Id are unique but you have used 'dId' for more than one time.
e.target works only when there is an event attached with an element or can be captured using "window.event || e". In your code I could not see the purpose of e.target
Hope this helps! :)
This can be quickly achieved with a little of jQuery.
First Approach
$('ul a').click(function(){
$(this).addClass('orglistactive');
$(this).parent().parent().parent().find('a:first').addClass('orglistactive');
});
Take a look at a live demo: http://jsfiddle.net/augusto1982/6xM2P/
Second Approach
One thing to keep in mind is that this code works ok if there's no other list in the page. If this is not the case, you should use some CSS class to determine the object to bind the click function. Otherwise, the jQuery selector gets a bit messy.
$('#orglistingid li ul li a').click(function(){
$(this).addClass('orglistactive');
$(this).parent().parent().parent().find('a:first').addClass('orglistactive');
});
Example: http://jsfiddle.net/augusto1982/GXcvD/
Third Approach
I would also recommend you to add a class to each user anchor, to make it easier.
HTML
<ul id="orglistingid">
<li>
<a>Sales </a> <!--Deparemtn Name -->
<ul id="dId">
<li>
<a class='user'>Rahul </a> <!--User -->
</li>
<li>
<a class='user'>Nitin </a>
</li>
</ul>
</li>
</ul>
<ul id="orglistingid">
<li>
<a class="active">Development</a>
<ul>
<li id="dId">
<a class="active user">Rokesh </a>
</li>
<li>
<a class='user'>Preeti</a>
</li>
</ul>
</li>
</ul>
jQuery
$('.user').click(function(){
$(this).addClass('orglistactive');
$(this).parent().parent().parent().find('a:first').addClass('orglistactive');
});
Take a look at this second example: http://jsfiddle.net/augusto1982/GW4mt/
Final Approach
In order to avoid all the parent()...parent() calls, you could use the closest method, but you need to change your HTML a bit.
HTML
<ul id="orglistingid">
<li class='department'>
<a>Sales </a> <!--Deparemtn Name -->
<ul id="dId">
<li>
<a class='user'>Rahul </a> <!--User -->
</li>
<li>
<a class='user'>Nitin </a>
</li>
</ul>
</li>
</ul>
<ul id="orglistingid">
<li class='department'>
<a class="active">Development</a>
<ul>
<li id="dId">
<a class="active user">Rokesh </a>
</li>
<li>
<a class='user'>Preeti</a>
</li>
</ul>
</li>
</ul>
jQuery
$('.user').click(function(){
$(this).addClass('orglistactive');
$(this).closest('.department').find('a:first').addClass('orglistactive');
});
Demo: http://jsfiddle.net/augusto1982/e7PVF/
Like other comments, I'd recommend you to have unique IDs. While this is not a restriction, is a best practice.

If element has children html elements

I the following un-ordered list.
<ul>
<li>
<a class="hlink hlink-1" href="#"> Prank Boss Apps </a>
<ul>
<li> link 1 </li>
<li> link 2 </li>
<li> link 3 </li>
</ul>
</li>
<li>
<a class="hlink hlink-2" href="#"> Uninstall an app. </a>
</li>
<li>
<a class="hlink hlink-3" href="#"> Contact Us </a>
</li>
</ul>
In the un-ordered list, not every list-item will have another un-ordered list.
<li> blah
<ul>
<li> link 1 </li>
<li> link 2 </li>
<li> link 3 </li>
</ul>
</li>
So some will just have a link inside of the list item and others will have a un-ordered list inside.
How can I check if the list item doesn't have another un-ordered list inside of it?
function hasChildULs(thisList)
{
if ($(thisList).children('ul').length > 0)
{
return true;
}
else
{
return false;
}
}
Once you've got a reference to the li element you can use this.
function isLeafNode(liElement) {
return !liElement.getElementsByTagName("ul").length;
}
This should get you started: http://www.w3schools.com/dom/dom_element.asp (if you don't want to use jQuery)

Categories

Resources