Dropdown not working the second time when clicked using dom - javascript

I have made a navigation tab with buttons, and a side-button which displays a list of files when I click the nav button.
Visual representation:
check1 check2 check3
dropdown (assuming check1 is clicked)
1.txt
2.txt
All the information comes up properly when I click on these checks in the console. but when I click on the button second time, it doesn't display any dropdown even though it shows correct information in console.
Code for function to create dropdown:
function add_pvt_dropdown(files) {
const dropdown_div = document.getElementById("pvt_list_dropdown");
//console.log(dropdown_div.childNodes[2])
console.log("these are the child nodes \n:", dropdown_div.childNodes, "and this is the lenght", dropdown_div.childNodes.length)
if (dropdown_div.childNodes[2])
dropdown_div.removeChild(dropdown_div.childNodes[2])
console.log(dropdown_div)
const UL = document.createElement("ul");
//files = localStorage.getItem('all_file_in_dir').split(',')
if (typeof (files) === undefined && files == null) {
alert("choose something")
} else {
UL.setAttribute("class", "dropdown-menu");
UL.setAttribute("id", "pvt_option");
UL.setAttribute("aria-labelledby", "dropdownMenuButton");
files.forEach(val => {
if (val.includes('CSV_')) {
var li = document.createElement('li');
var a = document.createElement('a');
a.setAttribute('class', "dropdown-item")
a.setAttribute('id', val)
li.appendChild(a);
UL.appendChild(li)
t = document.createTextNode(val);
a.innerHTML = a.innerHTML + val;
console.log(a.innerHTML)
}
});
dropdown_div.appendChild(UL)
}
}
HTML code
<div id="pvt_list_dropdown" class="dropdown" data-toggle="dropdown" data-bs-toggle="dropdown" data-bs-toggle="dropdown" >
<button class="btn btn-secondary dropdown-toggle btn-sm" type="button" id="dropdownMenuButtonPvt" data-toggle="dropdown" data-bs-toggle="dropdown" aria-expanded="false">
List
</button>
</div>
Functionality: when I click on the navigation buttons, it takes all the files from a particular directory and shows as dropdown. As mentioned, it works just once, but when I click any other button or the same button twice, nothing is shows up in the dropdown.
Further information: I checked that it may be an arrangement issue with js and bootstrap but even correcting that doesn't help:
<script src="https://unpkg.com/#popperjs/core#2"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
how information is shown for that element:
<div id="pvt_list_dropdown" class="dropdown">
<button class="btn btn-secondary dropdown-toggle btn-sm" type="button" id="dropdownMenuButtonPvt" data-bs-toggle="dropdown" aria-expanded="false">List</button>
<ul class="dropdown-menu" id="pvt_option" aria-labelledby="dropdownMenuButton">
<li>
<a class="dropdown-item" id="f1.csv">f1.csv
</a>
</li>
<li>
<a class="dropdown-item" id="f2.csv">f2.csv
</a>
</li>
</ul>
</div>
Edit:
information on how events are triggered:
the menu bar is called when DOM is loaded:
document.addEventListener("DOMContentLoaded", menu_tags)
menu_tags is a function that will dynamically create the menu using create an element
function menu_tags() {
var check = ["check1",
"check2"
]
sub_checks = [
"sub_checks1"
]
var toadd = document.createDocumentFragment();
var i;
for (let i = 0; i < check.length; i++) {
var newLi = document.createElement('a');
newLi.href = "#" + check[i];
newLi.innerHTML = check[i];
newLi.id = check[i];
newLi.className = "tablinks"
newLi.onclick = function() {open(event, check[i])};
// if(lib_verify_check[i] == "lib-checker"){
// }
toadd.appendChild(newLi);
}
document.getElementById("myTopnav").appendChild(toadd)
}
The open function will fetch the information for files for selected check
function open(event, checkname){
var i, tabcontent, tablinks;
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace("active", "");
}
event.currentTarget.className += " active";
console.log(event.currentTarget.id)
localStorage.setItem('selected_check', event.currentTarget.id)
// Exists.
if(event.currentTarget.id){
get_files()
console.log("changed")
}
//localStorage.getItem('get_files')
}
in the get_files() function, all the file information will be stored and that information will be displayed in dropdown.
Please find the fiddle link below:
Note that get_files wont work in fiddle, this is for checking the functionality:
fiddle_link

Related

How can I check two conditions by clicking link and confirm pop window?

I'm new to JavaScript and have 2 html links:
<li><a class="dropdown-item confirm" href="#">wtdata</a></li>
<li><a class="dropdown-item confirm" href="#">ftdata</a></li>
The first step is getting the specific text value by clicking each link. For example, if I click the first link I will get the text wtdata. If I click the second link, I get the text ftdata. I have completed this step by:
<script>
var myFunction = function() {
var attribute = this.innerHTML;
alert(attribute);
};
var elements = document.getElementsByClassName("dropdown-item");
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', myFunction, false);
}
</script>
After clicking the link in last step, a Bootstrap modal will automatically pop out which has 2 buttons. This is a built-in Bootstrap function, already done. The buttons are:
<button id='cancel_btn'>Cancel</button>
<button id='confirm_btn'>Confirm</button>
The second step is:
If in the first step link wtdata is clicked and Confirm button in pop windows has been clicked,then replace the href value of link wtdata with 'wtdata_url'.
Same as link ftdata,if
in the first step link ftdata is clicked and Confirm button in pop window has been clicked ,replace the href value of link ftdata with 'ftdata_url'.
How to complete the second step?I have tried build a function to return the specific text that has been clicked ,but I can't get the return value:
<script>
function getLinkname(cl){
var elements = document.getElementsByClassName(cl);
var getText = function() {
var attribute = this.innerHTML;
document.getElementById("staticBackdropLabel").innerHTML='Run ' + attribute + ' ?';
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', getText, false);
}
return attribute;
}
var linkname = getLinkname('confirm');
console.log(linkname);
</script>
error:
Uncaught ReferenceError: attribute is not defined
at getLinkname ((index):159:1)
This example I wrote is based on my undertanding about your question.
📌 I use the id attribute, because it is a simple way.
📌 If you want to change innerText of <a/> tag dynamically, the better way is to produce your <ul/> link list by JavaScript.
function clickATag (e) {
document.getElementById('input').value = e.innerText
document.getElementById('aTagId').innerText = e.id
var myModal = getMyModal();
myModal.show()
}
function clickButton (e) {
const aTagId = document.getElementById('aTagId').innerText;
const a = document.getElementById(aTagId);
a.innerText = document.getElementById("input").value;
const result = document.getElementById('result');
result.innerText = "new url: " + document.getElementById("input").value;
}
function getMyModal () {
var myModal = new bootstrap.Modal(document.getElementById('myModal'), {
keyboard: false
})
return myModal;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<ul>
<li><a id="a1" class="dropdown-item confirm" href="#" onclick="clickATag(this)">wtdata</a></li>
<li><a id="a2" class="dropdown-item confirm" href="#" onclick="clickATag(this)">ftdata</a></li>
</ul>
<div id="myModal" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input id="input" />
<p id="result">new url:</p>
<p id="aTagId" hidden></p>
<p>Buttons</p>
<button id='cancel_btn' type="button" class="btn btn-primary" onclick="clickButton(this)">Confirm</button>
<button id='confirm_btn' type="button" class="btn btn-secondary">Cancel</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

Remove class if id's the correct ID

Looking to remove a class if a certain button is clicked.
<div class="slide-container">
<section class="about" id="slide-0">
<div class="menu-total">
<nav class="nav">
<button class="nav_link home" onclick="slideTo('slide-2')">HOME</button>
<button class="nav_link about" onclick="slideTo('slide-0')">ABOUT</button>
<button class="nav_link fun-stuff" onclick="slideTo('slide-1')">FUN STUFF</button>
<button class="nav_link professional" onclick="slideTo('slide-3')">PROFESSIONAL</button>
<button class="nav_link contact" onclick="slideTo('slide-4')">CONTACT</button>
</nav>
<div class="hamburger">
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
</div>
</div>
The one I want to remove the class on is the HOME button. So "slideTo('slide-2)". If it's clicked on the others then the class is kept. I believe someone is either wrong with my loop or not getting the ID correctly of the items/
function slideTo(slideId) {
const slide = document.getElementById(slideId);
slide.scrollIntoView({
behavior: 'smooth'
})
// above this line works fine
let nonHome = document.querySelectorAll('.slide-container section');
let nonHomeID = document.getElementById('slide-2');
var i;
setTimeout(function(){
for (i=0; i < nonHome.length; i++ ){
// i believe it's somewhere here it is wrong
if (nonHome[i].id != nonHomeID){
nonHome[i].classList.add("nav-visibility");
} else{
nonHomeID.classList.remove("nav-visibility");
}
}
}, 1000)
}
If you can use jquery library, you can write in the HTML:
<button class="nav_link" data-value="home">HOME</button>
...
and then in the JS code:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // Get the data-value clicked
$(".nav_link").each(function() { // Loop through all elements of the class 'nav-link'
var v = $(this).data("value");
if (v == valueClicked) {
$(this).removeClass("nav-visibility");
} else {
$(this).addClass("nav-visibility");
}
)
}
Not much simpler, but the HTML is cleaner.
Simpler version if it is not required to browse through all buttons at each button click:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // The value of the button clicked by the user
if (valueClicked == "home") {
$(this).removeClass("nav-visibility");
console.log('remove')
} else { $(this).addClass("nav-visibility");
console.log('add')
}
});

Populating Drop Menu from Array Using JavaScript

I need to dynamically generate a drop-menu list from an array via JavaScript. I'm getting close, but while I can populate the array elements into the Bootstrap-enabled drop-menu that appears on my index.html page, I cannot select those individual elements that show up as drop menu items. I need to edit my code so I can click on one of those elements and run my second function, that populates the selection to an input field.
First, here's my script to iterate over the array:
<script>
let select = document.getElementById("selectJob");
let options = ["Job 1", "Job 2", "Job 3", "Job 4", "Job 5"];
for (let i = 0; i < options.length; i++) {
let opt = options[i];
let el = document.createElement("option");
el.textContent = opt;
el.value = opt;
select.appendChild(el);
}
</script>
And here's the second script I use:
<script>
function populateJobVal(val) {
document.getElementById("selection").value = val;
}
</script>
And here's the drop-menu section in my HTML where I'm trying to use this:
<div class="dropdown">
<button class="btn btn-default btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
Select Job Type to Schedule
<span class="caret"></span></button>
<ul class="dropdown-menu" id="selectJob">
<li>
<a href="#" role="button" onclick="populateJobVal(selectJob)" class="btn btn-link">
</a>
</li>
</ul>
</div>
Notice I am adding the "id" to the <ul> element. Should it be going elsewhere? I did try putting the "id" on the <li> element, but that makes all the array elements one clickable field, rather than each one being clickable.
Right now, when I click on the drop-menu button, the different jobs do appear. However, they are not individually clickable.
What do I need to edit in my code to make each element a clickable link?
To match what you have templated, you need to do the following:
let select = document.getElementById("selectJob");
let options = ["Job 1", "Job 2", "Job 3", "Job 4", "Job 5"];
for (let i = 0; i < options.length; i++) {
let opt = options[i];
let a = document.createElement("a");
a.textContent = opt;
a.setAttribute('href', '#');
a.setAttribute('onclick', 'populateJobVal(selectJob)');
a.setAttribute('class', 'btn btn-link');
let li = document.createElement("li");
li.appendChild(a);
select.appendChild(li);
}
function populateJobVal(val) {
document.getElementById("selection").value = val;
}
<div class="dropdown">
<button class="btn btn-default btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
Select Job Type to Schedule
<span class="caret"></span></button>
<ul class="dropdown-menu" id="selectJob">
</ul>
</div>

Dynamically created dropdown using xml data is not working properly?

My requirement is to create bootstrap dropdown from the xml data received from the backed i done that but i cant able to select any particular element in the list please help me to fix this.
Html content
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul class="dropdown-menu">
<span id="demo"></span>
</ul>
</div>
JS content
var abc = "<getexternalworkloads>Cinebench,3DMark11,Furmark,Others<getexternalworkloads>"
if (abc != "") {
abc = abc.replace(new RegExp("<getexternalworkloads>", "g"), "");
abc = abc.split(",");
array = [];
array = array.concat(abc);
var text = "";
var i;
for (i = 0; i < array.length; i++) {
text += array[i] + "<br>";
afg = '<li >'+text+'</li>'
}
document.getElementById("demo").innerHTML = afg;
The out put i a
First of all your existing code was full of errors. But instead of correcting all, lets start by using JQuery. Since you are using Bootstrap there is no harm in that.
$(document).ready(function(){
var abc = "<getexternalworkloads>Cinebench,3DMark11,Furmark,Others<getexternalworkloads>"
if (abc != "") {
abc = abc.replace("<getexternalworkloads>", "").split(",")
.forEach( function(el, index) {
$("#demo").append('<a class="dropdown-item" href="#">'+el+'</a>');
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
<span class="caret"></span></button>
<ul id="demo" class="dropdown-menu">
</ul>
</div>
PS: In Bootstrap, classes are important, meaning you don't
neceserallly have to use <ul or <li> tags to get what you need.
Also, in your code it seems that you are overusing variables. Try to
avoid that.

Unable to disable `<li>` elements by setting `disable` property to `true`

I'm trying to make the rest of my chat room app disabled while a modal is open. I've been using element.disable = true to disable the buttons and this has worked. I have a ul where each li is the name of a chat room that is clickable and opens up its respective chat room in another container. I'm trying to disable the lis using the same disable.true method. I'm using a for loop to iterate through the array of lis, but it isn't working.
I used console.log to view the variable with the array stored in it (var lis) as well as the console.log(lis.length). The console shows that the array has a length of 5 but returns lis.length as 0.
Would be much appreciated if someone could tell me what I'm doing incorrectly.
HTML:
<div class"home-template" id="home">
<div class="rooms-container">
<h1 class="app-title">Bloc Chat</h1>
<ul id="rooms-list">
<li class="room-item" id="room-item" ng-repeat="chat in home.chatRooms">
{{ chat.$value }}
</li>
</ul>
<button class="btn btn-warning" id="new-room-button" type="button" ng-click="home.open()">New room</button>
<button class="btn btn-warning" id="delete-cookies-button" type="button" ng-click="home.deleteCookies()">Delete Cookie for testing</button>
</div>
<div class="messages-container">
<h1 class="current-room" ng-bind="home.activeRoom"></h1>
<ul class="messages-list">
<li class="message-bubble" ng-repeat="message in home.messages">
<div class="username">{{ message.username }}</div>
<div class="sentAt">{{ message.sentAt }}</div>
<div class="content">{{ message.content }}</div>
</li>
</ul>
</div>
</div>
JavaScript in a home controller:
home.cookieDisplay = $cookies.get('blocChatCurrentUser');
var modals = document.getElementsByClassName('modal');
var lis = document.getElementsByClassName('room-item');
var newButton = document.getElementById('new-room-button');
var delButton = document.getElementById('delete-cookies-button');
if (modals.length === 0) {
newButton.disabled = false;
delButton.disabled = false;
for (var i = 0; i < lis.length; i++) {
lis[i].disabled.false;
}
} else if (modals.length !== 0) {
newButton.disabled = true;
delButton.disabled = true;
for (var i = 0; i < lis.length; i++) {
// lis[i].setAttribute('display', 'none');
lis[i].disabled.true;
}
}
Here's what my console looks like:
You can't disable the li itself.
You can either disable the anchor tag (a) in it for example like this (refernece):
document.getElementById("tab_c").childNodes[0].onclick = function() {return false;};​
Or you can set pointer-events:noneas it has been done using CSS (reference):
.disabled {
pointer-events:none; //This makes it not clickable
opacity:0.6; //This grays it out to look disabled
}

Categories