Whats wrong with me code (dom+onclick+li+display)? - javascript

Working
tutorial.onclick = function(){
var tutorial = document.getElementById("tutorials-ul");
tutorial.style.display = "list-item";
}
Not working
news.onclick = function(){
var news = document.getElementById("news-ul");
if(news.style.display == "none") {
news.style.display = "list-item";
}
else if(news.style.display == "list-item") {
news.style.display = "none";
}
}
Any answer or opinion is accepted.

I assume the outer news is a button that has already been assigned to a variable (or the default global via its ID).
The issue is if the element itself does not have a display set in its style attribute, then its initial value will be "" instead of whatever was given in CSS.
Therefore instead of comparing to "none", compare to "".
news.onclick = function() {
var news = document.getElementById("news-ul");
if (news.style.display == "") {
news.style.display = "list-item";
} else {
news.style.display = "";
}
}
#news-ul {
display: none
}
<button id=news>CLICK FOR NEWS</button>
<ul id="news-ul">
<li>TEST
</ul>

I figured it out using this stack overflow Get a CSS value with JavaScript
The correct code for showing and hiding the nested uls is
news.onclick = function(){
var news = document.getElementById("news-ul");
function compareDisplayValue(){
var element = document.getElementById("news-ul");
var style = window.getComputedStyle(element);
var display = style.getPropertyValue('display');
if(display == "none"){
news.style.display = "list-item";
}
else if (display == "list-item"){
news.style.display = "none";
}
}
compareDisplayValue();
}

Related

Displaying div based on dropdown value

I have 3 divs each with a distinct id. Based off the value of a dropdown I have, I want to show one of the divs. I created my function and call it, but for some reason no change occurs. The new value of the dropdown is never recorded, when I use console.log. I am unsure what is causing the problem and would appreciate any help.
HTML
<div class="ins-left" id="fifteen">
<p>$15</p>
</div>
<div class="ins-left" id="thirty">
<p>$30</p>
</div>
<div class="ins-left" id="fourtyfive">
<p>$45</p>
</div>
CSS
#fifteen {
display: none;
}
#thirty {
display: none;
}
#fourtyfive {
display: none;
}
JS
var length = document.getElementById('length');
var chosenLength = length.options[length.selectedIndex].value;
var start = document.getElementById('start').innerHTML.split('.').join('').toLocaleLowerCase();
var end = document.getElementById('end').innerHTML.split('.').join('').toLocaleLowerCase();
var time = document.getElementById('time');
time.disabled = true;
function disabled() {
if (chosenLength.value != "") {
time.disabled = false;
}
}
var slotTimes = [];
document.getElementById("length").onchange = function (evt) {
var timeDistance = evt.target.value;
var startMoment = moment(start, "h:mm a");
var endMoment = moment(end, "h:mm a");
slotTimes = [];
while (startMoment.isSameOrBefore(endMoment)) {
slotTimes.push(startMoment.format("h:mm a"));
startMoment = startMoment.add(timeDistance, 'minutes');
}
addDropdown();
price();
};
function price(){
if (chosenLength.value === "") {
document.getElementById('fifteen').style.display = "none";
document.getElementById('thirty').style.display = "none";
document.getElementById('fourtyfive').style.display = "none";
}
if (chosenLength.value === "30") {
document.getElementById('fifteen').style.display = "block";
document.getElementById('thirty').style.display = "none";
document.getElementById('fourtyfive').style.display = "none";
}
if (chosenLength.value === "60") {
document.getElementById('fifteen').style.display = "none";
document.getElementById('thirty').style.display = "block";
document.getElementById('fourtyfive').style.display = "none";
}
if (chosenLength.value === "90") {
document.getElementById('fifteen').style.display = "none";
document.getElementById('thirty').style.display = "none";
document.getElementById('fourtyfive').style.display = "block";
}
}
function addDropdown() {
var doc = '',
times = slotTimes,
i;
for (i = 0; i < times.length; i++) {
doc += "<option value='" + times[i] + "'>" + times[i] + "</option>";
}
document.getElementById('time').innerHTML = doc;
disabled();
}
I made a simple working example for you here, so you can adjust your code based on this:
https://codepen.io/brunomont/pen/WmExvV
I had to remove a couple of broken references since your HTML didn't include everything (like the time elements). Also, make sure you have all the dependencies loading (I noticed you are using moment.js).
The changes I made were:
Adding a document.addEventListener("DOMContentLoaded", function() to make sure your HTML was loaded, before you tyr to run the JavaScript.
Change the way you bind your onChange function to be document.getElementById('length').addEventListener('change', function (evt)
Basically, the addEventListener is more flexible than onChange. You can read more about this change here:
addEventListener vs onclick
Hope it helps :)

I broke a working javascript script trying to expand it

The script below was working properly (toggling display on/off) before I added lines 3 to 8 to avoid displaying more than one element at a time (there are hundreds). It still works after adding lines 3 to 8 but it does not toggle back to "display:none;" (there is always one element visible).
I only have basic knowledge of Javascript and I cannot see what I am doing wrong. Can someone give me a hint/solution?
<script type="text/javascript">
function toggle_visibility(id) {
numb = document.forms.length
for(i=1;i<numb+1;i++) {
j="N"+i
elemnt = document.getElementById(j);
elemnt.style.display = "none";
}
var e = document.getElementById(id);
if(e.style.display == 'none')
e.style.display = 'block';
else
e.style.display = 'none';
}
</script>
You are not declaring i as local variable in for -loop.Instead use this.Also you have not declared elemnt variable.Hope you dont want it to be global variable
for(var i=1;i<numb+1;i++) {
j="N"+i
elemnt = document.getElementById(j);
elemnt.style.display = "none";
}
Try declaring all the variables first:
function toggle_visibility(id) {
var i, elemnt, state,
numb = document.forms.length + 1;
for( i = 1; i < numb; i++ ) {
elemnt = document.getElementById( "N" + i );
elemnt.style.display = "none";
}
elemnt = document.getElementById( id );
state = elemnt.style.display === 'none';
elemnt.style.display = state ? 'block' : 'none';
}

javascript webservice call and settimeout

i'm currently developing an application that relies on webservice calls in order to create a tree-like "menu", everything works as intended but i realized not all the target audience has a fast internet connection like i have right now on the development environment. my goal is to show a loading "screen" while the javascript function creates and then adds the elements to the DOM, the flowchart is as follows:
user click on the "expand" image of a node
user sees a div loading gif
user is presented with the childnodes
i'm not sure where i should put the timeout
my code:
...
elemento_tema_imagem_esconde_mostra.addEventListener("click", Get_Feat);
...
function Get_Feat(event) {
Tema_Expandido = event.target.parentNode;
if (typeof (Tema_Expandido.getElementsByTagName("ul")[0]) === "undefined") {
sMNID = event.target.parentNode.getElementsByTagName("a")[0].getAttribute("mnid");
var service = new WebJSON;
service.GetFeat(sMNID, SuccessCallback_Get_Feat, OnfailureCallback_Get_Feat);
} else {
//debugger;
var elemento = Tema_Expandido.getElementsByTagName("ul")[0];
var imagem_esconder_mostar = elemento.parentNode.childNodes[0];
var style = window.getComputedStyle(elemento, null);
if (style.display == "block") {
elemento.style.display = "none";
imagem_esconder_mostar.src = "Content/Images/img_abrir_22_22.png";
} else if (style.display == "none") {
elemento.style.display = "block";
imagem_esconder_mostar.src = "Content/Images/img_fechar_22_22.png";
}
}
};
function SuccessCallback_Get_Feat(Resultado_Get_Feat) {
var colleccao_Feat = JSON.parse(Resultado_Get_Feat);
var lista_feat = document.createElement("ul");
lista_feat.setAttribute("class", "lista-sem-bullets");
for (var i = 0; i < colleccao_Feat.length; i++) {
var elemento_feat = document.createElement("li");
var elemento_feat_imagem_esconde_mostra = document.createElement("img");
var elemento_feat_imagem_no = document.createElement("img");
var elemento_feat_link = document.createElement("a");
if (colleccao_Feat[i].FILHOS > 0) {
elemento_feat_imagem_esconde_mostra.src = "Content/Images/img_abrir_22_22.png";
elemento_feat_imagem_esconde_mostra.addEventListener("click", Get_Compo);
} else if (colleccao_Feat[i].FILHOS = 0) {
elemento_feat_imagem_esconde_mostra.src = "Content/Images/seta_dir_26_20.png";
}
//elemento_feat_imagem_esconde_mostra.addEventListener("click", Get_Feat);
//elemento_feat_imagem_no.src = "Content/Images/feat.png"
elemento_feat_link.setAttribute("FNID", colleccao_Feat[i].FNID);
elemento_feat_link.innerText = colleccao_Feat[i].NAMEDESC;
elemento_feat.appendChild(elemento_feat_imagem_esconde_mostra);
elemento_feat.appendChild(elemento_feat_imagem_no);
elemento_feat.appendChild(elemento_feat_link);
lista_feat.appendChild(elemento_feat);
};
document.getElementById("myModal_Loading").style.display = "none";
Tema_Expandido.appendChild(lista_feat);
Tema_Expandido.childNodes[0].src = "Content/Images/img_fechar_22_22.png";
};
function OnfailureCallback_Get_Feat(error) {
//displaying error on alert box
alert(error);
};
any help will be much appreciated

What is the plain Javascript equivalent of .each and $(this) when used together like in this example?

What is the plain Javascript equivalent of .each and $(this).find when used together in this example?
$(document).ready(function(){
$('.rows').each(function(){
var textfield = $(this).find(".textfield");
var colorbox = $(this).find(".box");
function colorchange() {
if (textfield.val() <100 || textfield.val() == null) {
colorbox.css("background-color","red");
colorbox.html("Too Low");
}
else if (textfield.val() >300) {
colorbox.css("background-color","red");
colorbox.html("Too High");
}
else {
colorbox.css("background-color","green");
colorbox.html("Just Right");
}
}
textfield.keyup(colorchange);
}
)});
Here's a fiddle with basically what I'm trying to accomplish, I know I need to use a loop I'm just not sure exactly how to set it up. I don't want to use jquery just for this simple functionality if I don't have to
http://jsfiddle.net/8u5dj/
I deleted the code I already tried because it changed every instance of the colorbox so I'm not sure what I did wrong.
This is how to do what you want in plain javascript:
http://jsfiddle.net/johnboker/6A5WS/4/
var rows = document.getElementsByClassName('rows');
for(var i = 0; i < rows.length; i++)
{
var textfield = rows[i].getElementsByClassName('textfield')[0];
var colorbox = rows[i].getElementsByClassName('box')[0];
var colorchange = function(tf, cb)
{
return function()
{
if (tf.value < 100 || tf.value == null)
{
cb.style.backgroundColor = 'red';
cb.innerText = "Too Low";
}
else if (tf.value > 300)
{
cb.style.backgroundColor = 'red';
cb.innerText = "Too High";
}
else
{
cb.style.backgroundColor = 'green';
cb.innerText = "Just Right";
}
};
}(textfield, colorbox);
textfield.onkeyup = colorchange;
}
var rows = document.querySelectorAll('.rows');
for (var i=0; i<rows.length; i++) {
var row = rows[i];
var textfield = row.querySelector('.textfield');
var colorbox = row.querySelector('.box');
// ...
}
Note that you must use a for loop to iterate the rows because querySelectorAll() does not return an array, despite appearances. In particular, that means that .forEach() isn't valid on the returned list.

Add class active when clicking menu link with JAVASCRIPT

HTML
<div id="top" class="shadow">
<ul class="gprc">
<li>Home</li>
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
<li>Text4</li>
</ul>
Javascript
window.onload = setActive;
function setActive() {
aObj = document.getElementById('top').getElementsByTagName('a');
var found = false;
for (i = 0; i < aObj.length; i++) {
if (document.location.href.indexOf(aObj[i].href) >= 0) {
aObj[i].className = 'active';
found = true;
}
}
if (!found) {
aObj[0].className = 'active';
}
}
The problem is that the menu home link remains selected or active all the time even if i click on other links and I would like to make it not selected on loading of the page and also to remain non-selected while other link that i clicked and i am on the specific landing page remains selected. Please only Javascript no JQUERY.
Try this:
window.onload = setActive;
function setActive() {
var aObj = document.getElementById('top').getElementsByTagName('a');
var found = false;
for(var i=aObj.length-1; i>=1 && !found; i--) {
if(document.location.href.indexOf(aObj[i].href)>=0) {
aObj[i].className='active';
found = true;
}
}
//if you never want home selected remove the next
if(!found && document.location.href.replace(/\/$/, "") == aObj[0].href.replace(/\/$/, ""))
aObj[0].className = 'active';
}
With this way you start at the end of the list, and when you find a coincidence it stop the search of an active link.
I hope it helps you
function setActive() {
var top = document.getElementById('top'),
aObj = top.getElementsByTagName('a'),
href = document.location.href,
found = false;
for (var i = 0; i < aObj.length || !found; i++) {
if (href.indexOf(aObj[i].href) >= 0) {
aObj[i].className = 'active';
found = true;
}
}
if (!found) {
aObj[0].className = 'active';
}
//Listen for link clicks
function listener(e) {
if(e.target.tagName === "A") {
for (var i = 0; i<aObj.length; i++) {//remove previous class
aObj[i].className = "";
}
e.target.className = "active";
}
}
if(top.addEventListener) {
top.addEventListener(listener);
} else if(top.attachEvent) {
top.attachEvent(listener);
}
}
You're going to need to listen to the click event so you can determine if one of your links is pressed. I'm going to do this using some simple delegation

Categories

Resources