javascript/Jquery improvement on a .hide() .show() div menu - javascript

i am super new to javascript and jquery self thought ....been working on this menu for a bit and i have finally "finished" but iv got some horrendous code and i am looking for ways to improve my code to make it more readable and functional any tips and hints would be helpful. the idea to save space on the page each div will have different parts of a form that the user will fill out
here is some of the code
<body>
<div class="content">
<div class="menu" id="menu"></div>
<div class="content" id="sort"></div>
<div class="menu"id="menu1"></div>
<div class="content" id="1sort"></div>
<div class="menu"id="menu2"></div>
<div class="content" id="sort2"></div>
</div>
<script>
var show = true;
var show2 = false;
var show3 = false;
$('#1sort').hide("fast");
$('#sort2').hide("fast");
$("#menu").click(function () {
if (show == true) {
$('#sort').hide("fast");
$('#1sort').show("fast");
show = false;
show2 = true;
} else if (show == false) {
$('#sort').show("fast");
$('#1sort').hide("fast");
$('#sort2').hide("fast");
show = true;
show2 = false;
show3 = false;
}
});
$("#menu1").click(function () {
if (show2 == true) {
$('#1sort').hide("fast");
$('#sort2').show("fast");
show2 = false;
show3 = true;
} else if (show2 == false) {
$('#1sort').show("fast");
$('#sort').hide("fast");
$('#sort2').hide("fast");
show = false;
show2 = true;
show3 = false;
}
});
$("#menu2").click(function () {
if (show3 == false) {
$('#1sort').hide("fast");
$('#sort').hide("fast");
$('#sort2').show("fast");
show = false;
show2 = false;
show3 = true;
}
});
</script>

You can use some basic traversal functions, and .is to determine visibility. You don't need boolean variables nor element IDs that way: http://jsfiddle.net/K2sqy/2/.
$(".menu").click(function() {
var $next = $(this).next(".content"); // corresponding .content element
var isVisible = $next.is(":visible"); // is it currently visible?
$(this).siblings(".content").hide("fast"); // hide all siblings
$next[isVisible ? "hide" : "show"]("fast"); // toggle the corresponding .content
if(isVisible) {
// it was visible, so now it's hidden. Show the other .content:
// the next or, if not available, the previous
var $second = $next.nextAll(".content").first();
if($second.length === 0) {
$second = $next.prevAll(".content").first();
}
$second.show("fast");
}
});

A useful technique here is to adorn some extra attributes (preferably html5 data-*) onto the links to indicate what it's associated content is.
<div class="menu" id="menu" data-content="sort"></div>
<div class="content" id="sort"></div>
<div class="menu"id="menu1" data-content="1sort"></div>
<div class="content" id="1sort"></div>
<div class="menu" id="menu2" data-content="sort2"></div>
<div class="content" id="sort2"></div>
You can then use this when an item is clicked to hide the currently visible one, and show the required one:
$('.menu').click(function(){
$('.content:visible').hide('fast');
$('#' + $(this).data('content')).show('fast');
});
Live example: http://jsfiddle.net/hAbPa/

You might also consider using jquery .toggle(). More info here.
$('#foo').toggle(showOrHide);
is equivalent to:
if ( showOrHide == true ) {
$('#foo').show();
} else if ( showOrHide == false ) {
$('#foo').hide();
}

I'm not 100% sure (untested)... but this is pretty close I think.
$(".menu").click(function (){
$(this).next('.content').toggle();
});

Related

JavaScript and HTML to show or hide an element

I think this is very easy, but I just can't seem to twig it at the moment. I want to use a JavaScript function to set the visibility of an HTML tag.
I realise the below is wrong as hidden doesn't take a boolean. I'm just struggling to click what the easiest way to do it is?
So I have some script like this:
<script>
function evaluateBoolean() {
if (location.hostname.indexOf("someval" > 0) {
return true;
} else {
return false;
}
}
</script>
And I wanted to use it something like this:
<div hidden="evaluateBoolean()">
this will be shown or displayed depending on the JavaScript boolean
</div>
I would recommend doing it by altering the display style in the JavaScript code.
const el = document.getElementById('container');
const btn = document.getElementById('btn');
btn.addEventListener('click', function handleClick() {
if (el.style.display === 'none') {
el.style.display = 'block';
btn.textContent = 'Hide element';
} else {
el.style.display = 'none';
btn.textContent = 'Show element';
}
});
You have a div with id: myDIV
<div id="myDIV" class="card-header">
Hello World
</div>
You then call this Javascript function to show the element:
function showDiv() {
document.getElementById('myDIV').style.display = "block";
}
and this one to hide it:
function hideDiv() {
document.getElementById('myDIV').style.display = "none";
}
Note, that you can hide a div by:
<div id="myDIV" class="card-header" style="display:none">
Hello World
</div>
And then call the function to show it.
You trigger must be outside of the element which you hide. because if hided you cant even clicked. The js function classList toggle would be good.
function evaluateBoolean() {
const d = document.querySelector('.w div');
d.classList.toggle('hide');
}
.w {
height: 40px;
background: yellow;
}
.hide {
display: none;
}
<div class="w" onclick="evaluateBoolean()">
<div> this will be shown or displayed depending on the javascript boolean </div>
</div>
You can't explicitly run js in your html, if you aren't using any framework like angular or react, where property binding is allowed.
For achieving your intentions with js you can use this approch:
Add to your div an id:
<div id="myDiv"> Toggled div </div>
In your js script modify your function evaluateBoleean() to show/hide the element:
function evaluateBoolean() {
const div = document.querySelector("#myDiv");
if (location.hostname.indexOf("someval" > 0) {
div.hidden = true;
} else {
div.hidden = false;
}
There's a very easy option:-->
having a blank text
firsly replace the html code with this:-->
<div hidden="evaluateBoolean()" id="ThingToBeHidden"> this will be shown or displayed depending on the javascript boolean </div>
and put js code:-->
document.getElementById("ThingToBeHidden").innerHTML = "";
So you have assigned the div to have it's special id which none other element has.
So now the js code selects the div with that id and then sets the context of it to blank.
If you want the text to appear again, the js code is:-->
document.getElementById("ThingToBeHidden").innerHTML = "this will be shown or displayed depending on the javascript boolean";
You can hide an element in several ways (using jQuery):
const o = $(cssSelectorForElementToStyle);
$(o).hide();
$(o).toggle();
$(o).css('display', 'none');
$(o).addClass('css_class_for_hiding_stuff');
Here using vanilla JavaScript:
const o = document.querySelector(cssSelectorForElementToStyle);
o.style.display = 'none';
o.classList.add('css_class_for_hiding_stuff');
But your question doesn't point out exactly when you are going to make this check. So let's assume you are going to check the boolean value once when the page is loaded and hide or show a given element according to that value:
$(document).ready(
() => {
if (evaluateBoolean() === true) {
// do nothing in this case
} else {
$('#elementWithThisId').css('display', 'none');
}
}
);
Without jQuery:
document.addEventListener("DOMContentLoaded", function() {
if (evaluateBoolean() === true) {
// do nothing in this case
} else {
document.querySelector('#elementWithThisId').style.display = 'none';
}
});

Javascript body overflow: hidden

I have been experimenting to try to get this to work.
I have 2 checkboxes acting as part of my mobile CSS navigation menu for either side. I have a javascript that prevents more than 1 checkbox to be open at a time. It works.
Now I am trying to add an overflow:hidden to the body when either 1 of the checkboxes is checked, obviously if nothing is checked then to remove overflow:hidden, but I can't seem to get the first part to work.
I am fairly new to Javascript so any help would be appreciated. Thanks!
function selectOnlyThis(id){
var myCheckbox = document.getElementsByName("nav-check");
Array.prototype.forEach.call(myCheckbox,function(el){
if (id != el)
{
el.checked = false;
}
});
if (id.checked == false)
{
id.checked = false;
} else
{
id.checked = true;
}
if (id.checked == true)
{
$('body').css("overflow", "hidden");
}
}
// Click, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
<div class="l-btn">
<input id="lger" type="checkbox" name="nav-check" onclick="selectOnlyThis(this)"/>
<label for="lger" onclick="topFunction()"><span></span><span></span</label>
</div>
<div class="r-btn">
<input id="rger" type="checkbox" name="nav-check" onclick="selectOnlyThis(this)"/>
<label for="rger" onclick="topFunction()"><span></span><br/><div>Location</div></label>
</div>
This will do
It takes all the changes made to any checkbox and checks if the id is rger or lger and the checkbox is checked or not, then it changes the css with the jquery .css() method.
<div class="r-btn">
<input id="rger" type="checkbox" name="nav-check" />
<label for="rger" onclick="topFunction()"><span></span><br/><div>Location</div></label>
</div>
$("input:checkbox").on('change', function () {
if (($(this).attr('id')=='rger' || $(this).attr('id')=='lger') && $(this).prop('checked')) {
$('body').css("overflow", "hidden");
}
else
$('body').css("overflow", "visible");
});
Refer this fiddle.
It looks like your coming from a different programming language? :)
You will love javascript, for example a slim function for your first checkbox.
function selectOnlyThis = ({ target }) => {
const { id, checked } = target;
id === 'rger' && checked && $('body').css("overflow", "hidden");
}

How to display hidden div after mouse out or hover

Hi guys can someone help me here I want to make a hidden div being displayed after I trigger the event to display and I remove the mouse on that div here is my code
<div id='MainContainer'>
<div id='btn-img' onmouseover='DisplayHidden()'>content 1</div>
<div id='container2'>content 2</div>
</div>
function DisplayHidden()
{
$('#container2').show();
}
is it possible?
I preferred this way because if you want to add more attributes and comparisons parameters you may add it easily and attribute binding is dynamical.
$(document).ready(function(){
$("#MainContainer > div").on("click",function(e){
if(false === !!$(this).attr('data-click')){
$(this).attr("data-click", true);
alert('No');
}else{
alert('Clicking on same div');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='MainContainer'>
<div id='container1'>content 1</div>
<div id='container2'>content 2</div>
</div>
Here is what you could do, using pure javascript.
Bind the click event on the container element and use event.target attribute to check the previous click element and take appropriate action.
Event.target documentation on MDN
document.addEventListener("DOMContentLoaded", function() {
var prevElement = null;
document.querySelector("#MainContainer").addEventListener("click", function(event) {
if (prevElement === event.target) {
console.log("Yes")
} else {
console.log("No");
}
prevElement = event.target;
});
});
<div id='MainContainer'>
<div id='container1'>content 1</div>
<div id='container2'>content 2</div>
</div>
var lastClick = null;
$('div#MainContainer div').click(function() {
var clickedId = $(this).attr('id');
if (clickedId == lastClick) {
alert('Clicked the same div');
}
else {
alert('Clicked on a different div');
lastClick = clickedId;
}
});
Here a simple solution with plain javascript:
var g_lastTarget = null
var g_handleClick = function(e) {
var target = e.currentTarget
if (g_lastTarget === target) {
alert('You clicked the container twice. Container ID = ' + target.id)
}
g_lastTarget = target
}
var c1 = document.getElementById('container1')
var c2 = document.getElementById('container2')
c1.addEventListener('click', g_handleClick)
c2.addEventListener('click', g_handleClick)
Create a common class & use querySelectorAll to select the desirable elements.
Then loop through it attach eventListener method to it.Create a variable to store the id of the currently clicked element. On subsequent click check if the variable value and id is same. If it is same then throw an alert.
var getElements = document.querySelectorAll(".elem");
var clickedElem = "";
getElements.forEach(function(item) {
item.addEventListener('click', function() {
if (item.id === clickedElem) {
alert('Clicking on same div')
} else {
clickedElem = item.id
}
})
})
<div id='MainContainer'>
<div id='container1' class="elem">content 1</div>
<div id='container2' class="elem">content 2</div>
</div>

Using the Bootstrap wizard control but how do you prevent going to a different tab when validation fails in a tab

I am using hte Bootstrap wizard. The user can either click the next or previous button or the tabs above to switch to different pages in the wizard.
On one page in the wizard I need to validate if one number is bigger than another. If it isn't then the validation fails. Pushing the next button will not go to the next page. The problem happens when the user pushes the tab to a later tab and wizard lets them go to that new page in the wizard.
My javascript html code looks like:
#* Javascript code for the wizard *#
<script type="text/javascript">
$(document).ready(function () {
$('#rootwizard').bootstrapWizard({
onNext: function (tab, navigation, index) {
if(WizardValidation(index) == false)
{
return false;
}
},
onTabClick: function(tab, navigation, index)
{
if (WizardValidation(tab[0].getAttribute('data-index')) == false) {
return false;
}
},
onTabShow: function (tab, navigation, index) {
if (WizardValidation(tab[0].getAttribute('data-index')) == false) {
return false;
}
var $total = navigation.find('li').length;
var $current = index + 1;
var $percent = ($current / $total) * 100;
$('#rootwizard').find('.progress-bar').css({ width: $percent + '%' });
}
});
window.prettyPrint && prettyPrint()
});
function WizardValidation(gotoIndex)
{
// Validation for various parts in the wizard
if (gotoIndex > 2) {
var oDaysMin = document.getElementById('OobeDaysMin').value
if (oDaysMin.length == 0) {
alert('You must enter a valid integer value');
document.getElementById('OobeDaysMin').focus();
return false;
}
var oDaysMax = document.getElementById('OobeDaysMax').value
if (oDaysMax.length == 0) {
alert('You must enter a valid integer value');
document.getElementById('OobeDaysMax').focus();
return false;
}
if ((parseInt(oDaysMax, 10) < parseInt(oDaysMin, 10))) {
alert('OobeDaysMax must be equal or greater than OobeDaysMin');
document.getElementById('OobeDaysMax').focus();
return false;
}
}
}
<section id="wizard">
<div id="rootwizard">
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<ul>
<li id="wiz0" data-index="0">Name</li>
<li id="wiz1" data-index="1">Questions / Layout</li>
<li id="wiz2" data-index="2">Configuration</li>
<li id="wiz3" data-index="3">Assests / Themes</li>
<li id="wiz4" data-index="4">Quota Mgmt</li>
<li id="wiz5" data-index="5">Go Live</li>
</ul>
</div>
</div>
</div>
I have tried using the onTabClick and the onTabShow events to try to prevent allowing someone to go to a page after the page with the validation error.
Any ideas on how I can do this?
Thanks.
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href");
console.log(target);
if (target == "#hesapbilgileri") {
if ($('#anlasmakabulcheck').is(':checked')) {
$('.test .wz-steps a[href="#first"]').tab('show');
}
else
$('.test .wz-steps a[href="#second"]').tab('show');
}
});

jQuery many of the same elements, one has to start when you click

I have code like that:
<img src="fl_uk.png" class="menulink" />
<div class="test">Something</div>
<img src="fl_uk.png" class="menulink" />
<div class="test">Something2</div>
$('.menulink').click(function(){
if($('.menulink').attr('src') == "fl_pol.png"){
$(this).attr('src',"fl_uk.png");
$('.test').hide('slow');
return false;
}
else
{
$(this).attr('src',"fl_pol.png");
$('.test').show('slow');
return false;
}
});
When I clicking on img should change image and show div. When I click again image should back to first and div should hide. That's working fine. But I woul like to do that should be there many imgae-buttons and many divs and after clicking one image-button should only change this image and open div below image. I don't know how many his image and div will be because they are generating from database.
How to create jQuery code to not repeat jQuery code
I might have done this like :
<img src="fl_uk.png" rel="uk" class="menulink" />
<div class="test" rel="uk_div">Something</div>
<img src="fl_pol.png" rel="pol" class="menulink" />
<div class="test" rel="pol_div">Something2</div>
and then
$(".menulink").on("click",function(){
$(".test").hide();
$("div[rel='"+$(this).attr("rel") + "_div']").show());
});
To answer your question, I'm going to assume you have a container around those images, such as <div id="images">...</div>. Now the solution is really simple:
document.getElementById('images').onclick = function(e) {
e = e || window.event;
var t = e.currentSrc || e.target;
if( !t.tagName) t = t.parentNode;
while( t != this && t.tagName != "IMG") t = t.parentNode;
if( t != this) {
if( t.src == "fl_pol.png") {
t.src = "fl_uk.png";
t.nextSibling.style.display = "none";
}
else {
t.src = "fl_pol.png";
t.nextSibling.style.display = "";
}
return false;
}
};
This is done in raw JS, rather than jQuery, which means it's considerably faster. It also delegates the event so there's only one listener, rather than one per image.
Try this:
$('.menulink').on('click', function(){
if($(this).attr('src') == "fl_pol.png"){
$(this).attr('src',"fl_uk.png");
$(this).next('.test').hide('slow');
return false;
}else{
$(this).attr('src',"fl_pol.png");
$(this).next('.test').show('slow');
return false;
}
});

Categories