jQuery target next() html item - javascript

hi I have a list of items which is generated like so:
<li class="panel-title">Item 1<i class="fa pull-right fa-plus"></i></li>
<ul class="panel-body">...</ul>
<li class="panel-title">Item 2<i class="fa pull-right fa-plus"></i></li>
<ul class="panel-body">...</ul>
<li class="panel-title">Item 3<i class="fa pull-right fa-plus"></i></li>
<ul class="panel-body">...</ul>
Upon clicking an 'li' item I need only the next 'ul' to expand. Unsure how to solve this & whether next() is the right action
Heres my code
$('li.panel-title > .fa').on("click",function() {
var $currIcon = $(this);
var $contents = $('ul.panel-body');
if($currIcon.hasClass('fa-plus')) {
$currIcon.$contents.next().slideDown();
$currIcon.removeClass('fa-plus');
$currIcon.addClass('fa-minus');
} else if($currIcon.hasClass('fa-minus')) {
$currIcon.$contents.next().slideUp();
$currIcon.removeClass('fa-minus');
$currIcon.addClass('fa-plus');
}
});

Try this
$('li.panel-title > .fa').on("click",function() {
var $currIcon = $(this);
var $contents = $('ul.panel-body');
if($currIcon.hasClass('fa-plus')) {
$currIcon.parent().next().slideDown();
$currIcon.removeClass('fa-plus');
$currIcon.addClass('fa-minus');
} else if($currIcon.hasClass('fa-minus')) {
$currIcon.parent().next().slideUp();
$currIcon.removeClass('fa-minus');
$currIcon.addClass('fa-plus');
}
});

Below is jQuery Code:
$('li.panel-title > .fa').on("click", function() {
var $currIcon = $(this);
var $contents = $($(this).closest('li').next().children('ul'));
if ($currIcon.hasClass('fa-plus')) {
$contents.slideDown();
$currIcon.removeClass('fa-plus');
$currIcon.addClass('fa-minus');
} else if ($currIcon.hasClass('fa-minus')) {
$contents.slideUp();
$currIcon.removeClass('fa-minus');
$currIcon.addClass('fa-plus');
}
});
I appended a codepen. I modified HTML markup a little bit, since ul is directly beneath its parent node ul.
http://codepen.io/wooljs/pen/pEgbkB

Related

Compare tag text value with a variable in jquery

I'm trying to compare the value of a tag obtained by query selector in the DOM with a given variable.
So far I've only managed the use of "contains" function, but I need to compare with an equality function.
The DOM element I need to obtain is "span:badge" and the variable to compare is "current_id".
This is the code I need to change:
var $a = $('span.badge:contains("' + current_id + '")').closest('a');
JS:
$(document).ready(function() {
"use strict";
var current_id = window.location.pathname.replace('/califications/','');
if (Number.isInteger(parseInt(current_id, 10))){
var $a = $('span.badge:contains("' + current_id + '")').closest('a');
$($a).addClass('active');
}else{
$('#middle_column > div > h1').html("No kid selected");
}
});
HTML:
<ul class="nav nav-pills flex-column" id="kid_list">
<t t-foreach="kids" t-as="kid">
<li class="nav-item">
<a t-attf-href="/califications/{{kid.id}}" t-attf-class="nav-link"><t t-esc="kid.name"/>
<span class="badge badge-pill float-right" style="display: none;"><t t-esc="kid.id" /></span>
</a>
</li>
</t>
</ul>
Thanks for reading!
To use contains seems right, but you need to do further, because contains also matches aa and ab if you search for a.
const $badges = $('span.badge:contains(`${current_id}`)');
const targetEl = null
$badges.each((i, e)=>{
if(e.text() === current_id){
targetEl = e.
}
})
targetEl should be what you need, or you will also do targetEl.closet("a") if you want to get the a.
You can use the selector which contains t-attf-href attribute ends with the id
$(`[t-attf-href$="${current_id}"]`).addClass('active');
Example:
var id = 'kid_id';
$(`[t-attf-href$="${id}"]`).addClass('active').text('test');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a t-attf-href="/califications/kid_id" t-attf-class="nav-link"><t t-esc="kid.name"/>
<span class="badge badge-pill float-right" style="display: none;"><t t-esc="kid.id" /></span>
</a>
Note: The .text('test') part is just for testing
Solution of the problem found.
var current_id = window.location.pathname.replace('/califications/','');
if (Number.isInteger(parseInt(current_id, 10))){
var $b = $('span.badge');
$b.each(function( index ) {
var badge_value = $( this ).text();
if (badge_value == current_id){
var active_a = $( this ).closest('a');
$(active_a).addClass('active');
}
});
}else{
$('#middle_column > div > h1').html("No kid selected");
}
Thanks for all the responses!

How to make links added from JSON clickable?

I am trying to append links from a JSON file but their onClick is not working.
HTML:
<li class="nav-item dropdown" id = "views">
<a class="nav-link dropdown-toggle" id="view-type" data-toggle="dropdown" data-selected="high_level" aria-haspopup="true" aria-expanded="false">High Level View</a>
<div class="dropdown-menu" aria-labelledby="view-type" style="height: 35vh; overflow: auto;">
<h7 class="dropdown-header">View Type</h7>
<a class="dropdown-item filter-option active" href="javascript:void(0);" id="high_level">High Level View</a>
</div>
</li>
Javascript:
d3.json(theURL, function(error, data) {
if (error) throw error;
var unique = [];
data.forEach(function(e){
if(unique.indexOf(e.segment) == -1){
unique.push(e.segment);
}
});
unique.forEach(d =>
$('#views .dropdown-menu').append(`<a class="dropdown-item filter-option ecodes" href="javascript:void(0);" id="${d.substring(0, 4)}">${d}</a>`)
)
if($('#all').hasClass('active') == true) {
$('.ecodes').remove();
}
});
$('.filter-option').on('click', function() {
let text = $(this).text();
let selected = $(this).prop('id');
$(this).parent().parent().children('a').text(text);
$(this).parent().parent().children('a').data().selected = selected;
filters[$(this).parent().parent().children('a').prop('id').replace('-','_')] = selected;
$.each($(this).parent().children('a'), function(i,d)
$(d).removeClass('active'); });
$(this).addClass('active');
});
Is there something wrong with my code? I cant seem to figure out why my links aren't working. I need onClick for them to have the class active.
You should use the static element as a starter then delegating the dynamic node(child node) inside the on method
$('dropdown-menu').on('click','.filter-option', function() {
let text = $(this).text();
let selected = $(this).prop('id');
$(this).parent().parent().children('a').text(text);
$(this).parent().parent().children('a').data().selected = selected;
filters[$(this).parent().parent().children('a').prop('id').replace('-','_')] = selected;
$.each($(this).parent().children('a'), function(i,d)
$(d).removeClass('active'); });
$(this).addClass('active');
});
You have to delegate the click to the parent element that exists in the page before you inject new links.
jQuery's on method accepts a selector as the second argument so you can update the following line:
$('.dropdown-menu').on('click', '.filter-option', function() {
let text = $(this).text();
let selected = $(this).prop('id');
$(this).parent().parent().children('a').text(text);
$(this).parent().parent().children('a').data().selected = selected;
filters[$(this).parent().parent().children('a').prop('id').replace('-','_')] = selected;
$.each($(this).parent().children('a'), function(i,d)
$(d).removeClass('active'); });
$(this).addClass('active');
});
Read more: http://api.jquery.com/on/#direct-and-delegated-events

Apply toggle function to only clicked element using pure java script

This is my html code where i'm displaying data
<ul id="menu">
<li *ngFor="let category of componentContents.dashboardMenu;let i = index" >
<p (click)="toggle_visibility()"class="parent-menu">{{category.category}</p>
<ul id="{{(category.category).split(' ').join('-')}}" class="toggled"
*ngIf="category.subCategory.length > 0" style="display:none">
<li *ngFor="let subCat of category.subCategory">
<a routerLink={{subCat.router}} routerLinkActive="active"
{{subCat.subcategory}}</a>
</li>
</ul>
</li>
This is the function where i'm trying to display sub menus on click but all the sub menus of all p tags are getting displayed.I want to apply toggle function to only clicked p element.
toggle_visibility() {
var pm = document.getElementByClassName('parent-menu');
var e = document.getElementsByClassName('toggled');
for (let i = 0; i < pm.length; i++) {
if (e[i].style.display == 'block' || (e[i].style.display == '') {
e[i].style.display = 'none';
}
else {
e[i].style.display = 'block';
}
};
}
As i'm new to java script and angular 2. Need help to figure this out.
You should rather use
[style.display]="e[i].style.display == '' ? 'none' : 'block'"
(click)="toggle_visibility(i)"
toggle_visibility(i) {
this.e[i] = !this.e[i];
}
where e is an array with the same number of items as
componentContents.dashboardMenu

jQuery detect if document contains an id matching the href of a link

I've written a function that adds hrefs to an alphabetical navigation bar. I made it so each letter section gives itself an ID. I want to make it so in the event there isn't for example a "C" section, I could add a class to the link linking to #c that would disable it. Here's what I have so far:
<ul class="no-bullet inline">
<li><a class="scroller"><strong>A</strong></a></li>
<li><a class="scroller"><strong>B</strong></a></li>
<li><a class="scroller"><strong>C</strong></a></li>
</ul>
<div class="space-above space-below letter-section">
<h4 class="alpha-heading"><strong>A</strong></h4>
<ul class="no-bullet">
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
</ul>
</div>
<div class="space-above space-below letter-section">
<h4 class="alpha-heading"><strong>A</strong></h4>
<ul class="no-bullet">
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
</ul>
</div>
<script>
function alphaLink() {
var alphaLink = $(this);
var alphaLinkRef = "#" + alphaLink.text().toLowerCase();
$(alphaLink).attr("href", alphaLinkRef);
};
$('.scroller').each(alphaLink);
//assigns each content section an ID
function alphaID() {
var section = $(this);
var sectionID = section.text().toLowerCase();
$(section).attr("ID", sectionID);
};
$('.alpha-heading').each(alphaID);
linkMatch function(){
var link = $(this);
if(link.length <= 0) {
$(this).addclass("disabled");
}
$("scroller").each(linkMatch);
</script>
If the HREF is something like '#C', take a look at this:
$(document).ready(function(){
$('a').each(function(i,e){
var href = $(this).attr('href')
if(!findID(href)){
// Doesn't exist
$(this).addClass('disabled');
}
})
function findID(ID){
var exists = false;
if($(ID).length > 0){
exists = true;
}
return exists;
}
})
Hope this helps!
UPDATED! Sorry I overlooked that you wanted to disable the link, not on click. Here is a JsFiddle if you inspect the link with href="$find-someting-else" you'll see it has the class disabled whereas the other one does not.
I took Jeremiah's code and altered it slightly to do what I needed it to do. Thanks so much for all the answers- here was the final product:
function findID(ID) {
var exists = false;
if ($(ID).length > 0) {
exists = true;
}
return exists;
}
function matchLink() {
var href = $(this).attr('href');
if (!findID(href)) {
// Doesn't exist
$(this).addClass('alpha-disabled');
}
};
$('.scroller').each(matchLink);
You can do it like this. Here is an example:
function linkMatch(index, elem){
var link = elem,
heading = $(".alpha-heading");
var linkHref = link.attr("href").substring(1, link.attr("href").length);
if(typeof(heading[index]) != "undefined") {
if(linkHref != heading[index].getAttribute("id")) {
link.addClass("disabled");
}
}
}
$(".scroller").each(function(index) {
linkMatch(index, $(this));
});
Edit
I've just edited my code, because I forgot to write length inside linkHref variable

Jquery click function trigger load more button

below i have 3 links as an tabs:
<li data-tab-id="self" class="tab selected">Near You<span class="unread-count hidden" style="display: none;"></span></li>
<li data-tab-id="friends" class="tab">Following<span class="unread-count hidden" style="display: none;"></span></li>
<li data-tab-id="user" class="tab">Your Activity<span class="unread-count hidden" style="display: none;"></span></li>
when i click the above link Jquery click function are triggered
$(".hd-ui-activity li a").click(function(e) {
e.preventDefault();
var tabid = $(this).parent().attr('data-tab-id');
if(tabid == "self"){
getFunc1(totalRecords);
} else if(tabid == "friends") {
getFunc2(totalFriendsRecords);
} else if(tabid == "user") {
getFunc3(totalUserRecords);
}
});
When each of the links/tabs are clicked the function eg getFunc1() are called which append an html to the following div (Each func have its own div)
<li data-section-id="following" data-component-bound="true">
<ul class="module-list">
<!-- USER ACTIVITY JSON -->
</ul>
<a class="ybtn ybtn-primary ybtn-large more-wishlist" href="#" onclick="javascript:getRecentActivityFriends(event)">
<span data-component-bound="true" class="loading-msg following">See more recent activity</span>
</a>
</li>
Only 4 list results are displayed on the div, when user click see more activity button, more result are loaded into div. The problems now is when the page load it display correctly 4 results but when i click the link again rather than a button all the data are displayed.Its difficult for me to navigate between tabs. How can i avoid this?
Update:
var totalFriendsRecords = '<?=$this->followingTotal?>';
function getRecentActivityFriends(event)
{
if (event != null){
disabledEventPreventDefault(event);
}
getFriendsActivity(totalFriendsRecords);
}
home.js
var totalFriendsRecordsView = 0;
function getFriendsActivity(totalFriendsRecords)
{
var activityHtml = ''
$.ajax({
url:baseUrl + "activity/feedfollowing",
data:{'total':totalFriendsRecordsView},
dataType:"json",
type:"POST",
success:function(data){
for(var i=0; i<data.length; i++){
activityHtml = '<p>'+data[i][name]+'</p>';
}
$('#activity-feed li[data-section-id=following] .module-list').append(activityHtml);
if( totalFriendsRecords <= totalFriendsRecordsView){
$('.following').text('Nothing beyond here ...');
$('.following').removeAttr('onclick');
$('.following').removeAttr('href');
}
}
});
}

Categories