getElementById().style.display does not work - javascript

I made some js code for <div> to appear or disappear.
[src.js]
openSearch = () => {
var con = document.getElementById("search-bar");
if(con.style.display == 'none') {
con.style.display = 'block';
} else {
con.style.display = 'none';
}
}
[style.css]
#search-bar {
position: absolute;
height: 4em;
width: 20em;
background-color: white;
border: 1px solid black;
padding: 1.5rem;
right: 0;
display: none;
}
and add onclick="openSearch()" to <a> tag.
When I click the <a> tag first time, it doesn't work anything.
But click again, it works properly.
So I tried to console.log(document.getElementById("search-bar").style.display, it throws ""(blank).
I wonder that I defined display: none to search-bar but why initial style.display of search-bar is blank value?
And how can I fix it?

Alternatively, you can move the display style to another class and can toggle class.
openSearch = () => {
var con = document.getElementById("search-bar");
con.classList.toggle("hidden");
}
#search-bar {
position: absolute;
height: 4em;
width: 20em;
background-color: white;
border: 1px solid black;
padding: 1.5rem;
right: 0;
}
.hidden {
display: none;
}
<a onclick="openSearch()">Toggle</a>
<div id="search-bar" class="hidden">Some text here</div>

function openSearch()
{
var div = document.getElementById("search-bar");
if (div.style.display !== "none") {
div.style.display = "none";
}
else {
div.style.display = "block";
}
}

You could try initializing the style via js to none:
document.getElementById("search-bar").style.display = 'none';
When the page loads. My guess is that'll work.

[SOLVED]
First I add display: none to css file.
But after style="display: none" to a tag, it works properly.
Maybe I think there is loading priority, But I don't know why exactly.

when you set the display:none in css it innisial like display="". and not display=none. the result is the same, but if you check display='none' he will return false.. you can try it like this:
openSearch = () => {
var con = document.getElementById("search-bar");
if(con.style.display == '') {
con.style.display = 'block';
} else {
con.style.display = '';
}
}
and it will work fine

Use this line code:
if(con.style.display == 'none' || con.style.display == '') {
openSearch = () => {
var con = document.getElementById("search-bar");
if(con.style.display == 'none' || con.style.display == '') {
con.style.display = 'block';
} else {
con.style.display = 'none';
}
}
#search-bar {
position: absolute;
height: 4em;
width: 20em;
background-color: white;
border: 1px solid black;
padding: 1.5rem;
right: 0;
display: none;
}
<div id="search-bar">My Div</div>
<a onclick="openSearch()" href="#">Click</a>

Related

Failing to get condition to work with div?

I want to have the ball sized to the prompt of the user upon entering it and something doesn't work, can't tell what I'm doing wrong.
<style>
body {
background-color: black;
text-align: center;
}
h1 {
color: white;
}
div {
width: 100px;
height: 100px;
margin: auto;
margin-bottom: 10px;
border-radius: 50%;
transition: 0.3s;
line-height: 50px;
.ball4 {
background-color: brown;
}
</style>
<div class="ball4" onclick="onBall4Click()">
PROMPT
</div>
<script>
function onBall4Click() {
var ball4 = document.querySelector('.ball4');
var ball4Size = prompt("Size of ball? ");
if (ball4Size > 1000) {
alert("Too big!")
} else {
var ball4Size = size;
}
}
</script>
Thanks in advance to the helpers.
I feel like this is what you want with your JavaScript:
function onBall4Click() {
var ball4 = document.querySelector('.ball4');
var ball4Size = prompt("Size of ball? ");
if (ball4Size > 1000) {
alert("Too big!")
} else {
ball4.style.width = ball4Size;
ball4.style.height = ball4Size;
}
}
You were using an undefined variable rather than setting the actual size of the element. Also, I believe you still need to make the element a ball at this point because it is just a brown div right now.

How to show or hide a div when clicking on the same button?

I face a problem when i want to add interactivity on my leaflet map.
I have a button on my map
<button id="az">Availability Zones</button>
The thing i want is when i click on it, it show a square of informations on my map
So i have create a square
<div class="square" id='square'> </div>
CSS = .square{
z-index: 4000;
width: 100%;
height: 0;
padding-top: 100%;
background-color: #ccc;
position: absolute;
display: none;
}
And an other css class square with same properties but with a display: block
.squareclick{
z-index: 4000;
width: 30%;
weight: 30%;
padding: 0 25 30;
margin-left: 400px;
margin-bottom: 200px;
height: 0;
padding-top: 100%;
background-color: #ccc;
position: relative;
display: block;
}
Now, for opening this square on a button i've add some interactivity
var button = document.getElementById('az')
L.DomEvent.on(button,'click',function(e){
console.log('Button clicked')
});
L.DomEvent.on(button,'click',function(){
document.getElementById('square').setAttribute("class", "squareclick");
});
The thing is that that button works for opening the square, but not for closing (I know this is normal)
I've try that thing but it seems to not work
L.DomEvent.on(button,'click',function myFunction() {
var x = document.getElementById("square");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
I don't know how to add a second interactivity on the same button :(
If someone can help!
Thank you very much
What you can try doing is instead of directly checking whether the square is visible or not, you can set a variable to check. Change:
L.DomEvent.on(button,'click',function myFunction() {
var x = document.getElementById("square");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
To:
var shown = false;
L.DomEvent.on(button,'click',function myFunction() {
var x = document.getElementById("square");
if (shown == false) {
x.style.display = "block";
shown = true;
} else if (shown == true) {
x.style.display = "none";
shown = false;
}
}
The variable shown tells us at the start the square is not visible. Every time you click the button, the variable changes and so does the style. If the square was to be visible at the start, then you can simply change shown to true at the start of the script. See if that way works. :)
I recommand to only add a class to the square that changes the display: none style.
var button = document.getElementById('az')
var square = document.getElementById('square')
L.DomEvent.on(button,'click',function(e){
console.log('Button clicked')
if(L.DomUtil.hasClass(square,'show')){
L.DomUtil.removeClass(square,'show');
}else{
L.DomUtil.addClass(square,'show');
}
});
.square{
z-index: 4000;
width: 30%;
weight: 30%;
padding: 0 25 30;
margin-left: 400px;
margin-bottom: 200px;
height: 0;
padding-top: 100%;
background-color: #ccc;
position: absolute;
display: none;
}
.show{
display: block;
}
https://jsfiddle.net/falkedesign/v8tdzmhe/

Why the onclick only works if you click twice?

I was searching for autocomplete examples in pure javascript, and I found a pretty good example on JSFiddle, but it has a Bug that I'm trying to figure it out how to fix.
The autocomplete only autocompletes the text if you click at the paragraph twice
Code:
var db = [
"drawLine",
"drawCircle",
"drawCircleMore",
"fillLine",
"fillCircle",
"fillCircleMore"
];
function popupClearAndHide() {
autocomplete_result.innerHTML = "";
autocomplete_result.style.display = "none";
}
function updPopup() {
if (!autocomplete.value) {
popupClearAndHide();
return;
}
var a = new RegExp("^" + autocomplete.value, "i");
for (var x = 0, b = document.createDocumentFragment(), c = false; x < db.length; x++) {
if (a.test(db[x])) {
c = true;
var d = document.createElement("p");
d.innerText = db[x];
d.setAttribute("onclick", "autocomplete.value=this.innerText;autocomplete_result.innerHTML='';autocomplete_result.style.display='none';");
b.appendChild(d);
}
}
if (c == true) {
autocomplete_result.innerHTML = "";
autocomplete_result.style.display = "block";
autocomplete_result.appendChild(b);
return;
}
popupClearAndHide();
}
autocomplete.addEventListener("keyup", updPopup);
autocomplete.addEventListener("change", updPopup);
autocomplete.addEventListener("focus", updPopup);
#autocomplete {
border: 1px solid silver;
outline: none;
margin: 0;
background: #fff;
}
#autocomplete_result {
border: 1px solid silver;
border-top: 0;
position: absolute;
overflow: auto;
max-height: 93px;
background: #fff;
}
#autocomplete,
#autocomplete_result {
width: 200px;
box-sizing: border-box;
}
#autocomplete,
#autocomplete_result p {
padding: 4px;
margin: 0;
color: #000;
}
#autocomplete_result p:nth-child(2n+1) {
background: #f6f6f6;
}
#autocomplete_result p:hover {
background: #e5e5e5;
}
<input id="autocomplete" type="text" />
<div id="autocomplete_result" style="display: none;"></div>
On change event is trigger before the click event can complete
Removing the on change call would fix the issue. Great suggestion from the comment below by 'imvain2' to replace "keyup" event listener with "input" event listener. This would trigger on any input, not only "keyup".
Demo: https://jsfiddle.net/hexzero/qrwgh7pj/
autocomplete.addEventListener("input", updPopup);
autocomplete.addEventListener("focus", updPopup);

Remove An Element When One Exists

I'm back with my nooby Javascript questions. I'm working on form validation and I'm adding text to check if a name was inputted. The problem I'm running into is if I don't put a name but then I do, the message for not putting a name shows up with the other element and vice versa but im looking for a way to make it dissapear when another element is chosen. Is there some sort of way of preventing an element from showing when one is present? I appreciate you guys/girls taking time out of your day to help a noob out haha. :)
Code:
var complete = document.getElementById('button');
complete.addEventListener('click', validate);
function validate() {
var textBox = document.getElementById('name');
var red = document.getElementById('nah');
var green = document.getElementById('yah');
if (textBox.value === '') {
red.style.display = 'block';
} else {
green.style.display = 'block';
}
}
#nah {
display: none;
color: red;
}
#yah {
color: green;
display: none;
}
button {
display: block;
margin-top: 50px;
border: 0.1px solid red;
background: red;
color: white;
font-size: 30px;
padding: 10px;
cursor: pointer;
}
<input type="text" id="name">
<p id="nah">Please Enter Name!</p>
<p id="yah">Thank you!</p>
<button id="button">Complete Form</button>
When you show one message you need to hide the other one.
var complete = document.getElementById('button');
complete.addEventListener('click', validate);
function validate() {
var textBox = document.getElementById('name');
var red = document.getElementById('nah');
var green = document.getElementById('yah');
if (textBox.value === '') {
red.style.display = 'block';
green.style.display = 'none';
} else {
green.style.display = 'block';
red.style.display = 'none';
}
}
#nah {
display: none;
color: red;
}
#yah {
color: green;
display: none;
}
button {
display: block;
margin-top: 50px;
border: 0.1px solid red;
background: red;
color: white;
font-size: 30px;
padding: 10px;
cursor: pointer;
}
<input type="text" id="name">
<p id="nah">Please Enter Name!</p>
<p id="yah">Thank you!</p>
<button id="button">Complete Form</button>
Simplest way is to just hide the other messages during validation:
function validate() {
var textBox = document.getElementById('name');
var red = document.getElementById('nah');
var green = document.getElementById('yah');
if (textBox.value === '') {
red.style.display = 'block';
green.style.display = 'none'; //hide the other element
} else {
green.style.display = 'block';
red.style.display = 'none'; //hide the other element
}
}
You could do it in a more sophisticated way using data attributes to control visibility, but this is probably a good start.

How to hide div after append to another?

I've got some kind of drop down menu dynamically appending to differents divs. Problem is, when someone click on "close", then style.display = "none" wont work. I can change background, opacity, size but i cant hide it.
Code looks like this:
<style>
html, body{
height: 98%;
}
#editorViewport{
width: 90%;
height: 100%;
min-width: 400px;
min-height: 300px;
position: relative;
margin: 0 auto;
border: 1px solid red;
}
#movingElementsContainer{
display: none;
top: 0px;
left: 0px;
}
#addStartingElementBtn{
width: 60px;
height: 60px;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
#addStartingElementBtn:hover{
background-color: #c9eac6;
border: 1px solid grey;
cursor: pointer;
}
#elementsMenuContainer{
width: 150px;
border: 1px solid grey;
background-color: white;
min-height: 100px;
padding: 5px;
position: absolute;
z-index: 2;
display: none;
}
.elementOption{
width: 90%;
padding: 5px;
border: 1px solid grey;
}
.elementOption:hover{
border: 1px solid red;
cursor: pointer;
}
</style>
<body>
<div id="editorViewport">
<div id="addStartingElementBtn" data-Owner="starting" data-Side="starting" class="openElementsMenu">
Click!
</div>
</div>
<div id="movingElementsContainer">
<div id="elementsMenuContainer" data-Open="false" data-Owner="" data-Side="">
<div data-Kind="1" class="elementOption">
One
</div>
<div data-Kind="2" class="elementOption">
Two
</div>
<div data-Kind="3" class="elementOption">
Three
</div>
<div data-Kind="99" class="elementOption">
Close
</div>
</div>
</div>
</body>
<script type="text/javascript">
function prepareEventHandlers(){
var openElementsMenu = document.getElementsByClassName("openElementsMenu");
var event = window.attachEvent ? 'onclick' : 'click';
for(var i = 0; i < openElementsMenu.length; i++){
if(openElementsMenu[i].addEventListener){
openElementsMenu[i].addEventListener('click', elementsMenu, false);
}else{
openElementsMenu[i].attachEvent('onclick', elementsMenu);
}
}
var elementOption = document.getElementsByClassName("elementOption");
for(var i = 0; i < elementOption.length; i++){
if(elementOption[i].addEventListener){
elementOption[i].addEventListener('click', selectElementToCreate, false);
}else{
elementOption[i].attachEvent('onclick', selectElementToCreate);
}
}
}
window.onload = function(){
prepareEventHandlers();
}
var totalElements = 0;
var editorViewport = "editorViewport";
var selectedElementId = "";
var elementsMenu = function(){
var elementsMenu = document.getElementById("elementsMenuContainer")
this.appendChild(elementsMenu);
elementsMenu.style.display = "block";
elementsMenu.style.left = 61 + "px";
elementsMenu.style.top = "0px";
elementsMenu.setAttribute("data-Open", "true");
elementsMenu.setAttribute("data-Owner", this.getAttribute("data-Owner"));
elementsMenu.setAttribute("data-Side", this.getAttribute("data-Side"));
}
var selectElementToCreate = function(){
var dataKind = this.getAttribute('data-Kind');
var parentNode = document.getElementById(this.parentNode.id);
alert(dataKind)
if(dataKind == "99"){
parentNode.style.display = "none"
parentNode.setAttribute("data-Open", "false");
parentNode.setAttribute("data-Owner", "");
parentNode.setAttribute("data-Side", "");
}
}
</script>
Here is a JSFiddle
Many thanks for any advise!
var selectElementToCreate = function(e){
var dataKind = this.getAttribute('data-Kind');
var parentNode = document.getElementById(this.parentNode.id);
alert(dataKind)
if(dataKind == "99"){
console.log(parentNode);
parentNode.style.display = "none"
parentNode.setAttribute("data-Open", "false");
parentNode.setAttribute("data-Owner", "");
parentNode.setAttribute("data-Side", "");
alert("Wont Close :");
}
e.stopPropagation();
}
You are moving the element into the clicked element.
var elementsMenu = document.getElementById("elementsMenuContainer")
this.appendChild(elementsMenu);
At first the menu item's click handler is executed which sets the display property to none and as the click event bubbles then the event handler of the wrapper element is executed and sets the display property to block.
You should stop the propagation of the event using stopPropagation method of the event object.
var selectElementToCreate = function (event) {
event.stopPropagation();
var dataKind = this.getAttribute('data-Kind');
var parentNode = this.parentNode;
if (dataKind == "99") {
parentNode.style.display = "none";
// ...
}
}

Categories