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

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
}

Related

Classlist validation for unique selected item

So I'm trying to create a chat application like messenger.
When I press the button, a new conversation should be started. I want to add a list item in my overview bar on the left but there can only be one selected, and that one has the 'history-item-selected' classname. So every new convo gets that classname, while the others ones get another classname to change it's appearance but it won't work.
const newConvoButton = document.getElementById("newmessage");
const addNewConvo = (e) => {
e.preventDefault();
const myMessages = document.getElementById('history');
let newListItem = document.createElement('li');
newListItem.textContent = "user " + Math.floor(Math.random(2 - 100) * 100);
myMessages.appendChild(newListItem);
if (newListItem.classList = 'history-item-selected') {
newListItem.classList.add('history-item-selected');
} else {
newListItem.classList.add('history-item')
};
};
newConvoButton.addEventListener('click', addNewConvo);
<main>
<div id="top">
<span>
<h2>My conversations</h2>
</span>
<button type="submit" id="newmessage">+</button>
</div>
<div id="messagecontainer">
<ul id="history"></ul>
<id id="chatscreen">
<ul id="messages">
<li>yolo</li>
</ul>
<div id="messagebottom">
<input type="text" placeholder="Start met typen" size="28" height="auto"> <button type="submit">Send</button>
</div>
</id>
</div>
</main>
There is a "tautological" way to do what you are trying to do.
var addNewConvo = (e)=> {
var nodes = document.querySelectorAll(".history-item-selected");
nodes.forEach(function(elem) {
this.classList.remove("history-item-selected");
});
e.target.classList.add("history-item-selected");
}
In your CSS, you should have something like
.history-item {
/*Styles for history-item*/
}
.history-item.history-item-selected {
/*Styles for elements with both */
}

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')
}
});

Select In Stock Items

I'm creating a script to perform a click action to only select in-stock items. But I'm having a hard time selecting the content "Disponible"
HTML below:
<div class="top namePartPriceContainer">
<span id="InventoryStatus_OnlineStatus_691003" class="text inventoryStatus inv-status-3" itemprop="availability" href="https://schema.org/InStock" content="Disponible">In Stock
</span>
<div id="InventoryStatus_ShowLink_Section_691003" class="left available" style="display:none;">
<span class="text Select attributes to see availability">Select attributes to see availability
</span>
</div>
My JavaScript code:
var products = document.getElementById("dijit__WidgetBase_0");
var items = products.getElementsByTagName("li");
for (var i = 0; i < items.length; ++i) {
if(items[i].getElementsByTagName("span")[0].innerText === "In Stock"){
document.getElementById("productPageAdd2Cart").click();
}
}
getAttribute(); looks like the solution for you.
var content = document.getElementById('id').getAttribute('content');
and then:
if(content == 'Disponible') {
document.getElementById("productPageAdd2Cart").click();
}

Why am I receiving a null value for this.nextElementSibling?

I'm new to Javascript and I'm trying to figure out why the .nextElementSibling is not grabbing the next element in the listHere's my HTML structure:
<div class="container">
<div id="User1" class="area-left">
<h1>User 1: Sylvr</h1><br>
</div>
<div id="ItemTree" class="area-center">
<h1>Bolt: Item Tree</h1><br>
<ul class="col_ul">
<li><span>[+]</span> Bolt
<ul>
<li>Zap</li>
<li><span>[+]</span> Gift of Bolt</li>
<ul>
<li>Icy Runestone</li>
<li>Superior Sigil of Air</li>
<li><span>[+]</span> Gift of Metal</li>
<li><span>[+]</span> Gift of Lightning</li>
</ul>
<li><span>[+]</span> Gift of Mastery</li>
<li><span>[+]</span> Gift of Fortune</li>
</ul>
</li>
</ul>
</div>
<div id="User2" class="area-right">
<h1>User 2: Gylen</h1><br>
</div>
</div>
<div id="GuildBank" class="container-bottom">
<h1></h1>
</div>
Here's the script that I'm using:
<script>
window.onload = function () {
var li_ul = document.querySelectorAll(".col_ul li ul");
for (var i = 0; i < li_ul.length; i++) {
li_ul[i].style.display = "none"
};
var exp_li = document.querySelectorAll(".col_ul li > span");
for (var i = 0; i < exp_li.length; i++) {
exp_li[i].style.cursor = "pointer";
exp_li[i].onclick = showul;
};
function showul () {
nextul = this.nextElementSibling;
if(nextul.style.display == "block")
nextul.style.display = "none";
else
nextul.style.display = "block";
}}
</script>
For some reason, the this.nextElementSibling part works once but then gives me a null value for any of the other nested lists. Any help would be much appreciated, thanks.
You are getting null on this.nextElementSibling because there is no next sibling that's an element!!
<li><span>[+]</span> Gift of Bolt</li>
If you look at this line you will find that you have already closed the <li> tagand hence there is no sibling for the <span> and you get a null. To fix this, simply wrap the <ul> next to the <li> inside <li>...</li>.
Check this solution on JSFiddle

toggle div while hiding other divs

I have a side nav on the left hand side with different types of surgeries. They are all in an ul.
When you click on a surgery (ul li), a div will show up on the right hand side, displaying FAQ's for that specific surgery. Clicking on another link in the ul will hide the currently open div and display the one you've just clicked on.
I've managed to do this, but I would also like to toggle the visibility of the FAQ div when I click the same ul li link again.
<html>
<head>
<style>
#popup div { display:none; }
#popup div.show { display:block; }
ul#links li { cursor:pointer;}
</style>
</head>
<body>
<div class="sidenav">
<ul id="links">
<li id="armlift">Arm Lift</li>
<li id="liposuction">Liposuction</li>
<li id="tummytuck">Tummy Tuck</li>
<li id="postgastric">Post-Gastric Bypass Surgery</li>
</ul>
</div>
<div id="popup">
<div id="a_armlift">
<span class="faq_header">Arm Lift</span>
<p class="treatment_question">What is a an Arm Lift?</p>
<div class="treatment_answer">This surgery removes excess...</div>
<p class="treatment_question">What should I know?</p>
<div class="treatment_answer">An incision is made...</div>
</div>
<div id="a_liposuction">
<span class="faq_header">Liposuction Lift</span>
<p class="treatment_question">What is a Liposuction?</p>
<div class="treatment_answer">Liposuction is the removal...</div>
<p class="treatment_question">What should I know?</p>
<div class="treatment_answer">Ideal candidates for...</div>
</div>
<div id="a_tummytuck">
<span class="faq_header">Tummy Tuck</span>
<p class="treatment_question">What is a Tummy Tuck?</p>
<div class="treatment_answer">A tummy tuck tightens...</div>
<p class="treatment_question">What is a Mini Tummy Tuck?</p>
<div class="treatment_answer">A mini-tuck is a...</div>
</div>
<div id="a_postgastric">
<span class="faq_header">Post-Gastric Bypass Surgery</span>
<p class="treatment_question">What is a Post-Gastric Bypass Surgery?</p>
<div class="treatment_answer">Gastric bypass surgery removes...</div>
<p class="treatment_question">What should I know?</p>
<div class="treatment_answer">Each patient has...</div>
</div>
</div>
<script type="text/javascript">
var links_ul = document.getElementById('links');
for (var i = 0; i < links_ul.children.length; i++) {
links_ul.children[i].onclick = function(ev) {
s = document.getElementById('a_' + this.id);
popup = document.getElementsByClassName('show');
for (var j = 0; j < popup.length; j++) {
popup[j].className = '';
}
s.className = 'show';
};
}
</script>
</body>
</html>
I would recommend looking into doing this differently. There are many plugins available that do this sort of thing.
But, here's the answer to your question: http://jsfiddle.net/6Vku8/1/
for (var i = 0; i < links_ul.children.length; i++) {
links_ul.children[i].onclick = function(ev) {
s = document.getElementById('a_' + this.id);
popup = document.getElementsByClassName('show');
var shown = s.className == 'show';
for (var j = 0; j < popup.length; j++) {
popup[j].className = '';
}
s.className = shown ? '' : 'show';
};
}​
You need to find out whether or not the div is "shown" before hiding all of the divs.

Categories