Remove a className only the sam parent div - javascript

do you know how to keep selected a div in a different column, right every time I click on a div it remove the previous selected. I would like to keep the user choice selected on each different column : [https://codepen.io/dodgpine/pen/bGaqWVG][1]
const subTitleBuild = document.querySelectorAll(".sub-title-build");
const subTitleOs = document.querySelectorAll(".sub-title-os");
const subTitlePackage = document.querySelectorAll(".sub-title-package");
const subTitleLanguage = document.querySelectorAll(".sub-title-language");
const subTitleCuda = document.querySelectorAll(".sub-title-cuda");
const selections = [
subTitleBuild,
subTitleOs,
subTitlePackage,
subTitleLanguage,
subTitleCuda,
];
selections.forEach((selection) => {
selection.forEach((title) => {
title.addEventListener("click", () => {
removeSelectedClasses();
title.classList.add("selected");
});
});
});
function removeSelectedClasses() {
selections.forEach((selection) => {
selection.forEach((title) => {
console.log(title);
title.classList.remove("selected");
});
});
}

I've made two changes to your javascript, which I think achieve what you want (if I have understood correctly, you want a click to apply the class selected without affecting previously selected options, and, presumably, be able to remove earlier selections with another click on them).
Firstly, I commented out (removed) title.classList.remove("selected"); from your removeSelectedClasses() function, as this is what was clearing earlier selections.
Secondly, I modified, title.classList.add("selected"); in your event listeners to instead toggle the selected class on and off using: title.classList.toggle("selected");. This enables a single click to apply the selected class, while a second click on the same box removes it.
The snippet below works to show the effect.
I note you probably need column selections to be limited to a single choice, so you will have to fiddle with how the changes I suggested are applied. But the principle should help you do that.
const subTitleBuild = document.querySelectorAll(".sub-title-build");
const subTitleOs = document.querySelectorAll(".sub-title-os");
const subTitlePackage = document.querySelectorAll(".sub-title-package");
const subTitleLanguage = document.querySelectorAll(".sub-title-language");
const subTitleCuda = document.querySelectorAll(".sub-title-cuda");
const selections = [
subTitleBuild,
subTitleOs,
subTitlePackage,
subTitleLanguage,
subTitleCuda,
];
selections.forEach((selection) => {
selection.forEach((title) => {
title.addEventListener("click", () => {
removeSelectedClasses();
title.classList.toggle("selected");
});
});
});
function removeSelectedClasses() {
selections.forEach((selection) => {
selection.forEach((title) => {
console.log(title);
//title.classList.remove("selected");
});
});
}
.container-master {
width: 1200px;
margin: auto;
}
.container {
display: flex;
justify-content: space-between;
}
.column {
width: 170px;
}
.container-btn {
padding: 20px;
border: 2px solid black;
text-align: center;
margin-top: 10px;
}
.title {
margin-bottom: 30px;
background-color: #3e4652;
color: #ffffff;
}
.sub-title,
.sub-title-build {
cursor: pointer;
}
.row-cmd {
width: 1200px;
margin: 50px auto;
}
.container-btn-cmd {
padding: 20px;
border: 2px solid black;
text-align: center;
margin-top: 10px;
}
.command-container {
padding: 20px;
border: 2px solid black;
text-align: center;
margin-top: 10px;
}
.selected {
background-color: orangered;
color: #ffffff;
}
<div class="container-master">
<div class="container">
<div class="column ptbuild">
<div class="container-btn title">
<div class="btn">PyTorch Build</div>
</div>
<div class="container-btn sub-title-build" id="stable">
<div class="btn">Stable (1.11.0)</div>
</div>
<div class="container-btn sub-title-build" id="preview">
<div class="btn">Preview (Nightly)</div>
</div>
<div class="container-btn sub-title-build" id="lts">
<div class="btn">LTS (1.8.2)</div>
</div>
</div>
<div class="column os">
<div class="container-btn title">
<div class="btn">Your OS</div>
</div>
<div class="container-btn sub-title-os" id="linux">
<div class="btn">Linux</div>
</div>
<div class="container-btn sub-title-os" id="macos">
<div class="btn">Mac</div>
</div>
<div class="container-btn sub-title-os" id="windows">
<div class="btn">Windows</div>
</div>
</div>
<div class="column package">
<div class="container-btn title">
<div class="btn">Package</div>
</div>
<div class="container-btn sub-title-package" id="conda">
<div class="btn">Conda</div>
</div>
<div class="container-btn sub-title-package" id="pip">
<div class="btn">Pip</div>
</div>
<div class="container-btn sub-title-package" id="libtorch">
<div class="btn">LibTorch</div>
</div>
<div class="container-btn sub-title-package" id="source">
<div class="btn">Source</div>
</div>
</div>
<div class="column language">
<div class="container-btn title">
<div class="btn">Language</div>
</div>
<div class="container-btn sub-title-language" id="python">
<div class="btn">Python</div>
</div>
<div class="container-btn sub-title-language" id="cplusplus">
<div class="btn">C++ / Java</div>
</div>
</div>
<div class="column cuda">
<div class="container-btn title">
<div class="btn">Compute Platform</div>
</div>
<div
class="container-btn sub-title-cuda"
id="cuda10.2"
style="text-decoration: line-through"
>
<div class="btn">CUDA 10.2</div>
</div>
<div
class="container-btn sub-title-cuda"
id="cuda11.x"
style="text-decoration: line-through"
>
<div class="btn">CUDA 11.3</div>
</div>
<div
class="container-btn sub-title-cuda"
id="rocm4.x"
style="text-decoration: line-through"
>
<div class="btn">ROCM 4.2 (beta)</div>
</div>
<div class="container-btn sub-title-cuda" id="accnone">
<div class="btn">CPU</div>
</div>
</div>
</div>
<div class="row-cmd">
<div class="container-btn-cmd title">
<div class="option-text">Run this Command:</div>
</div>
<div class="command-container">
<div class="cmd-text" id="command">
<pre># MacOS Binaries dont support CUDA, install from source if CUDA is needed<br>conda install pytorch torchvision torchaudio -c pytorch</pre>
</div>
</div>
</div>
</div>

Related

Passing Javascript value into CSS?

I'm trying to pass my javascript value (a percentage) into the css 100% width line which is currently at 30%. This currently creates a table that populates outward, starting at 0 and then going out to 30%, I want to be able to implement my Javascript value (c2_percent) instead of the 30% value. If anyone can help that would be great. Thanks
<div class="bar-graph bar-graph-horizontal bar-graph-one">
<div class="bar-one">
<span class="rating-a1">A1</span>
<div class="bar" id="rating-a1" data-percentage=""></div>
</div>
<div class="bar-two">
<span class="rating-a2">A2</span>
<div class="bar" data-percentage="11%"></div>
</div>
<div class="bar-three">
<span class="rating-a3">A3</span>
<div class="bar" data-percentage="7%"></div>
</div>
<div class="bar-four">
<span class="rating-b1">B1</span>
<div class="bar" data-percentage="10%"></div>
</div>
<div class="bar-five">
<span class="rating-b2">B2</span>
<div class="bar" data-percentage="20%"></div>
</div>
<div class="bar-six">
<span class="rating-b3">B3</span>
<div class="bar" data-percentage="5%"></div>
</div>
<div class="bar-seven">
<span class="rating-c1">C1</span>
<div class="bar" data-percentage="9%"></div>
</div>
<div class="bar-eight">
<span class="rating-c2">C2</span>
<div class="bar" id="c2-rating" data-percentage=""></div>
</div>
<div class="bar-nine">
<span class="rating-c3">C3</span>
<div class="bar" data-percentage="5%"></div>
</div>
<div class="bar-ten">
<span class="rating-d1">D1</span>
<div class="bar" data-percentage="5%"></div>
</div>
</div>
#-webkit-keyframes show-bar-eight {
0% {
width: 0;
}
100% {
width: 30%;
}
}
<script>
for(let i = 0; i < 1; i++) {
const c2_security_values = Array.from(document.querySelectorAll('.security-value-c2'));
const c2_security_values_inner = c2_security_values.map((element) => element.innerText);
const c2_summed_values = c2_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));
const total_security_values = Array.from(document.querySelectorAll('.individual-market-value'));
const total_security_values_inner = total_security_values.map((element) => element.innerText);
const total_summed_values = total_security_values_inner.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue));
const c2_percent = c2_summed_values / total_summed_values
}
</script>
Out of the top of my head, I would add this line after calculating c2_percent in the script (make sure to have your c2_percent defined outside of the loop, and set it as a variable, not a constant).
document.getElementById('c2-rating').setAttribute("data-percentage", c2_percent * 100 + '%');
As you don't provide any other data about the rest of the page, the styles, etc. I cannot tell if this would even work.
Do you pretend to modify the width of the c2-rating?
This only modifies the value of the data-percentage attribute.
To modify the css width attribute, you can try
document.getElementById('c2-rating').setAttribute("style","width:" + (c2_percent * 100) + '%');
I have made a snippet that shows that it would work, it all will depend on the rest of the page in your project.
<html>
<head>
<style>
.bar-graph {
font-family: Arial, Helvetica, sans-serif;
}
.bar-graph div {
padding: 5px 0px;
}
.bar-graph div span {
display: inline-block;
font-weight: 600;
margin: 5px 5px;
float: left;
}
.bar-graph .bar {
border: 1px solid #ccc;
background-color: #eee;
height: 30px;
}
#-webkit-keyframes show-bar-eight {
0% {
width: 0;
}
100% {
width: 30%;
}
}
</style>
</head>
<body>
<div class="bar-graph bar-graph-horizontal bar-graph-one">
<div class="bar-one">
<span class="rating-a1">A1</span>
<div class="bar" id="rating-a1" data-percentage=""></div>
</div>
<div class="bar-two">
<span class="rating-a2">A2</span>
<div class="bar" data-percentage="11%"></div>
</div>
<div class="bar-three">
<span class="rating-a3">A3</span>
<div class="bar" data-percentage="7%"></div>
</div>
<div class="bar-four">
<span class="rating-b1">B1</span>
<div class="bar" data-percentage="10%"></div>
</div>
<div class="bar-five">
<span class="rating-b2">B2</span>
<div class="bar" data-percentage="20%"></div>
</div>
<div class="bar-six">
<span class="rating-b3">B3</span>
<div class="bar" data-percentage="5%"></div>
</div>
<div class="bar-seven">
<span class="rating-c1">C1</span>
<div class="bar" data-percentage="9%"></div>
</div>
<div class="bar-eight">
<span class="rating-c2">C2</span>
<div class="bar" id="c2-rating" data-percentage=""></div>
</div>
<div class="bar-nine">
<span class="rating-c3">C3</span>
<div class="bar" data-percentage="5%"></div>
</div>
<div class="bar-ten">
<span class="rating-d1">D1</span>
<div class="bar" data-percentage="5%"></div>
</div>
</div>
<input type="range" min="0" max="100" value="0" class="slider" id="c2RatingSlider" value="43" onchange="updateC2()">
<script>
updateC2();
function updateC2() {
var c2_percent = document.getElementById("c2RatingSlider").value / 100;
document.getElementById('c2-rating').setAttribute("data-percentage", c2_percent * 100 + '%');
document.querySelectorAll('.bar').forEach((bar) => {
const percentage = bar.getAttribute('data-percentage');
bar.setAttribute("style", "width:" + percentage);
});
}
</script>
</body>
</html>

JavaScript get multiple element's text values

I want to make that when the user clicks onto the bordered container, the 'Name' text should show the container's name only and the 'Subject' text should show the container's subject only, but this code shows all the elements inside the container for the 'Name' and the 'Subject' too.
I mean there are two elements inside one container. One with class 'name' and one with the class 'subject'. When I click onto the bordered container I want to get the 'name' text's and write it into the element with the class resname. And the same thing with the subject. Any idea how to solve it?
var name = document.querySelectorAll('.name');
var gname = $('.resname');
var gsub = $('.ressubject');
$('.container').click(function() {
gname.text($(this).text());
gsub.text($(this).text());
});
.container {
border: 1px solid red;
cursor: pointer;
padding: 5px;
}
.resname, .ressubject {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="header">
<span class="name">firstname</span>
</div>
<div class="body">
<span class="subject">firstsubject</span>
</div>
</div>
<br>
<div class="container">
<div class="header">
<span class="name">secondname</span>
</div>
<div class="body">
<span class="subject">secondsubject</span>
</div>
</div>
<hr><br>
<div class="result">
<span>Name: <span class="resname"></span></span><br>
<span>Subject: <span class="ressubject"></span></span>
</div>
is that what you want?
const container = document.querySelector('.container');
const output = document.querySelector('.output');
const outputItemName = output.querySelector('.output-item > span[data-name]');
const outputItemSubject = output.querySelector('.output-item > span[data-subject]');
container.addEventListener('click', (e) => {
const containerItem = e.target.closest('.container-item');
if (!containerItem) return;
const { name, subject } = containerItem.dataset;
outputItemName.innerText = name;
outputItemSubject.innerText = subject;
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container-inner>* {
margin-bottom: 16px;
}
.container-inner>*:last-of-type {
margin-bottom: 0;
}
.container-item {
padding: 8px;
border: 1px solid black;
cursor: pointer;
}
.output {
margin-top: 16px;
}
<div class="container">
<div class="container-inner">
<div class="container-item" data-name="First name" data-subject="First subject">
<div class="container-item-name">First name</div>
<div class="container-item-subject">First subject</div>
</div>
<div class="container-item" data-name="Second name" data-subject="Second subject">
<div class="container-item-name">Second name</div>
<div class="container-item-subject">Second subject</div>
</div>
</div>
</div>
<div class="output">
<div class="output-inner">
<div class="output-item">
<span>Name:</span>
<span data-name></span>
</div>
<div class="output-item">
<span>Subject:</span>
<span data-subject></span>
</div>
</div>
</div>

How to correctly target by class name?

I am trying to practice some things on JS, I want to toggle a number of divs on click to change their color but I can't seem to target correctly the first one. It was fine when I did it by tag name but by class it doesnt seem to work. What am I doing wrong? Thanks!
EDIT. This is what my code looks like after your corrections.
<body>
<div class="container">
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
<div class="four">
</div>
</div>
<script src="script.js"></script>
</body>
let boxOne = document.getElementsByClassName("one")[0]
boxOne.onclick = function() {
alert("Clicked!")
}
I'm going to add that its better to assign an id and use getElementById if the selector is only used by one element.
let boxOne = document.getElementById("one");
let allBoxes = document.getElementsByClassName("square");
boxOne.onclick = function() {
alert("Clicked via ID");
}
const arr = [1, 2, 3];
arr.forEach(i => {
allBoxes[i].onclick = function() {
alert("Clicked via Class");
}
})
.square {
width: 100px;
height: 100px;
background: blue;
margin: 20px;
font-size: 50px;
color: white;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
cursor: pointer;
}
<body>
<div class="container">
<div class="square" id="one">
1
</div>
<div class="square" id="two">
2
</div>
<div class="square" id="three">
3
</div>
<div class="square" id="four">
4
</div>
</div>
</body>
With this line:document.getElementsByClassName(".one")[0]
you are already targeting the div, so change out this:
boxOne[0].onclick =
to this:
boxOne.onclick =
document.
getElementsByClassName returns array of elements with that className (without dot)
querySelector is used for css selectors (eg. ".one", "div.one")
querySelectorAll like 2. but returns array
let boxOne = document.getElementsByClassName("one")[0]
boxOne.onclick = function() {
alert("Clicked!")
}
div {
width: 100px;
height: 100px;
margin: 30px;
background: blue
}
<body>
<div class="container">
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
<div class="four">
</div>
</div>
<script src="script.js"></script>
</body>

Have dragula show drop position on hover over element

I have got a drag and drop functionality working with dragula so that it creates elements to drop the element into as a child. The idea is that you can make any element become a container to hold child items.
The problem I am having is that I don't want the drop locations to be visible until I have hovered my draggable element over. When dragging an element around the page, it renders all the parent containers - but i only really want that to appear when hovering over a spot where it can be created. Not so much of a problem with a small amount of items but when you got 100+ items its causes the page to grow and is quite jarring.
Below is what I have got so far. Any help is greatly appreciated!
var drake;
function setupDragula() {
var containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
var item = Array.prototype.slice.call(document.querySelectorAll(".js-structure-item"));
var opts = {
allowNestedContainers: true
};
opts = {
accepts: function(el, target, source, sibling) {
// prevent dragged containers from trying to drop inside itself
return !contains(el, target);
}
};
drake = dragula(
containers,
opts
).on('drag', function(el) {
prepareEmptyDropZones();
el.classList.remove('ex-moved');
}).on('drop', function(el, container, source) {
el.classList.add('ex-moved');
removeEmptyDropZones();
}).on('cancel', function(el, container, source) {
removeEmptyDropZones();
}).on('over', function(el, container) {
container.classList.add('editing');
el.classList.add('el-over');
}).on('out', function(el, container) {
container.classList.remove('editing');
el.classList.remove('el-over');
});
}
function contains(a, b) {
return a.contains ?
a != b && a.contains(b) :
!!(a.compareDocumentPosition(b) & 16);
}
function prepareEmptyDropZones() {
var item = querySelectorAllArray(".js-structure-item");
item.forEach(function(el) {
var firstParent = el.querySelector('.js-structure-parent');
if (firstParent === null) {
//el.classList.add('empty');
var emptyParent = document.createElement('div');
emptyParent.className = "js-structure-parent";
//emptyParent.classList.add('empty-drop-zone');
el.appendChild(emptyParent);
} else {
el.classList.remove('empty');
}
});
resetContainers();
}
function removeEmptyDropZones() {
var dropZones = querySelectorAllArray(".js-structure-parent");
dropZones.forEach(function(dropZone) {
if (dropZone.children.length == 0) {
dropZone.remove();
}
});
}
function resetContainers() {
drake.containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
}
function querySelectorAllArray(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
document.addEventListener("DOMContentLoaded", function(event) {
setupDragula();
});
.js-structure-item {
cursor: move;
}
.js-structure-item .container {
margin-bottom: 10px;
}
/*parent*/
.js-structure-parent {
padding: 0px 0px 0px 30px;
/*border: 1px solid red;
position: relative;*/
}
.js-structure-parent:empty,
.empty-drop-zone {
min-height: 20px;
border: 1px dashed #ccc;
}
.el-over {
background-color: green;
}
.js-structure-item.empty {
color: #666;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.min.js"></script>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Image file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Document file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 4
</div>
</div>
</div>
</div>
</div>
var drake;
function setupDragula() {
var containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
var item = Array.prototype.slice.call(document.querySelectorAll(".js-structure-item"));
var opts = {
allowNestedContainers: true
};
opts = {
accepts: function(el, target, source, sibling) {
// prevent dragged containers from trying to drop inside itself
return !contains(el, target);
}
};
drake = dragula(
containers,
opts
).on('drag', function(el) {
prepareEmptyDropZones();
el.classList.remove('ex-moved');
}).on('drop', function(el, container, source) {
el.classList.add('ex-moved');
removeEmptyDropZones();
}).on('cancel', function(el, container, source) {
removeEmptyDropZones();
}).on('over', function(el, container) {
container.classList.add('editing');
el.classList.add('el-over');
}).on('out', function(el, container) {
container.classList.remove('editing');
el.classList.remove('el-over');
});
}
function contains(a, b) {
return a.contains ?
a != b && a.contains(b) :
!!(a.compareDocumentPosition(b) & 16);
}
function prepareEmptyDropZones() {
var item = querySelectorAllArray(".js-structure-item");
item.forEach(function(el) {
var firstParent = el.querySelector('.js-structure-parent');
if (firstParent === null) {
//el.classList.add('empty');
var emptyParent = document.createElement('div');
emptyParent.className = "js-structure-parent";
//emptyParent.classList.add('empty-drop-zone');
el.appendChild(emptyParent);
} else {
el.classList.remove('empty');
}
});
resetContainers();
}
function removeEmptyDropZones() {
var dropZones = querySelectorAllArray(".js-structure-parent");
dropZones.forEach(function(dropZone) {
if (dropZone.children.length == 0) {
dropZone.remove();
}
});
}
function resetContainers() {
drake.containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
}
function querySelectorAllArray(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
document.addEventListener("DOMContentLoaded", function(event) {
setupDragula();
});
.js-structure-item {
cursor: move;
}
.js-structure-item .container {
margin-bottom: 10px;
}
/*parent*/
.js-structure-parent {
padding: 0px 0px 0px 30px;
/*border: 1px solid red;
position: relative;*/
}
.el-over {
background-color: green;
}
.js-structure-item.empty {
color: #666;
}
.gu-mirror {
position: fixed !important;
margin: 0 !important;
z-index: 9999 !important;
opacity: 0.8;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
}
.gu-hide {
display: none !important;
}
.gu-unselectable {
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
}
.js-structure-parent:empty,
.empty-drop-zone {
min-height: 6px;
}
.gu-transit {
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.min.js"></script>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Image file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Document file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 4
</div>
</div>
</div>
</div>
</div>
Try this :::
var drake;
function setupDragula() {
var containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
var item = Array.prototype.slice.call(document.querySelectorAll(".js-structure-item"));
var opts = {
allowNestedContainers: true
};
opts = {
accepts: function(el, target, source, sibling) {
// prevent dragged containers from trying to drop inside itself
return !contains(el, target);
}
};
drake = dragula(
containers,
opts
).on('drag', function(el) {
prepareEmptyDropZones();
el.classList.remove('ex-moved');
}).on('drop', function(el, container, source) {
el.classList.add('ex-moved');
removeEmptyDropZones();
}).on('cancel', function(el, container, source) {
removeEmptyDropZones();
}).on('over', function(el, container) {
container.classList.add('editing');
el.classList.add('el-over');
}).on('out', function(el, container) {
container.classList.remove('editing');
el.classList.remove('el-over');
});
}
function contains(a, b) {
return a.contains ?
a != b && a.contains(b) :
!!(a.compareDocumentPosition(b) & 16);
}
function prepareEmptyDropZones() {
var item = querySelectorAllArray(".js-structure-item");
item.forEach(function(el) {
var firstParent = el.querySelector('.js-structure-parent');
if (firstParent === null) {
//el.classList.add('empty');
var emptyParent = document.createElement('div');
emptyParent.className = "js-structure-parent";
//emptyParent.classList.add('empty-drop-zone');
el.appendChild(emptyParent);
} else {
el.classList.remove('empty');
}
});
resetContainers();
}
function removeEmptyDropZones() {
var dropZones = querySelectorAllArray(".js-structure-parent");
dropZones.forEach(function(dropZone) {
if (dropZone.children.length == 0) {
dropZone.remove();
}
});
}
function resetContainers() {
drake.containers = Array.prototype.slice.call(document.querySelectorAll(".js-structure-parent"));
}
function querySelectorAllArray(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector))
}
document.addEventListener("DOMContentLoaded", function(event) {
setupDragula();
});
.js-structure-item {
cursor: move;
}
.js-structure-item .container {
margin-bottom: 10px;
}
/*parent*/
.js-structure-parent {
padding: 0px 0px 0px 30px;
/*border: 1px solid red;
position: relative;*/
}
.el-over {
background-color: green;
}
.js-structure-item.empty {
color: #666;
}
.gu-mirror {
position: fixed !important;
margin: 0 !important;
z-index: 9999 !important;
opacity: 0.8;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
}
.gu-hide {
display: none !important;
}
.gu-unselectable {
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
user-select: none !important;
}
.gu-transit {
opacity: 0.2;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
filter: alpha(opacity=20);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.2/dragula.min.js"></script>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
File 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
File 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image Folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Image file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Image file 4
</div>
</div>
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document folder
</div>
<div class="js-structure-parent">
<div class="js-structure-item">
<div class="container">
Document file 1
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 2
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 3
</div>
</div>
<div class="js-structure-item">
<div class="container">
Document file 4
</div>
</div>
</div>
</div>
</div>

Javascript - set div display on click - ClassName not defined

I am trying to use the following function to change whether a div is shown or not, by clicking an image.
function showTxt(elementClass, nr) {
"use strict";
if (document.getElementByClassName(elementClass)[nr].style.display === "none") {
document.getElementByClassName(elementClass)[nr].style.display = "block";
} else {
document.getElementByClassName(elementClass)[nr].style.display = "none";
}
}
.employees{
width: 80%;
margin-left: 10%;
}
.employee{
width: 20%;
display: inline-block;
margin-left: 5%;
vertical-align: top;
margin-right: 5%;
}
.employee_img img{
width: 100%;
}
.employee_txt{
display: none;
}
<div class="employees">
<div class="employee">
<div class="employee_img">
<img src="resources/katerina.jpg" alt="katerina">
</div>
<div class="employee_txt" id="katerina"></div>
</div>
<div class="employee">
<div class="employee_img">
<img src="resources/sindre.jpg" alt="sindre">
</div>
<div class="employee_txt" id="sindre"></div>
</div>
<div class="employee">
<div class="employee_img" onclick="showTxt(employee_txt, 2)">
<img src="resources/daniel.jpg" alt="daniel">
</div>
<div class="employee_txt" id="daniel">
<p>this is me</p>
</div>
</div>
</div>
Stack's snippet tool shows the message: "Uncaught ReferenceError: employee_txt is not defined". And I have noe idea why.
Any help is appreciated.
A couple of things are wrong, it's getElementsByClassName, Elements being plural, and you need quotes around the string you're passing in your function call.
function showTxt(elementClass, nr) {
"use strict";
if (document.getElementsByClassName(elementClass)[nr].style.display === "none") {
document.getElementsByClassName(elementClass)[nr].style.display = "block";
} else {
document.getElementsByClassName(elementClass)[nr].style.display = "none";
}
}
.employees{
width: 80%;
margin-left: 10%;
}
.employee{
width: 20%;
display: inline-block;
margin-left: 5%;
vertical-align: top;
margin-right: 5%;
}
.employee_img img{
width: 100%;
}
.employee_txt{
display: none;
}
<div class="employees">
<div class="employee">
<div class="employee_img">
<img src="resources/katerina.jpg" alt="katerina">
</div>
<div class="employee_txt" id="katerina"></div>
</div>
<div class="employee">
<div class="employee_img">
<img src="resources/sindre.jpg" alt="sindre">
</div>
<div class="employee_txt" id="sindre"></div>
</div>
<div class="employee">
<div class="employee_img" onclick="showTxt('employee_txt', 2)">
<img src="resources/daniel.jpg" alt="daniel">
</div>
<div class="employee_txt" id="daniel" style="display:none;">
<p>this is me</p>
</div>
</div>
</div>
Your code
onclick="showTxt(employee_txt, 2)"
It is looking for the variable employee_txt not a string.
onclick="showTxt('employee_txt', 2)"
You have to call it
<div class="employee_img" onclick="showTxt('employee_tx', 2)">
<img src="resources/daniel.jpg" alt="daniel">
</div>
You need to use the function reference of showTxt instead of calling the function and assigning its result to the onClick handler.
To do so, use this:
onClick="showTxt.bind(showTxt, 'employee_txt', 2)"
This will return a new function that already has the 2 parameters bound to it so it can just be called as func().
I would also suggest you to use a variable inside of your showTxt function to store the result of the getElementsByClassName(classname)[index] call.

Categories