Skip to content

Instantly share code, notes, and snippets.

@jonathanlaf
Last active October 26, 2020 13:29
Show Gist options
  • Save jonathanlaf/e1033f60d202e25a16856eb636dc34fd to your computer and use it in GitHub Desktop.
Save jonathanlaf/e1033f60d202e25a16856eb636dc34fd to your computer and use it in GitHub Desktop.
Get element parent or sibling by id / class name or tag name
/*
* Use case:
* Need to toggle the next row
*
* The first part of this script is for demo purpose. (In order to make the demo work, you need bootstrap.)
*/
// Get all the btns
const informationToggleBtns = document.querySelectorAll('.toggle-info');
// Bind Click event on them
informationToggleBtns
.forEach(btn => btn.addEventListener("click", toggleMoreInfo));
// Find the parent row then find the sibbling of this row.
// Now that we have the next sibbling row, do the toggle magic.
function toggleMoreInfo(e) {
const btnClasses = e.target.classList;
const parent = findParent(e.target, 'tr')
const nextRow = findNextSibbling(parent, 'tr');
const nextRowClasses = nextRow.classList;
if (nextRowClasses.contains('d-none')) {
btnClasses.remove('fa-plus-square');
btnClasses.add('fa-minus-square');
nextRowClasses.remove('d-none');
} else {
btnClasses.remove('fa-minus-square');
btnClasses.add('fa-plus-square');
nextRowClasses.add('d-none');
}
}
/*
* Parent and Sibbling Search through ID, Class and Tag name.
*/
// Recursive function that search for a parent from element to document.
function findParent(element, selector) {
const searchType = selectorType(selector);
let parent = element.parentNode;
let found = false;
if (parent === null) {
return false;
}
switch (searchType) {
case 'class':
found = isElementMatchClassName(parent, selector);
break
case 'id':
found = isElementMatchID(parent, selector);
break;
case 'tag':
default:
found = isElementMatchTag(parent, selector);
break;
}
if (!found) {
return findParent(parent, selector);
} else {
return parent;
}
}
// Recursive function that search for a sibbling from element to end of document.
function findNextSibbling(element, selector) {
const searchType = selectorType(selector);
let nextSibbling = element.nextSibling;
let found = false;
if (nextSibbling === null) {
return false;
}
switch (searchType) {
case 'class':
found = isElementMatchClassName(nextSibbling, selector);
break
case 'id':
found = isElementMatchID(nextSibbling, selector);
break;
case 'tag':
default:
found = isElementMatchTag(nextSibbling, selector);
break;
}
if (!found) {
return findNextSibbling(nextSibbling, selector);
} else {
return nextSibbling;
}
}
// Get the selector tye
function selectorType(str) {
switch (str.charAt(0)) {
case '.':
return 'class';
case '#':
return 'id';
default:
return 'tag';
}
}
// Check if element have given classname
function isElementMatchClassName(element, selector) {
return element.classList.contains(selector.substring(1));
}
// Check if element's id match selector
function isElementMatchID(element, selector) {
return element.id === selector.substring(1);
}
// Check if element tag name match selector
function isElementMatchTag(element, selector) {
return element.nodeName.toUpperCase() === selector.toUpperCase();
}
<table class="table table-striped">
<tbody>
<tr id="first-row">
<td><span class="toggle-info"><i class="fa fa-plus-square pl-3"></i></span></td>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr class="d-none">
<td colspan="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc laoreet fringilla libero, fermentum ultrices augue aliquet vitae. Praesent scelerisque molestie consectetur. Curabitur diam ligula, consectetur ac arcu ut, volutpat consequat leo. Donec ullamcorper massa quis sem hendrerit elementum. Nam turpis metus, ultrices in velit tempus, gravida laoreet massa. Nullam aliquam risus vel orci congue, ac ultricies elit porta. Curabitur posuere mi sem, ac vestibulum nibh suscipit at. Etiam eget posuere orci, sed accumsan nibh.</td>
</tr>
<tr id="second-row">
<td><span class="toggle-info"><i class="fa fa-plus-square pl-3"></i></span></td>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr class="d-none">
<td colspan="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc laoreet fringilla libero, fermentum ultrices augue aliquet vitae. Praesent scelerisque molestie consectetur. Curabitur diam ligula, consectetur ac arcu ut, volutpat consequat leo. Donec ullamcorper massa quis sem hendrerit elementum. Nam turpis metus, ultrices in velit tempus, gravida laoreet massa. Nullam aliquam risus vel orci congue, ac ultricies elit porta. Curabitur posuere mi sem, ac vestibulum nibh suscipit at. Etiam eget posuere orci, sed accumsan nibh.</td>
</tr>
<tr id="third-row">
<td><span class="toggle-info"><i class="fa fa-plus-square pl-3"></i></span></td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr class="d-none">
<td colspan="4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc laoreet fringilla libero, fermentum ultrices augue aliquet vitae. Praesent scelerisque molestie consectetur. Curabitur diam ligula, consectetur ac arcu ut, volutpat consequat leo. Donec ullamcorper massa quis sem hendrerit elementum. Nam turpis metus, ultrices in velit tempus, gravida laoreet massa. Nullam aliquam risus vel orci congue, ac ultricies elit porta. Curabitur posuere mi sem, ac vestibulum nibh suscipit at. Etiam eget posuere orci, sed accumsan nibh.</td>
</tr>
</tbody>
</table>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment