NWJS JS script not functioning right - javascript

Im using JS to make divs display as block or none onclick of certain inputs. When i only have it working for one input the scripts work find, but as soon as i impliment the code for the second input it glitches out and both buttons open up the div thats only supposed to work for the second button.
Some of my code:
<span name="FaviconSPAN" id="FaviconSPAN" class="FaviconSPAN" OnClick="showOrHide()">
<img src="ASSETS/IMAGES/FAVICON1.png" alt="FAVICON" name="FaviconPNG" id="FaviconPNG" class="FaviconPNG" />
</span>
<div name="SoftMenuWrapper1" id="SoftMenuWrapper1" class="SoftMenuWrapper1">
<input type="button" value="Favorites" name="SoftMenuInput1" id="SoftMenuInput1" class="SoftMenuInput1" ONCLICK="ShowAndHide()" />
<div name="SoftMenuContent1" id="SoftMenuContent1" class="SoftMenuContent1">
Link 1
Link 1
Link 1
</div>
</div>
<script type="text/javascript">
var faqPage = document.getElementById('SoftMenuContent1');
function showDiv() {
faqPage.style.display = "block";
}
function closeDiv() {
faqPage.style.display = "none";
}
function showOrHide() {
if (faqPage.style.display === "block") {
closeDiv()
}
else {
showDiv()
}
}
</script>
<SCRIPT>
function ShowAndHide() {
var x = document.getElementById('SectionName');
if (x.style.display == 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
</SCRIPT>

First off the markup looks kinda messy. You don't need to add an ID, name, and class to everything. Only add those things if you need them.
name is rarely used, it's a way to connect to HTML elements. Like connected radio dials. You probably don't need this at all in this code.
class this should only be used if you need to add a specific CSS classname to adjust the styles. If you are not doing that, don't include it.
id should be assigned to a unique value that only occurs once on the page. it can be used to auto-scroll to that position of the page if the url contains #whatever and that matches an element with id="whatever". Though it is more commonly used just to target a specific element in your JavaScript. If you aren't doing either of those things, don't add it.
Another problem you have is order of execution. You can either define your JS first (<script> at the top) and then reference the functions with onclick in the HTML, or (more commonly), define your HTML first with ID's, then have your <script> at the bottom targeting the IDs (document.getElementById('asdf')).
Here is a cleaner version of your code.
<span id="faviconContainer">
<img src="assets/images/favicon1.png" alt="Image of an icon" />
</span>
<div>
<input type="button" value="Favorites" id="softMenuInput" />
<div id="faqPage">
Link 1
Link 2
Link 3
</div>
</div>
<script type="text/javascript">
/**
* Takes in an ID to find an element on the page, then shows/hides it.
*
* #param {string} id The element's ID
*/
function toggle (id) {
var el = document.getElementById(id);
if (el.style.display === 'block') {
el.style.display = 'none';
} else {
el.style.display = 'block';
}
}
var faviconContainer = document.getElementById('faviconContainer');
var softMenuInput = document.getElementById('softMenuInput');
faviconContainer.addEventListener('click', function () {
toggle('faqPage');
});
softMenuInput.addEventListener('click', function () {
toggle('sectionName');
});
</script>
This question isn't related to NW.js at all. It's just basic HTML and JavaScript.
I recommend you follow these resources to improve your skills. You can also rely on the world's largest programming community (HTML/JS) to ask these questions. Then when you have NW.js specific things, you can ask those here.
https://marksheet.io - HTML/CSS/Sass
https://freeCodeCamp.org - JavaScript

Related

Why does my JS function only manipulate one <div> that is assigned to the class instead of all?

I have this JS function that is supposed to initially hide a that has the class name "tw" and when clicked on a button it should make it visible. However, whenever I click the button it only changes the visibility of one div. I have 4. How can I fix this?
function myFunction(){
var elms = document.getElementsByClassName("tw");
Array.from(elms).forEach((x) => {
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
})
}
https://jsfiddle.net/qm8bxryh/307/
Here's the fiddle
I copied your code into the context of a very simple page (see below) and it seems to work...I might have missed something, but could the issue be elsewhere in your project? Perhaps investigating it piece by piece in the browser console could help.
<!DOCTYPE html>
<html>
<script>
function myFunction(){
var elms = document.getElementsByClassName("tw");
Array.from(elms).forEach((x) => {
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
})
}
</script>
<body>
<button onclick="myFunction()">Click me</button>
<div class="tw">1</div>
<div class="tw" style="display: block;">2</div>
<div class="tw">3</div>
<div class="tw" style="display: block;">4</div>
</body>
</html>
There is no display value set as default, so when you try to access it on an element where you never used display in css or style it returns undefined or nothing
Thats why on the first button click nothing happens if no element has any display, then due to your function all of them get through the else display: block and on the second click the all toggle
What i like to do is creating a class like displayNone
so in css:
.displayNone{
display:none;
}
then whenever you wanna make an element invisible give it this class and then when you click the button just remove the class and all elements become visible
so like this in your function:
function myFunction() {
var elms = document.getElementsByClassName("tw");
console.log(elms);
console.log(Array.from(elms));
Array.from(elms).forEach((x) => x.classList.remove('displayNone')); // just remove the class
}
alternatively you can also use the classList.toggle('displayNone) so it switches between display none and its inital display
I would keep styling in the CSS realm and toggle a class in JS to display the element. Also when you return a nodeList using querySelectorAll() it is in array form already.
Add a css class to the CSS:
.display {
display: block;
}
Then your JS function could be a lot more streamlined with toggle()
let elms = document.querySelectorAll(".tw");
function myFunction() {
elms.forEach(el => el.classList.toggle('display'))
}
JSFiddle

Link to another page at an anchor point and also show div

I want to have a single link that will take you to a different HTML page, down to a specific anchor tag, and also show a div that would be hidden by default.
I know how to link to another page and to an anchor on that page.
Link
On anotherpage.html, I have code to show that div.
<a onclick="toggle_visibility('hiddendiv');">Show div</a>
The Javascript for that is this:
<script type="text/javascript">
<!--
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
//-->
</script>
But I don't know how I could get the first link to also do what the second link is doing. Is this possible? This is for a local site, so I think I'm limited to just HTML, Javascript, and CSS.
Edit: I'm going to use this with Tipue Search (http://www.tipue.com/slide/). I'm going to have the search results point to specific sections on specific pages which have divs that are hidden by default. But in those sections, there are buttons to show those divs. I also included the Javascript I'm using for that above.
The HTML page with the second link either has a <script> tag pointing to an external javascript file providing the toggle_visiblility function or that function is defined directly on the page.
If you add the function definition either by linking to the javascript file <script src="myscripts.js"></script> or copy the definition directly into a <script> tag.
Once the toggle_visibility function is available on your page, the first link can read simply Link , obviously replacing hiddendiv with the appropriate string.
can you please check this project at: https://github.com/nezirz/anchor_scroll
First page contains only link to second one:
<div>
go to index2 and show diw
</div>
And second page contain this code:
<div>
<div id="anchor1" style="background-color:blue; height:500px;">
</div>
</div>
<div>
<div id="anchor2" style="background-color:green; height:400px;display: none;">
</div>
</div>
<div>
<div id="anchor3" style="background-color:red; height:200px;">
</div>
</div>
<script>
window.onload = function() {
var anchor = window.location.hash.substr(1);
console.log(anchor);
setTimeout(function(){
myFunction(anchor);
Element.prototype.documentOffsetTop = function () {
return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop() : 0 );
};
var top = document.getElementById( anchor ).documentOffsetTop() - (window.innerHeight / 2 );
window.scrollTo( 0, top );
}, 2000);
function myFunction(element) {
console.log(element);
var x = document.getElementById(element);
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
};
</script>
This is only proof of concept, please update it to your exact requirement. I think that it is not complicated to you.

div#d1 toggle on p#1 click - howTo?

I am trying to toggle a div when its name is clicked.
I have multiple coupls like that in my page, and I want it to work as
"when <p id= "d2"> is clicked => <div id="d2"> is toggled".
I tried those functions:
$(document).ready(function(){
$("p").click(function(){
$("div#" + $(this).attr('id')).toggle();
});
});
function rgt() {
//document.body.innerHTML = "";
var id = "d" + this.id;
var situation = document.getElementById(id).style.display;
if (situation == "none") {
situation = "block";
}
else {
situation = "none";
}
}
function showHide(theId) {
if (document.getElementById("d" + theId).style.display == "none") {
document.getElementById("d" + theId).style.display = "block";
}
else {
document.getElementById("d" + theId).style.display = "none";
}
}
I can't make it Work!!! Why is it?
the browser says:"no 'display' property for null"...
I will be more than happy to solve it with simple jquery
Ensure Your id Attributes Are Unique
Assuming that your id attributes are unique, which they are required to be per the specification:
The id attribute specifies its element's unique identifier (ID). The
value must be unique amongst all the IDs in the element's home subtree
and must contain at least one character. The value must not contain
any space characters.
You should consider renaming your id attributes to d{n} and your paragraphs to p{n} respectively as seen below :
<button id='p1'>p1</button> <button id='p2'>p2</button> <button id='p3'>p3</button>
<div id='d1'><pre>d1</pre></div>
<div id='d2'><pre>d2</pre></div>
<div id='d3'><pre>d3</pre></div>
which would allow you to use the following function to handle your toggle operations :
$(function(){
// When an ID that starts with P is clicked
$('[id^="p"]').click(function(){
// Get the proper number for it
var id = parseInt($(this).attr('id').replace(/\D/g,''));
// Now that you have the ID, use it to toggle the appropriate <div>
$('#d' + id).toggle();
})
});
Example Using Unique IDs
You can see an interactive example of this approach here and demonstrated below :
Consider Using data-* Attributes
HTML supports the use of data attributes that can be useful for targeting specific elements through jQuery and associating them to other actions. For instance, if you create an attribute on each of your "p" elements as follows :
<button data-toggles='d1'>p1</button>
<button data-toggles='d2'>p2</button>
<button data-toggles='d3'>p3</button>
and then simply change your jQuery to use those as selectors :
$(function(){
// When an element with a "toggles" attribute is clicked
$('[data-toggles]').click(function(){
// Then toggle its target
$('#' + $(this).data('toggles')).toggle();
});
});
Is this you are looking?
$("#p1").on("click", function() {
$("#d1").toggle();
});
js fiddle: https://jsfiddle.net/Jomet/09yehw9y/
jQuery(function($){
var $toggles = $('.divToggle');
var $togglables = $('.togglableDiv');
$toggles.on('click', function(){
//get the div at the same index as the p, and toggle it
$togglables.eq($toggles.index(this)).toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="divToggle">Show Me 1</p>
<p class="divToggle">Show Me 2</p>
<p class="divToggle">Show Me 3</p>
<div class="togglableDiv">Weeee 1</div>
<div class="togglableDiv">Weeee 2</div>
<div class="togglableDiv">Weeee 3</div>
Minimal approach using classes. This solution assumes the order of the p elements in the dom are in the same order as the divs are in the order. They do not have to be contiguous, but the order does matter with this solution.
ids are not the droids you are looking for.
An id needs to be unique. If you want to classify something one would suggest to use classes. You can actually use serveral of them for some fancy stuff. How about something like this:
<p class="toggle one">one</p>
<div class="toggle one" style="display:none">content one</div>
Straight forward. Every element that is a switch or switchable gets the class toggle. Each pair of switch and switchable(s) gets an additional identifier (like one, two, ...).
Simple JScript Implementation:
Now how about not using JQuery to work with that? Sure it i$ handy, but it hides all that neat stuff one would eventually like to learn her/himself!
var myToggle = {};
(function(module) {
"use strict";
(function init() {
var elements = document.getElementsByClassName("toggle");
var element;
var i = elements.length;
while (i) {
i -= 1;
element = elements[i].className;
elements[i].setAttribute("onclick", "myToggle.swap(\"" + element + "\")");
}
}());
module.swap = function(element) {
var couple = document.getElementsByClassName(element);
var i = couple.length;
while (i) {
i -= 1;
if (couple[i].style.display === "none" && couple[i].tagName === "DIV") {
couple[i].style.display = "block";
} else if (couple[i].tagName === "DIV") {
couple[i].style.display = "none";
}
}
};
}(myToggle));
<p class="toggle one">one</p>
<div class="toggle one" style="display:none">content one</div>
<p class="toggle two">two</p>
<div class="toggle two" style="display:none">content two 1</div>
<div class="toggle two" style="display:none">content two 2</div>
var myToggle = {} is the object we use to keep our little program contained. It prevents that our code conflicts with other declarations. Because what if some plugin on our site already declared a function called swap()? One would overwrite the other!
Using an object like this ensures that our version is now known as myToggle.swap()!
It may be hard to follow how it got to that name. Important hint: something looking like this... (function() { CODE } ()) ...is called an immediately-invoked function expression. iffy! It's a function that is immediatly executed and keeps its variables to itself. Or can give them to whatever you feed it in the last ()-pair.
Everything else is as verbose as can be... no fancy regular expressions, hacks or libraries. Get into it!

Toggle visibility for multiple divs with one function: navigation bar

My Assignment: Hi! I am doing an assignment in school where I am supposed write code in Javascript in order to toggle visibility for the submenus each belonging to their own topmenu in a navigation bar for a webpage. The visibility should be set to hidden by default and should be shown when a topmenu is clicked on.
I know how to toggle visibility for ONE submenu belonging to a topmenu, but fail to make my code work for multiple elements. My HTML-code:
<a class="left_top1" onclick = "toggle()">Opinion</a><br>
<div class="left_submenu_1" style="display: none;">
<a class="left_sub1">Leaders</a><br>
<a class="left_sub1">Debates</a><br>
</div>
<br>
<a class="left_top2" onclick = "toggle()">Economy</a><br>
<div class="left_submenu_2" style="display: none;">
<a class="left_sub2">News</a><br>
<a class="left_sub2">Your Economy</a><br>
</div>
My Problem: The topmenus I speak of are "Opinion" and "Economy". The visibility of the div with the class "left_submenu_1" should be toggled when you click the topmenu "left_top1". Thus should the visibilily of the div with the class "left_submenu_2" be toggled when you click the topmenu "left_top2". This is what I fail to do. My Javascript code is so far:
function toggle() {
var e = document.querySelectorAll("div.left_submenu_1, div.left_submenu_2");
for (var i=0; i < e.length; i++) { // I know this will enable/disable the visibility for ALL elements selected from the querySelectorAll, which should NOT happen
if(e[i].style.display == "none") {
e[i].style.display = "block";
} else if(e[i].style.display == "block") {
e[i].style.display = "none";
}
}
}
Anyone who knows how to solve this issue of mine? I know there are errors in the for-loop (as I wrote next to it), but this is the best I can manage for now.
Please note: We are NOT allowed to use jQuery or to give the topmenus id:s, as the idea is to use one general function to toggle the visibility. Furthermore, the code which enables the toggle-function should be done in Javascript.
I would approach it by passing the class name of the div to be shown (or hidden) into the function to begin with.
HTML
<a class="left_top1" onclick = "toggle('.left_submenu_1')">Opinion</a>
Then in the function you can grab the element and toggle it's display state.
JavaScript
function toggle(qs) {
var e = document.querySelector(qs);
e.style.display = e.style.display === 'block' ? 'none' : 'block';
}
The e.style.display === 'block' ? 'none' : 'block' part is saying if the elements display state is equal to block, return none, otherwise return block.
The return value is set as the new element display state due to the e.style.display = beforehand.
Tring to make it work modifying it as less as possible :
- use onClick="toggle(this)" in the anchors tags
- use a bit different toggle function like:
function toggle (el) {
var e = document.querySelectorAll('.' + el.className.replace('top', 'submenu_'))[0];
e.style.display = e.style.display.match(/none/) ? '' : 'none';
}
hope it helps, but I have to suggest You to make a small step forward and search for event delegation. Bye

Javascript if else statement to hide and show div

Please refer to the following codes :
<div id="message-1" onclick="javascript:showresponddiv(this.id)>
</div>
<div id="respond-1" style="display:none;">
</div>
<div id="message-2" onclick="javascript:showresponddiv(this.id)>
</div>
<div id="respond-2" style="display:none;">
</div>
<script type="text/javascript">
function showresponddiv(messagedivid){
var responddivid = messagedivid.replace("message-", "respond-");
if (document.getElementById(responddivid).style.display=="none"){
document.getElementById(responddivid).style.display="inline";
} else {
document.getElementById(responddivid).style.display="none";
}
}
</script>
The codes above already success make the respond div appear when user click on message div. The respond div will disappear when user click on message div again. Now my question is how to make the respond div of 1st message disappear when user click on 2nd message to display the respond div of 2nd message?
You should give the "respond" divs a common class:
<div id="respond-1" class="response' style="display:none;"></div>
Then you can get all divs by using getElementsByTagName, compare the class and hide them on a match:
function hideAllResponses() {
var divs = document.getElementsByTagName('div');
for(var i = divs.length; i-- ;) {
var div = divs[i];
if(div.className === 'response') {
div.style.display = 'none';
}
}
}
We cannot use getElementsByClassName, because this method is not supported by IE8 and below. But of course this method can be extended to make use of it if it is supported (same for querySelectorAll). This is left as an exercise for the reader.
Further notes:
Adding javascript: to the click handler is syntactically not wrong but totally unnecessary. Just do:
onclick="showresponddiv(this.id)"
If you have to do a lot of DOM manipulation of this kind, you should have a look at a library such as jQuery which greatly simplify such tasks.
Update: If always only one response is shown and you are worried about speed, then store a reference to opened one:
var current = null;
function showresponddiv(messagedivid){
var id = messagedivid.replace("message-", "respond-"),
div = document.getElementById(id);
// hide previous one
if(current && current !== div) {
current.style.display = 'none';
}
if (div.style.display=="none"){
div.style.display="inline";
current = div;
}
else {
div.style.display="none";
}
}
Edit: Fixed logic. See a DEMO.
You can add some class to all divs with id="respond-"
e.g
<div id="respond-1" class="classname" style="display:none;"></div>
<div id="respond-2" class="classname" style="display:none;"></div>
Now at first row of your function "showresponddiv()" you should find all divs with class "classname" and hide them.
With jQuery it is simple code:
$(".classname").hide();
jQuery - is a Javascript Library that helps you to easy manipulate with DOM and provides cross-browser compatibility.
Also you can look to Sizzle - it is a JavaScript CSS selector engine used by jQuery for selecting DOM elements

Categories