Trouble with javascript and making it work with my exsisting code - javascript

I am using jQuery, and I'm have not used it a lot before so I'm a newbie.
I'm trying to make a slide in menu, and I found code for it. The problem, however, is when I insert it into my existing code in Sublime Text. For some reason the javascript does not work.
$(".myButton").click(function() {
var effect = 'slide';
var options = {
direction: $('.mySelect').val()
};
var duration = 500;
$('#myDiv').toggle(effect, options, duration);
});
.myButton {
font-size: 1em;
cursor: pointer;
font-weight: bold;
}
.mySelect {
padding: .2em 0;
font-size: 1em;
display: none;
}
#myDiv {
color: #fff;
background-color: pink;
border: 2px solid #000;
display: none;
text-align: justify;
padding-left: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="myButton">
run effect
</div>
<select class="mySelect">
<option value="left">Left</option>
</select>
<div id="myDiv">
<ul>
<li> episoder </li>
<li> - </li>
<li> karakterer </li>
<li> - </li>
<li> medvirkende </li>
<li> - </li>
<li> produksjon </li>
</ul>
</div>
I have set, .mySelect { display: none; }, because I don't want the user to be able to choose which side it will enter from.

You need to make sure your jQuery code runs when the DOM has been loaded. To do that you can place the <script> block just before the </body> tag. Alternatively you can place it in the <head> and wrap your JS code in a document.ready event handler, like this:
$(function() {
$(".myButton").click(function() {
var effect = 'slide';
var options = {
direction: $('.mySelect').val()
};
var duration = 500;
$('#myDiv').toggle(effect, options, duration);
});
});

Related

if statement when button is clicked

Trying to make an if statement in JS that when one of the top 3 buttons changes, it checks which of the bottom 2 has the "active" class. and visa versa
So when I click 30g it will check if option a or option b is active, and then change the price accordingly.
Any help would be greatly appreciated as I'm kind of a noob.
$(function(){
$('ul.nav li').on('click', function(){
$(this).parent().find('li.activeBtn').removeClass('activeBtn');
$(this).addClass('activeBtn');
});
});
function myFunction(){
const element = document.getElementById("30");
const element2 = document.getElementById("no");
const pricetag = document.getElementById("price");
if(((element.classList.contains("activeBtn")) == true) && ((element2.classList.contains("activeBtn")) == true)){
pricetag.innerHTML = "€1,00";
}
}
ul.nav a {
border: 2px solid #E1E8EE;
border-radius: 6px;
padding: 13px 20px;
font-size: 14px;
color: #5E6977;
background-color: #fff;
cursor: pointer;
transition: all .5s;
display: inline-block;
vertical-align: middle;
}
.activeBtn {
color: grey;
font-weight: 1000;
border: 2px solid grey;
border-radius: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav">
<li id="30" onclick="myFunction()" class="activeBtn"><a>30g</a></li>
<li id="70" onclick="myFunction()"><a>70g</a></li>
<li id="90" onclick="myFunction()"><a>90g</a></li>
</ul>
<ul class="nav">
<li id="no" class="activeBtn"><a>Zonder kreeftensoep</a></li>
<li id="yes"><a>Met kreeftensoep</a></li>
</ul>
<br>
<div class="product-price">
<span id="price">148$</span>
</div>
Are you trying to update the total price depending on which element is already selected ?
If that's the case, you can use a for loop event binding ->
// You should add a '.nav__el' class to your <li> elements in html
const navEls = document.querySelectorAll('.nav__el')
// Bind an event listener to all your buttons
navEls.forEach(el => {
el.addEventListener('click', () => {
const domPrice = document.querySelector('#price')
// Get the price related to your button
const price = el.getAttribute('data-price')
// Get the current total
const currentPrice = parseInt(domPrice.innerText)
if(el.classList.contains('activeBtn')) {
el.classList.remove('activeBtn')
domPrice.innerText = `${currentPrice - price}$`
}
else {
el.classList.add('activeBtn')
domPrice.innerText = `${currentPrice + price}$`
}
})
})

Is my code to change the CSS of an element when clicked efficient?

I want to know if there is a more efficient way to change the CSS of multiple elements when one is clicked.
I have working code whereby clicking on a subheading within the "About" section changes its color, the color of the other subheadings, and the opacity of reach respective paragraph. It looks like a lot of code to me. I imagine there is a simpler or at least more streamlined way to accomplish these things that I just don't know with my borderline intermediate JS skills.
const about = () => {
const paraOne = document.getElementById("para-one");
const paraTwo = document.getElementById("para-two");
const paraThree = document.getElementById("para-three");
const mission = document.querySelector(".mission");
const value = document.querySelector(".value");
const vision = document.querySelector(".vision");
mission.addEventListener('click', () => {
mission.classList.add("active");
value.classList.remove("active");
vision.classList.remove("active");
paraOne.classList.remove('zero');
paraTwo.classList.add('zero');
paraThree.classList.add('zero');
});
value.addEventListener('click', () => {
value.classList.add("active");
mission.classList.remove("active");
vision.classList.remove("active");
paraOne.classList.add('zero');
paraTwo.classList.remove('zero');
paraThree.classList.add('zero');
});
vision.addEventListener('click', () => {
vision.classList.add("active");
mission.classList.remove("active");
value.classList.remove("active");
paraOne.classList.add('zero');
paraTwo.classList.add('zero');
paraThree.classList.remove('zero');
});
}
about();
#about-center ul li:hover,
#about-center ul li.active {
color: black;
cursor: pointer;
}
.active {
color: black;
cursor: pointer;
}
#container {
position: relative;
}
#container p {
position: absolute;
left: 30%;
}
.zero {
opacity: 0;
}
#about ul,
#about p,
#about button {
margin-bottom: 2em;
}
#about-center p {
font-size: 2rem;
}
<div id="about-center">
<h1>About Us</h1>
<ul>
<li class="mission active">OUR MISSION</li>
<li class="value">our values</li>
<li class="vision">our vision</li>
</ul>
<div id="container">
<p id="para-one">This is our mission.
</p>
<p id="para-two" class="zero">These are our values.
</p>
<p id="para-three" class="zero">This is our vision.
</p>
</div>
<button>read more</button>
</div>
You can loop over all the li elements. Use this to add the event listeners initially. Then in the listener, you can loop again to do the appropriate class changes for the element that the user clicked on versus the other elements. And you can use the index of the iteration to change the class of the corresponding p element.
const about = () => {
const lis = document.querySelectorAll("#about-list li");
const paras = document.querySelectorAll("#container p");
lis.forEach(li => li.addEventListener("click", (e) => lis.forEach((li1, index) => {
if (li1 == e.target) {
li1.classList.add("active");
paras[index].classList.remove("zero");
} else {
li1.classList.remove("active");
paras[index].classList.add("zero");
}
})));
}
about();
#about-center ul li:hover,
#about-center ul li.active {
color: black;
cursor: pointer;
}
.active {
color: black;
cursor: pointer;
}
#about-center ul li {
color: grey;
}
#container {
position: relative;
}
#container p {
position: absolute;
left: 30%;
}
.zero {
opacity: 0;
}
#about ul,
#about p,
#about button {
margin-bottom: 2em;
}
#about-center p {
font-size: 2rem;
}
<div id="about-center">
<h1>About Us</h1>
<ul id="about-list">
<li class="mission active">OUR MISSION</li>
<li class="value">our values</li>
<li class="vision">our vision</li>
</ul>
<div id="container">
<p id="para-one">This is our mission.
</p>
<p id="para-two" class="zero">These are our values.
</p>
<p id="para-three" class="zero">This is our vision.
</p>
</div>
<button>read more</button>
</div>
I think this is as effective as it could be. Now, there are things which can be done to make it more readable (especially if you get more than three tabs later), but that won't change the effectiveness or would actually make it worse.
Like ... it would be more readable to make function which will turn "off" all tabs and call it from all click handlers, although technically it means it will be needlessly removing class which is not set on one of them.
Also, if you put the matching paragraphs IDs into HTML, you can use just one function for all and use event.currentTarget to recognize which one it was called for. Again, not worth the time if you have just three tabs, but if you have more ...

Detect data change from different DOM element

TL;DR: Detect item change from the actual <ul> list and persist the data
Howdy everyone?
I'm currently doing a Trello-like based web-application using PHP as a backend and jQueryUI as a front-end.
The front-end part is made using sortable(), by defining three UL elements. One is a container / wrapper with the id Nav and the other two are actual boards that hold the items.
Case scenarios are simple:
You can reorder boards
You can move order of items inside the single board
You can move item from one board to another
The included code supports all three of them but the data should persist to the back-end powered database (I'm currently on SQLite since the project is in early phase).
Problem
The method setSortAction currently detects all three use case but once you move the item from one board to another the order of the list can't be properly detected (since they are in incremented value).
Getting the bodyContent like this: action=updateMenuItemListings&record=2&record=1&record=3
by moving the second item to the first place in the board is fine, and I can persist that change through the POST request on back-end and then onto the database.
What happens when you move the first item from the second board on the first board? You'd get value of bodyContent similar to this:
action=updateMenuItemListings&record=1&record=2&record=1&record=3
As you can see the record with value 1 duplicates.
That means I can't detect the item moved is from the second board and I have duplicate items in the order of the board.
How would you go about designing this? Can it be done by the given code or have I totally missed the logic that one should apply in this scenario?
Thank you.
$(function() {
var debugMode = true;
$("ul.droptrue").sortable({
connectWith: "ul"
});
//Set common sort settings for all lists
$(".sortable").sortable({
opacity: 0.6,
cursor: 'move'
});
//Function used to configure update calls for each sort
function setSortAction(selector, updatePage, updateAction, itemLabel) {
$(selector).sortable({
update: function() {
var itemList = $(this).sortable(
"serialize", {
attribute: "id",
key: itemLabel
});
//Create POST request to persist the update
var bodyContent = "action=" + updateAction + "&" + itemList;
if (debugMode) {
alert("DEBUG: bodyContent = \n" + bodyContent);
}
//$.post(updatePage, bodyContent, function (postResult)
//{ alert(postResult); });
}
});
}
//Set sort update action for top level and second level
setSortAction(".navLevel1",
"reorder.php",
"updateMenuListings",
"record");
setSortAction(".navLevel2",
"reorder.php",
"updateMenuItemListings",
"record");
});
#import url( 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' );
#sortable_1,
#sortable_2,
#sortable_3 {
list-style-type: none;
margin: 0;
float: left;
margin-right: 10px;
background: #eee;
padding: 5px;
width: 143px;
}
#sortable_1 li,
#sortable_2 li,
#sortable_3 li {
margin: 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
table {
font-size: 1em;
}
.ui-draggable,
.ui-droppable {
background-position: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul id="Nav" class="sortable navLevel1">
<ul id="sortable_1" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Classes</li>
<li id="item_1" class="ui-state-default">Some class</li>
<li id="item_2" class="ui-state-default">Another one!</li>
<li id="item_3" class="ui-state-default">Yep, thats enough</li>
</ul>
<ul id="sortable_2" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Presentation</li>
<li id="item_1" class="ui-state-default">Tom</li>
<li id="item_2" class="ui-state-default">Jessica</li>
<li id="item_3" class="ui-state-default">Kevin</li>
</ul>
</ul>
<br style="clear:both">
Unlike classes HTML ID's should be unique, in this way you can identify which items are from which columns.
Knowing for example that column one has 4 slots and column two has 6 would mean that a request array of 7,3,9,3,2,5,6,1,4,8,10 gets split into 4 and 6 hence
Column one: 7, 3, 9, 10,
Column two: 2, 5, 6, 1, 4, 8
$(function() {
var debugMode = true;
$("ul.droptrue").sortable({
connectWith: "ul"
});
//Set common sort settings for all lists
$(".sortable").sortable({
opacity: 0.6,
cursor: 'move'
});
//Function used to configure update calls for each sort
function setSortAction(selector, updatePage, updateAction, itemLabel) {
$(selector).sortable({
update: function() {
var itemList = $(this).sortable(
"serialize", {
attribute: "id",
key: itemLabel
});
//Create POST request to persist the update
var bodyContent = "action=" + updateAction + "&" + itemList;
if (debugMode) {
$('#report').text("DEBUG: bodyContent = \n" + bodyContent);
}
//$.post(updatePage, bodyContent, function (postResult)
//{ alert(postResult); });
}
});
}
//Set sort update action for top level and second level
setSortAction(".navLevel1",
"reorder.php",
"updateMenuListings",
"record");
setSortAction(".navLevel2",
"reorder.php",
"updateMenuItemListings",
"record");
});
#import url( 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' );
#sortable_1,
#sortable_2,
#sortable_3 {
list-style-type: none;
margin: 0;
float: left;
margin-right: 10px;
background: #eee;
padding: 5px;
width: 143px;
}
#sortable_1 li,
#sortable_2 li,
#sortable_3 li {
margin: 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
table {
font-size: 1em;
}
.ui-draggable,
.ui-droppable {
background-position: top;
}
#report {
position: fixed;
font-size: 0.5em;
bottom: 2em;
left: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul id="Nav" class="sortable navLevel1">
<ul id="sortable_1" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Classes</li>
<li id="item_1" class="ui-state-default">Some class</li>
<li id="item_2" class="ui-state-default">Another one!</li>
<li id="item_3" class="ui-state-default">Yep, thats enough</li>
</ul>
<ul id="sortable_2" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Presentation</li>
<li id="item_4" class="ui-state-default">Tom</li>
<li id="item_5" class="ui-state-default">Jessica</li>
<li id="item_6" class="ui-state-default">Kevin</li>
</ul>
</ul>
<div id="report"></div>
<br style="clear:both">

Onhover of Navigation change to light color background

I am doing a functionality for my website, where I want a functionality as same here.
In detail: When I hover on navigation, I want to make the background light.
Do let me know if needed anything else.
I hope I understand your question. See the example below:
$(document).ready(function() {
$("ul li").mouseover(function () {
$(this).addClass('light-bg', 1000);
$('body').addClass('new-body-bg', 1000);
});
$("ul li").mouseleave(function () {
$(this).removeClass('light-bg', 1000);
$('body').removeClass('new-body-bg', 1000);
}); });
ul {
background-color: #ddd; /* Choose the color of your choice */
height: 40px;
}
li {
display: inline-block;
font-size: 18px;
padding: 10px;
line-height: 20px;
text-align: center;
margin-right: 15px;
}
.light-bg {
background-color: #fff; /* Choose the color of your choice */
line-height: 20px;
}
.new-body-bg {
background-color: #ccc; /* Choose the color of your choice */
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li> One </li>
<li> Two </li>
<li>Three </li>
<li> Four</li>
</ul>
It works perfectly on JsFiddle
See: http://jsfiddle.net/snlacks/tekokmke/1/
Without using jQuery,
you want to find all of the elements you want to do this to
then you want to loop through them
You'll apply two listeners to each one, one for entering and one for leaving.
js:
var mes = document.querySelectorAll(".me");
function changeIn(){
document.body.style.backgroundColor = "lightgray";
}
function changeOut(){
document.body.style.backgroundColor = "darkgray";
}
for(i = 0; i < mes.length; i++){
mes[i].onmouseenter = changeIn;
mes[i].onmouseleave = changeOut;
}

Drop Down Menu Issue

I am writing a drop-down menu for the school intranet site and I have created a rather strange issue. The sub-menus are offset from the selected menu y position by 36px.
Here's a excerpt of the code (please excuse the quality :D)
<html>
<head>
<style>
#navagationBar {
margin: 0;
padding: 0;
z-index: 30;
}
#navagationBar li {
list-style: none;
float: left;
font: bold 12px 'Arial';
margin-left: 10px;
width: 96px;
}
#navagationBar li a {
display: block;
margin: 0 1px 0 0;
padding: 4px 10px;
width: 136px;
color: #FFFFFF;
text-align: center;
text-decoration: none;
}
#navagationBar li a:hover {
background: #796952;
}
#navagationBar div {
position: absolute;
visibility: hidden;
background: transparent;
}
#navagationBar div a {
position: relative;
display: block;
padding: 5px 10px;
width: 136px;
white-space: nowrap;
text-align: left;
text-decoration: none;
background: #796952;
color: #FFF;
font: 9px "Arial";
}
#navagationBar div a:hover {
background: #969696;
color: #FFF;
}
#navagationBar a {
color: #FFF;
}
div.navagation {
background: #2d221c;
height: 28px;
}
div.sub {
left: 156px;
}
</style>
<!-- BG COLOR: #2d221c
FORERGROUND: #3c3429
HOVER: #796952
-->
<script>
var menuItem = 0;
var subItem = 0;
var timeLimit = 250;
var closeTimer = 0;
var closeSubTimer = 0;
// open menu
function openMenu(id) {
stopTimer();
// If a layer is already open close it
if (menuItem) {
menuItem.style.visibility = 'hidden';
}
// Then set the one clicked on by the user to be shown
menuItem = document.getElementById(id);
menuItem.style.visibility = 'visible';
}
function openSub(id) {
stopSubTimer();
// If a layer is already open close it
if (subItem) {
subItem.style.visibility = 'hidden';
}
subItem = document.getElementById(id);
subItem.style.visibility = 'visible';
}
function close() {
if (menuItem) {
menuItem.style.visibility = 'hidden';
}
}
function closeSub() {
if (subItem) {
subItem.style.visibility = 'hidden';
}
}
function startTimer() {
closeTimer = window.setTimeout(close, timeLimit);
}
function startSubTimer() {
closeSubTimer = window.setTimeout(closeSub, timeLimit);
}
// Stop timing
function stopTimer() {
if (closeTimer) {
window.clearTimeout(closeTimer);
closeTimer = null;
}
}
// TODO: Make more modular
function stopSubTimer() {
if (closeSubTimer) {
window.clearTimeout(closeSubTimer);
closeSubTimer = null;
}
}
// If the user click out, close teh box
document.onclick = close();
document.onclick = closeSub();
</script>
</head>
<body>
<div class="navagation">
<ul id="navagationBar">
<li>HSIE
<div id="menu0" onMouseOver="stopTimer()" onMouseOut="startTimer()">
Business Studies
<div class='sub' id="submenu0_0" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">
<a href='view.php?id=110'>Year 11</a>
<a href='view.php?id=109'>Year 12</a>
</div>
Commerce
<div class='sub' id="submenu0_1" onMouseOver="openSub('submenu0_1')" onMouseOut="startSubTimer()">
<a href='view.php?id=112'>Year 9</a>
<a href='view.php?id=111'>Year 10</a>
</div>
Geography
<div class='sub' id="submenu0_2" onMouseOver="openSub('submenu0_2')" onMouseOut="startSubTimer()">
<a href='view.php?id=48'>Year 7</a>
<a href='view.php?id=92'>Year 8</a>
<a href='view.php?id=105'>Year 9</a>
<a href='view.php?id=70'>Year 10</a>
<a href='view.php?id=69'>Year 11</a>
<a href='view.php?id=131'>Year 12</a>
</div>
History
<div class='sub' id="submenu0_3" onMouseOver="openSub('submenu0_3')" onMouseOut="startSubTimer()">
<a href='category.php?id=89'>Junior</a>
<a href='category.php?id=90'>Senior</a>
</div>
</div>
</li>
</ul>
</div>
</body>
</html>
Try putting the sub menu divs before the corresponding a tags (instead of putting these divs after them).
For instance, try this:
<div class='sub' id="submenu0_0" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">
<a href='view.php?id=110'>Year 11</a>
<a href='view.php?id=109'>Year 12</a>
</div>
Business Studies
Instead of this:
Business Studies
<div class='sub' id="submenu0_0" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">
<a href='view.php?id=110'>Year 11</a>
<a href='view.php?id=109'>Year 12</a>
</div>
DOM Access
First, you have to make absolutely sure to not access the DOM by getElementbyId(); before the whole page has loaded.
You have to invoke the script right before the closing body tag or wrap your whole code in one function and invoke it at the end, right before the closing body tag. This is Yahoo! and Google Front-End Development best practice.
Alternatively you could use JQuery's $(document).ready() function or another JavaScript library's document-loaded function. Using a library for addressing just this issue, however would be overkill.
Global Variables
By declaring var menuItem = 0; outside the function scope, you declare the variable as a global, which is a very bad thing! It will clutter your entire Web site's namespace. Declare variables inside a function to create a closure.
Also you don't want to initialise your menuItem variable with an integer, because you will reference an object later on (a DOM object). Albeit Javascript doesn't need types to be dclared and this will work, it is creating confusion with the reader of the code. Just use var menuItem; inside the function.
CSS Block Formatting Context
Try using display: inline or display: block with your HTML elements. Make sure to read and understand the W3C CSS Visual formatting model.
You have individual IDs for each sub level so you could add styling for each.
#submenu0_0 > a {top:0px;}
#submenu0_1 > a {top:25px;}
#submenu0_2 > a {top:50px;}
#submenu0_3 > a {top:75px;}
Is this due to quirks mode?
Try using a proper doctype like this:
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
</body>
</html>

Categories

Resources