// here we cache a reference to all .row elements which are not .header elements,
// using document.querySelectorAll(), which returns a non-live NodeList:
const rows = document.querySelectorAll('.row:not(.header)'),
// declaring a function, using Arrow syntax (since we don't use 'this'
// within the function body:
isVisible = (el) => {
// if el is truthy, so is not 'null' or 'undefined':
if (el) {
// we return the results of the following assessments:
// el.hidden === false: we test whether the hidden property
// evaluates to false; if so:
// window.getComputedStyle(el, null).display !== 'none':
// recovers the rendered 'display' property
// of the element, and the assessment checks
// that it is not equal to 'none';
// if both assessments evaluate to true, we return true otherwise
// we return false:
return el.hidden === false && window.getComputedStyle(el, null).display !== 'none';
}
// by default, in the event of a non-existent element or null-reference,
// is passed to the function we simply return false:
return false;
},
// another function declared using Arrow syntax:
orderToggle = (e) => {
// 'e' is a reference to the Event Object passed from the
// EventTarget.addEventListener() call (later);
// activated is a reference to the element to which the
// event-handler was bound:
const activated = e.currentTarget,
// potentialOrders is a reference to the nextElementSibling
// of the current-target; the variable name refers to the
// fact that there may not be a nextSiblingElement or
// that the nextSiblingElement may not be the appropriate
// element:
potentialOrders = activated.nextElementSibling,
// here we call the isVisible() function, above, to retrieve
// a Boolean (true/false) to represent the current-visibility
// of the potentialOrder element:
currentVisibility = isVisible(potentialOrders);
// if the potentialOrders element is truthy (exists, and does not
// evaluate to either undefined or null), we test whether that
// element matches the CSS selector passed to the Element.matches()
// method:
if (potentialOrders && potentialOrders.matches('.orders')) {
// here we update the hidden property of the potentialOrders
// element, isVisible() function returns true, we wish to hide
// the element, so we set 'hidden' to true, otherwise we set
// it to false (as returned by the isVisible() function):
potentialOrders.hidden = currentVisibility;
}
};
// here we iterate over the NodeList of .row:not(.header) elements
// using NodeList.prototype.forEach() along with an Arrow function:
rows.forEach(
// 'el' is a reference to the current Node of the NodeList over
// which we're iterating:
(el) => {
// here we use EventTarget.addEventListener() to bind the anonymous
// function of the addEventListener() method to:
el.addEventListener('click', function(e) {
// call the orderToggle() function, passing the Event
// Object to the function:
orderToggle(e)
});
});
/* setting common default properties for all elements,
along with the ::before and ::after pseudo-elements: */
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
line-height: 1.5;
margin: 0;
padding: 0;
}
.herotable {
margin: auto 1em;
width: 90vw;
}
/* using CSS grid layout: */
.table {
display: grid;
/* setting four columns of equal width: */
grid-template-columns: repeat(4, 1fr);
}
/* distinguishing the .header element to
make the headings visually distinguishable,
but do consider adding appropriate ARIA
roles/attributes to the HTML for
accessibility purposes: */
.header {
font-weight: bold;
border-bottom: 2px solid currentColor;
}
.table.list {
/* placing this element full width across the
defined grid-columns 1 is the first
column, -1 represents the last column; this
is shorthand for "grid-column-start: 1"
and "grid-column-end: -1": */
grid-column: 1 / -1;
/* setting grid-row-gap of 0.5em, and a
grid-column-gap of 0.25em; to separate
cells (adjust to taste): */
gap: 0.5em 0.25em;
}
.row {
/* using CSS grid-layout: */
display: grid;
/* again positioning the elements
to start in the first column
and end in the last column: */
grid-column: 1 / -1;
/* here we use subgrid to have the
grid of the .row elements match
the columns defined on the parent
element: */
grid-template-columns: subgrid;
}
.row:not(.header) {
/* used to indicate interactivity, this
may or not be desired in your use-case,
adjust to taste: */
cursor: pointer;
}
.orders {
/* we don't need to use subgrid here since
the .orders element(s) are children of a
.table element: */
display: grid;
grid-column: 1 / -1;
}
/* hiding elements with the hidden attribute,
because we've overriden the default
display of the .orders elements: */
.orders[hidden] {
display: none;
}
.order {
border: 1px solid currentColor;
border-left-color: transparent;
border-right-color: transparent;
}
<div class="wrapper herotable">
<div id="test">
<div class="table">
<div class="row header">
<div class="cell sorting sort" data-sort="name">Name</div>
<div class="cell sorting sort" data-sort="age">Age</div>
<div class="cell sorting sort" data-sort="ocupat">Occupation</div>
<div class="cell sorting sort" data-sort="location">Location</div>
</div>
<div class="table list">
<div class="row">
<div class="cell name" data-title="Name">Luke Peters</div>
<div class="cell age" data-title="Age">25</div>
<div class="cell ocupat" data-title="Occupation">Freelance Web Developer</div>
<div class="cell location" data-title="Location">Brookline, MA</div>
</div>
<!-- note that I've set the 'hidden' attribute on the element
so that it is hidden on page-load; this may or may not
be required for your use-case: -->
<div class="orders" hidden>
<div class="order">This should be an independent div-element. I would like to inject it with JavaScript when clicking on line above.<br> It should not expand the name column.</div>
</div>
<div class="row">
<div class="cell name" data-title="Name">Joseph Smith</div>
<div class="cell age" data-title="Age">27</div>
<div class="cell ocupat" data-title="Occupation">Project Manager</div>
<div class="cell location" data-title="Location">Somerville, MA</div>
</div>
<div class="row">
<div class="cell name" data-title="Name">Maxwell Johnson</div>
<div class="cell age" data-title="Age">26</div>
<div class="cell ocupat" data-title="Occupation">UX Architect & Designer</div>
<div class="cell location" data-title="Location">Arlington, MA</div>
</div>
</div>
</div>
</div>
</div>