jQuery - find all first siblings of each node - javascript

HTML:
<ul class="treeview">
<li>
<a data-toggle="collapse" href=".options1"> <!-- this one -->
Item 1
</a>
<ul class="collapse options1">
<li>
<a data-toggle="collapse" href=".sublevel1"></a> <!-- this one -->
<input type="checkbox" value="option1" />
<a data-toggle="collapse" href=".sublevel1">Item 1-1</a> <!-- not this one -->
<ul class="collapse sublevel1">
<li>
Item 1-1-1
<ul>
<li><input type="checkbox" value="option1" />
Item 1-1-1-1
</li>
<li><a data-toggle="collapse" href=".collapse1-1-1-1-1"></a> <!-- this one -->
<input type="checkbox" value="option1" />
<a data-toggle="collapse" href=".collapse1-1-1-1-1">Item 1-1-1-2</a> <!-- not this one -->
<ul class="collapse collapse1-1-1-1-1">
<li>Item 1-1-1-2-1
<ul>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-1</li>
<li><a data-toggle="collapse" href=".collapse1-1-1-1-1-1-1"></a><input type="checkbox" value="option1" />
<a data-toggle="collapse" href=".collapse1-1-1-1-1-1-1">Item 1-1-1-2-1-2</a>
<ul class="collapse collapse1-1-1-1-1-1-1">
<li>Item 1-1-1-2-1-2-1
<ul>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-1</li>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-2</li>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-3</li>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-4</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><input type="checkbox" value="option1" />Item 1-2</li>
<li><input type="checkbox" value="option1" />Item 1-3</li>
<li><input type="checkbox" value="option1" />Item 1-4</li>
</ul>
</li>
</ul>
jQuery:
$('.treeview ul').not('ul:not([class])').siblings('a')
.prepend("<span>XYZ</span>");
As you can see, I'm already looking for all <ul>'s which don't have ANY classname, and then looking for <a> siblings, but I only need the first sibling (before the input checkbox).
Here's a jsFiddle to help you out: https://jsfiddle.net/st2yehgr/1/ (tip: all the item that have double 'XYZ', I only want the first one)
Can anyone help me here?? Cheers! :)

You can try this
$('.treeview li>a:first-child')
.prepend("<span>XYZ</span>");
Check this fiddle

Answered by :#mplungjan
$('.treeview ul').not('ul:not([class])').each(function() {
$(this).find("a").first().prepend("<span>XYZ</span>");
});
His fiddle: https://jsfiddle.net/qtrhu249/1/ (which I then updated the html to also cover the first level [wrapped everything in a div]).

$('.collapse li').find( "input[type='checkbox']" ).prev().prepend("<span>XYZ</span>")
Try this

Related

Find first parent element with specific first-level descendant

I am trying get first parent (Only) of selected element which have Input type Checkbox as first-level descendant.
HTML
$('input[type="checkbox"]').change(function(e) {
$(this)
.parent()
.parents("li:has(input[type='checkbox'])")
.find(">span")
.css("background-color", "yellow");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<ul class="UL1">
<li class="LI1">
<input class="checkbox1" type="checkbox" />
<span>LI1</span>
<ul class="UL2">
<li class="LI3">
<input class="checkbox2" type="checkbox" />
<span>LI3</span>
</li>
<li class="LI4">
<input class="checkbox3" type="checkbox" />
<span>LI4</span>
<ul class="UL3">
<li class="LI5">
<span>LI5</span>
</li>
<li class="LI6">
<span>LI6</span>
<ul class="UL4">
<li class="LI7">
<span>LI7</span>
</li>
<li class="LI8">
<input class="checkbox4" type="checkbox" />
<span>LI8</span>
</li>
<li class="LI9">
<span>LI9</span>
</li>
</ul>
</li>
<li class="LI10">
<span>LI10</span>
</li>
</ul>
</li>
<li class="LI11">
<span>LI11</span>
</li>
</ul>
</li>
<li class="LI12">
<input class="checkbox5" type="checkbox" />
<span>LI12</span>
</li>
</ul>
</div>
NOTE: In this code I am highlighting span only as an example, but my actual purpose of having parent with checkbox is different.
Here when selecting "LI8" checkbox, I need its parent that has Checkbox. according to this I should receive "LI4" but when I am using ".parents(). it is giving me all parents including "LI" not having Checkbox.
Does anybody know how can I get only first parent that has checkbox as first-level descendant? In my scenario on selection of "LI8", only "LI4" should return and "LI6" and "LI1" must ignore. Thank you.
li:has(input[type='checkbox']) will select all lis that contain an input at any level.
Use the direct descendant selector (>) here: .parents("li:has(>input[type='checkbox'])") to select those lis that have a child input.
You can then limit the selection to a single item using .first().
$('input[type="checkbox"]').change(function(e) {
$(this)
.parent()
.parents("li:has(>input[type='checkbox'])")
.first()
.find(">span")
.css("background-color", "yellow");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<ul class="UL1">
<li class="LI1">
<input class="checkbox1" type="checkbox" />
<span>LI1</span>
<ul class="UL2">
<li class="LI3">
<input class="checkbox2" type="checkbox" />
<span>LI3</span>
</li>
<li class="LI4">
<input class="checkbox3" type="checkbox" />
<span>LI4</span>
<ul class="UL3">
<li class="LI5">
<span>LI5</span>
</li>
<li class="LI6">
<span>LI6</span>
<ul class="UL4">
<li class="LI7">
<span>LI7</span>
</li>
<li class="LI8">
<input class="checkbox4" type="checkbox" />
<span>LI8</span>
</li>
<li class="LI9">
<span>LI9</span>
</li>
</ul>
</li>
<li class="LI10">
<span>LI10</span>
</li>
</ul>
</li>
<li class="LI11">
<span>LI11</span>
</li>
</ul>
</li>
<li class="LI12">
<input class="checkbox5" type="checkbox" />
<span>LI12</span>
</li>
</ul>
</div>

With Bootstrap 4, how can I collapse sidebar in mobile/tablet view

I want to create a collapsible sidebar that is expanded on lg and higher views, but is collapsed with a (now visible) button to expand on tablet and mobile views (md or smaller).
How would I make my sidebar collapsible on mobile/tablet views? (xs, md, lg)
It needs to be expanded in desktop views (lg, xl) and have a toggle button that's hidden in large desktop views, but displays in small mobile/tablet views.
Do I need to write some custom JS?
Linked here are the BS4 Docs for Collapse, but I didn't understand how this would do what I need (https://getbootstrap.com/docs/4.0/components/collapse/#options).
//The Button
<h4 class="mb-3"><span class="text-muted">Search Filters</span>
<button class="navbar-toggler border"
type="button"
data-toggle="collapse"
data-target="#sidebar"
aria-expanded="false"
aria-label="Toggle filters">
<span><i class="fas fa-filter"></i></span>
</button>
</h4>
//The Sidebar
<ul id="sidebar" class="list-group mb-3">
<li class="list-group-item d-flex justify-content-between lh-condensed">
<div>
<h6 class="my-0">Header</h6>
<div class="input-group mb-3">
<ul>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
</ul>
</div>
</li>
<li class="list-group-item d-flex justify-content-between lh-condensed">
<div>
<h6 class="my-0">Header</h6>
<div class="input-group mb-3">
<ul>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
</ul>
</div>
</li>
<li class="list-group-item d-flex justify-content-between lh-condensed">
<div>
<h6 class="my-0">Header</h6>
<div class="input-group mb-3">
<ul>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
<li><input type="checkbox" aria-label="Checkbox"> Checkbox List Item </li>
</ul>
</div>
</li>
</ul>
</div>
Well, with some help on other websites I figured out the solution. The guys at the Slack Bootstrap Help Channel were kind enough to point me in the right direction by linking a StackOverflow thread.
Using that link along with the Collapse Documentation at Bootstrap I was able to figure it out. Below is the answer...
// Used jQuery to create the new logic:
if ($(window).width() < 922) {
$('#sidebar').collapse({
toggle: false
});
} else {
$('#sidebar').collapse({
toggle: true
});
}
// Also, needed to add the .collapse class to the UL:
<ul id="sidebar" class="collapse list-group mb-3">
....
</ul>
I hope this helps others!
No need to use JS, use Bootstrap classes:
https://getbootstrap.com/docs/4.1/utilities/display/#hiding-elements
You could do this:
//The Button: The class d-lg-none will hide the filters for large size (ie: it'll be visible on xs-s-md sizes only)
<h4 class="d-lg-none mb-3"><span class="text-muted">Search Filters</span>
<button class="navbar-toggler border"
type="button"
data-toggle="collapse"
data-target="#sidebar"
aria-expanded="false"
aria-label="Toggle filters">
<span><i class="fas fa-filter"></i></span>
</button>
</h4>
//The Sidebar : "d-none d-lg-block" will display the sidebar only on large size
<ul id="sidebar" class="d-none d-lg-block list-group mb-3">
....
</ul>

Jquery accordion collapsed on page load

I am trying to create an expandable accordion using jquery. I am not able to figure out that how am I supposed to prevent it from expanding on page load. I have no idea of jquery,and any help will be greatly appreciated.
<ul>
<li class="expandable root">
<label for=" Oraganization" class="active"> Oraganization</label>
<span class="pull-right oraganization active expand-icon glyphicon glyphicon-minus"></span>
<ul id="accordion">
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-minus"></span>
<input type="checkbox" id="Manager-1">
<label for="Manager-1"> Manager-1</label>
<ul id="accordion">
<li>
<input type="checkbox" id="Sub-Manager-1">
<label for="Sub-Manager-1"> Sub-Manager-1</label>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-minus"></span>
<input type="checkbox" id="Sub-Manager-2">
<label for="Sub-Manager-2"> Sub-Manager-2</label>
<ul class="accordion">
<li>
<input type="checkbox" id="Associate-1">
<label for="Associate-1"> Associate-1</label>
</li>
<li>
<input type="checkbox" id="Associate-2">
<label for="Associate-2"> Associate-2</label>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-minus"></span>
<input type="checkbox" id="Associate-5">
<label for="Associate-5"> Associate-5</label>
<ul class="accordion">
<li>
<input type="checkbox" id="Sub-associate-1">
<label for="Sub-associate-1"> Sub-associate-1</label>
</li>
<li>
<input type="checkbox" id="Sub-associate-2">
<label for="Sub-associate-2"> Sub-associate-2</label>
</li>
<li>
<input type="checkbox" id="Sub-associate-3">
<label for="Sub-associate-3"> Sub-associate-3</label>
</li>
<li>
<input type="checkbox" id="Sub-associate-4">
<label for="Sub-associate-4"> Sub-associate-4</label>
</li>
</ul>
</li>
</ul>
</li>
</li>
</ul>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-plus"></span>
<input type="checkbox" id="Manager-2">
<label for="Manager-2"> Manager-2</label>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-plus"></span>
<input type="checkbox" id="Manager-3">
<label for="Manager-3"> Manager-3</label>
</li>
</ul>
</li>
</ul>
JS File:
$(document).ready(function(){
$('.expand-icon').click(function(){
var elem = $(this);
if(elem.hasClass('active')) {
elem.removeClass('active');
var subElem = elem.siblings('ul');
var nestedElem =elem.siblings('ul').find('ul');
if(nestedElem.length == 0) {
subElem.slideUp('fast');
}
else {
nestedElem.slideUp('fast',function(){
subElem.slideUp('fast');
});
}
$.when(elem.removeClass('glyphicon-minus')).then(function(){
elem.addClass('glyphicon-plus');
});
}
else {
elem.addClass('active');
elem.siblings('ul').slideDown('fast',function(){
elem.siblings('ul').find('ul').slideDown('fast');
});
$.when(elem.removeClass('glyphicon-plus')).then(function(){
elem.addClass('glyphicon-minus');
});
}
});
$('.expandable :checkbox').on('change', function() {
$(this).parent().find('li input[type=checkbox]').prop('checked', $(this).is(':checked'));
var sibs = false;
$(this).closest('ul').children('li').each(function () {
if($('input[type=checkbox]', this).is(':checked')) sibs=true;
});
$(this).parents('ul').siblings(':checkbox').prop('checked', sibs);
});
});
You an find the bootply at this link: http://www.bootply.com/1W8bSTnmx6
Fiddle Here
This is because you have this first accordian open when loading it. To fix it, do a click operation on this at the time of load with $($('#accordion .expand-icon')[0]).click();. Check the working example here http://www.bootply.com/vGoKbvfKtl
you are just displaying all the accordions when the page gets loaded since there is no hiding any where.
According to your code Since only the first Accordion contains the data, it is getting displayed else every expandable div will get displayed.
The solution for this is to add a hide class to the class accordion so that it does not display at the beginning, the at the time of click function, you can remove that class and it gets displayed.
$(document).ready(function(){
$('.expand-icon').click(function(){
$('ul').removeClass('hide')
var elem = $(this);
if(elem.hasClass('active')) {
elem.removeClass('active');
var subElem = elem.siblings('ul');
var nestedElem =elem.siblings('ul').find('ul');
if(nestedElem.length == 0) {
subElem.slideUp('fast');
}
else {
nestedElem.slideUp('fast',function(){
subElem.slideUp('fast');
});
}
$.when(elem.removeClass('glyphicon-minus')).then(function(){
elem.addClass('glyphicon-plus');
});
}
else {
elem.addClass('active');
elem.siblings('ul').slideDown('fast',function(){
elem.siblings('ul').find('ul').slideDown('fast');
});
$.when(elem.removeClass('glyphicon-plus')).then(function(){
elem.addClass('glyphicon-minus');
});
}
});
$('.expandable :checkbox').on('change', function() {
$(this).parent().find('li input[type=checkbox]').prop('checked', $(this).is(':checked'));
var sibs = false;
$(this).closest('ul').children('li').each(function () {
if($('input[type=checkbox]', this).is(':checked')) sibs=true;
});
$(this).parents('ul').siblings(':checkbox').prop('checked', sibs);
});
$('.organization').click(function(){
$('.accordion')[0].click()
})
});
<ul>
<li class="expandable ">
<label for=" Oraganization" class="active"> Oraganization</label>
<span class=" organization active expand-icon glyphicon glyphicon-minus"></span>
<ul id="">
<li class="expandable">
<span class="expand-icon glyphicon glyphicon-plus"></span>
<input type="checkbox" id="Manager-1">
<label for="Manager-1"> Manager-1</label>
<ul class="accordion hide">
<li>
<input type="checkbox" id="Sub-Manager-1">
<label for="Sub-Manager-1"> Sub-Manager-1</label>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-minus"></span>
<input type="checkbox" id="Sub-Manager-2">
<label for="Sub-Manager-2"> Sub-Manager-2</label>
<ul class="accordion">
<li>
<input type="checkbox" id="Associate-1">
<label for="Associate-1"> Associate-1</label>
</li>
<li>
<input type="checkbox" id="Associate-2">
<label for="Associate-2"> Associate-2</label>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-minus"></span>
<input type="checkbox" id="Associate-5">
<label for="Associate-5"> Associate-5</label>
<ul class="accordion">
<li>
<input type="checkbox" id="Sub-associate-1">
<label for="Sub-associate-1"> Sub-associate-1</label>
</li>
<li>
<input type="checkbox" id="Sub-associate-2">
<label for="Sub-associate-2"> Sub-associate-2</label>
</li>
<li>
<input type="checkbox" id="Sub-associate-3">
<label for="Sub-associate-3"> Sub-associate-3</label>
</li>
<li>
<input type="checkbox" id="Sub-associate-4">
<label for="Sub-associate-4"> Sub-associate-4</label>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-plus"></span>
<input type="checkbox" id="Manager-2">
<label for="Manager-2"> Manager-2</label>
</li>
<li class="expandable">
<span class="expand-icon active glyphicon glyphicon-plus"></span>
<input type="checkbox" id="Manager-3">
<label for="Manager-3"> Manager-3</label>
</li>
</ul>
</li>
</ul>
Here is the bootply,
Bootply link for it

AngularJS ng-click function that adds class to clicked navigation link

I'm struggling to find the correct code to a navigation sidebar on a angularJS app. What should happen is when you click a link a background color should highlight the active link. It does work as expected except you have to click each link twice before the highlight shows.
What is it that I'm doing wrong? Any help would be greatly appreciated.
javascript
$scope.addActiveClass = function ($index) {
$scope.addActiveClass = $index;
var checked = $('ul.sidebar2-nav li');
$(checked).on("click", "", function () {
$(this).addClass('active-label');
});
}
html
<nav id="program-editor-pullout" menustate="closed" >
<ul class="list-unstyled sidebar2-nav">
<li ui-sref-active="active-label">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-click="addActiveClass($index)" ng-class="{active: home}" ui-sref-active="active" ui-sref=".home">Home</a>
</label>
</div>
</li>
<li ui-sref-active="active-label">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-click="addActiveClass($index)" ng-class="{active: evaluations}" ui-sref-active="active" ui-sref=".evaluation">Evaluations</a>
</label>
</div>
</li>
<li ui-sref-active="active-label">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-click="addActiveClass($index)" ng-class="{active: questions}" ui-sref-active="active" ui-sref=".question">Questions</a>
</label>
</div>
</li>
<li ui-sref-active="active-label">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-click="addActiveClass()" ng-class="{active: hstranscripts}" ui-sref-active="active" ui-sref=".hstranscripts">High School Transcripts</a>
</label>
</div>
</li>
<li ui-sref-active="active-label">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-click="addActiveClass($index)" ng-class="{active: collegetranscripts}" ui-sref-active="active" ui-sref=".collegetranscripts">College Transcripts & Course Work</a>
</label>
</div>
</li>
<li ui-sref-active="active-label">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-click="addActiveClass($index)" ng-class="{active: prerequisites}" ui-sref-active="active" ui-sref=".prerequisites">Prerequisites</a>
</label>
</div>
</li>
<li ui-sref-active="active-label">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-click="addActiveClass($index)" ng-class="{active: documents}" ui-sref-active="active" ui-sref=".document">Documents</a>
</label>
</div>
</li>
</ul>
</nav>
CSS
ul.sidebar2-nav li a.active {
color: #000;
cursor: pointer;
text-decoration: none;
}
ul.sidebar2-nav li.active-label {
background: whitesmoke;
}
I found the solution. Your example was correct, but in my html code I had this:
<li ui-sref-active="active-label" ng-click="addActiveClass($event, $index)">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-class="{active: home}" ui-sref-active="active" ui-sref=".home">Home</a>
</label>
</div>
</li>
Notice how the anchor tag has the ng-class and the ui-sref-active on it. I removed these attributes and it works as expected. Thank you for your guidance, I appreciate it!!
Move click event from a to parent li tag
<nav id="program-editor-pullout" menustate="closed" >
<ul class="list-unstyled sidebar2-nav">
<li ui-sref-active="active-label" ng-click="addActiveClass($event, $index)">
<div class="checkbox">
<label>
<input type="checkbox" ng-checked="true">
<a ng-class="{active: home}" ui-sref-active="active" ui-sref=".home">Home</a>
</label>
</div>
</li>
Change your click handler to something like this
$scope.addActiveClass = function ($event, $index) {
$scope.addActiveClass = $index;
//var checked = $('ul.sidebar2-nav li');
//$(checked).on("click", "", function () {
// $(this).addClass('active-label');
//});
$($event.target).addClass('active-label');
}

how to check all the children check

Hi I have the following structure:
<ul class="main">
<li class="toggle">
<input type="checkbox"> information
</li>
<ul>
<li class="modulo">
<input type="checkbox"> General
</li>
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</ul>
</ul>
I now need to know how to set all the children checkboxes to "checked" when the main parent checkbox is checked by the user
Im using jQuery, thanks
Your can change markup like following:
<ul class="main">
<li class="toggle">
<input type="checkbox"> information
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</li>
<li class="modulo">
<input type="checkbox"> General
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</li>
</ul>
jQuery
$('ul.main > li > :checkbox').change(function() {
$(this).next('ul').find(':checkbox').prop('checked', this.checked);
});
If you correct your markup:
<ul class="main">
<li class="toggle">
<input type="checkbox"> information
<ul>
<li class="modulo">
<input type="checkbox"> General
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</li>
</ul>
</li>
</ul>
...this should do it:
$(".main input[type='checkbox']").click(function() {
$(this).parent().find("input[type='checkbox']").prop("checked", this.checked);
});
Live example | source
Then you'll want to handle the converse case (unchecking the parent if you uncheck an ancestor so all ancestors are no longer checked), but I leave that as an exercise for you.
This toggles the checks: http://jsfiddle.net/
I'd suggest you indent your code for more easy reading too.

Categories

Resources