let slider = document.getElementById("slider");
let rightBtn = document.getElementById("rightbutton");
let leftBtn = document.getElementById("leftbutton");
let element = document.getElementById("elementtype").innerHTML;
let celciusBoiling = document.getElementById("celciusboiling").value;
let chlorine = ["Chlorine", 100, 200];
function moveSliderRight() {
if (rightBtn.onclick) {
slider.value++;
}
}
function moveSliderLeft() {
if (leftBtn.onclick) {
slider.value--;
}
}
function main() {
moveSliderRight();
moveSliderLeft();
if (slider.value == parseInt(2)) {
element = chlorine[0];
celciusBoiling = chlorine[1];
}
}
main();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: peachpuff;
}
header {
width: 90%;
margin: 10px auto 0px;
}
header h1 {
text-align: center;
border: 1px solid black;
padding: 15px 0px;
}
.navbar {
width: 75%;
margin: 50px auto 50px;
padding: 10px 0px;
display: flex;
justify-content: space-around;
border: 1px solid black;
}
.navlinks {
border-right: 1px solid black;
width: 50%;
text-align: center;
display: block;
}
#nav3 {
border: none;
}
#intro {
margin: 0px auto 50px;
width: 40%;
text-align: center;
}
#slider {
-webkit-appearance: none;
background-color: grey;
width: 90%;
display: block;
margin: auto;
}
#slider::-webkit-slider-thumb {
cursor: pointer;
}
#slider::-moz-range-thumb {
cursor: pointer;
}
#valuetag {
text-align: center;
margin-top:25px;
}
h2 {
text-align: center;
font-size: 45px;
text-decoration: underline;
}
#display {
width: 90%;
margin-left: 50px;
margin-bottom: 50px;
font-size: 40px;
}
#display div {
display: inline-block;
width: 45%;
text-align: center;
}
span {
font-size: 15px;
}
.boiling {
margin-left: 6%;
}
.boilingpointslider {
text-align: center;
}
button {
margin: 20px 20px 20px 0px;
width: 75px;
}
<header>
<h1>Periodic Table Gases - Interative Slider</h1>
<nav>
<div class="navbar">
<div class="navlinks">Boiling Point</div>
<div class="navlinks" id="nav3">Melting Point</div>
</div>
</nav>
</header>
<div id="intro">
<p>Interact with the slider buttons to view the displayed properties held by gases, within the periodic table of elements.</p>
</div>
<h2 id="elementtype">Hydrogen</h2>
<div id="display">
<div class="boiling">
<h2>Boiling Point</h2>
<input id="celciusboiling" type="number" value="0"><span>℃</span>
<input id="fahrenboiling" type="number"><span>℉</span>
<input id="kelvinboiling" type="number"><span>K</span>
</div>
<div class="melting">
<h2>Melting Point</h2>
<input id="celciusmelting" type="number"><span>℃</span>
<input id="fahrenmelting" type="number"><span>℉</span>
<input id="kelvinmelting" type="number"><span>K</span>
</div>
</div>
<input type="range" min="0" max="9" value="0" id="slider">
<div class="boilingpointslider">
<button id="leftbutton" onclick="moveSliderLeft()">Left</button>
<button id="rightbutton" onclick="moveSliderRight()">Right</button>
</div>
I am having issues transferring a value to an input field.
Within the snippet linked their is a heading with the value hydrogen and to the bottom left their is a boiling point heading with a input field for celcius.
I'm trying to achieve a scenario whereby you move the slider along using the buttons and at each value the heading changes to a different element and the input value for just the celcius boiling point changes.
I can't get this to work though. The buttons are working to make the slider move left and right, but for whatever reason i cant get the value to appear within the input field or change the heading. I've displayed the code i have already to get the buttons to move the slider and a snippet of what i thought would allow the changes i want to take place when the slider value changes to 2. I cant get it to to work though
Thanks.
You don't show your HTML, but I presume that slider is an input (text or hidden).
The value attribute is a string, even if you assign it a number, so you need to first convert it to a integer if you want to increment or decrement it, like so:
slider.value = parseInt(slider.value)++ // or --
Note that also you are trying to parseInt(2) down in your main(), which makes no sense as 2 is already an integer.
Related
I have two toggles (toggle-1 and toggle-2) with different contents in a header. I would like to prevent the user to have both toggles active simultaneously (otherwise they overlap).
In the code below I tried to use if statements to hide one of the toggles if the other is already opened but it does not work.
Ideally, what I would like to happen is that if toggle-1 is active and the user clicks on toggle-2, then toggle-1 would come back to its original state and toggle-2 would be now active. The same the other way around.
I am not familiar with JavaScript yet and I'd really appreciate if you could tell me what I have done wrong and how it should be done to have my ideal result
Here's the link to my CodePen if you find it easier:
https://codepen.io/fergos2/pen/NWWxgEp
var myToggle
var oneToggle = $(document).ready(function() {
$('.toggle-1').click(function() {
$('.toggle-1').toggleClass('active')
$('.toggle-1-content').toggleClass('active')
})
})
var twoToggle = $(document).ready(function() {
$('.toggle-2').click(function() {
$('.toggle-2').toggleClass('active')
$('.toggle-2-content').toggleClass('active')
})
})
if (myToggle == oneToggle) {
$(document).ready(function() {
$('toggle-2-content').hide();
})
} else if (myToggle == twoToggle) {
$('toggle-1-content').hide();
}
.container {
width: 100%;
height: 1000px;
margin: 0 auto;
background-color: #eee;
}
.wrapper {
background-color: pink;
position: relative;
display: flex;
align-items: center;
}
.toggle-1,
.toggle-2 {
display: block;
width: 20px;
height: 20px;
float: left;
cursor: pointer;
color: white;
text-align: center;
background-color: green;
margin: 10px;
}
.toggle-1.active,
.toggle-2.active {
background-color: red;
}
.toggle-1-content,
.toggle-2-content {
display: none;
}
.toggle-1-content.active,
.toggle-2-content.active {
display: block;
background-color: white;
border: 1px solid black;
position: absolute;
top: 40px;
}
.toggle-1-content.active {
left: 0;
}
.toggle-2-content.active {
left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<div class="toggle-1">1</div>
<div class="toggle-1-content">
<p>Some content 1</p>
</div>
<div class="toggle-2">2</div>
<div class="toggle-2-content">
<p>Some content 2</p>
</div>
</div>
</div>
Several issues.
Please study the code below
too many $(document.ready... and no need to store the result of such a statement
Using a data-attribute and a common class, shortens the code a lot. DRY Don't repeat yourself
I simplified the content containers CSS too
$(function() { // on page load
$('.toggle').on("click", function() { // any of the toggles
const $wrapper = $(this).closest(".wrapper");
const id = $(this).data("id");
$(this).toggleClass('active'); // toggle clicked div
const show = $(this).is(".active"); // is it active after we toggled?
$wrapper
.find(".toggle") // find all toggles
.not(this) // exclude the one we clicked
.removeClass("active"); // remove class
$wrapper.find(".content").hide(); // hide any content divs
$("#" + id).toggle(show); // show the one belonging to the clicked toggle
})
})
.container {
width: 100%;
height: 1000px;
margin: 0 auto;
background-color: #eee;
}
.wrapper {
background-color: pink;
position: relative;
display: flex;
align-items: center;
}
.toggle {
display: block;
width: 20px;
height: 20px;
float: left;
cursor: pointer;
color: white;
text-align: center;
background-color: green;
margin: 10px;
}
.active {
background-color: red;
}
.content {
display: none;
background-color: white;
border: 1px solid black;
position: absolute;
top: 40px;
}
#div1 {
left: 0;
}
#div2 {
left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<div class="toggle" data-id="div1">1</div>
<div id="div1" class="content">
<p>Some content 1</p>
</div>
<div class="toggle" data-id="div2">2</div>
<div id="div2" class="content">
<p>Some content 2</p>
</div>
</div>
</div>
Working code:
$(document).ready(function() {
$('.toggle-1').click(function() {
if ($('.toggle-2').hasClass('active')) {
// remove toggle-2 active classes
$('.toggle-2').removeClass('active');
$('.toggle-2-content').removeClass('active');
}
$('.toggle-1').toggleClass('active');
$('.toggle-1-content').toggleClass('active');
});
$('.toggle-2').click(function() {
if ($('.toggle-1').hasClass('active')) {
// remove toggle-1 active classes
$('.toggle-1').removeClass('active');
$('.toggle-1-content').removeClass('active');
}
$('.toggle-2').toggleClass('active');
$('.toggle-2-content').toggleClass('active');
});
});
Here is the link to my working version.
A few things to keep in mind:
You don't need to call $(document).ready() multiple times. There's just no reason to call it multiple times on a single page as the event is only fired once.
You need to keep track of state somehow; hence the if ($('el').hasClass('classname')) syntax. Once you handle that properly, it's easy to ensure that each element is 'reset' to its original state when the other is clicked.
Hope that helps!
toggleClass accepts a second boolean parameter that forces the type of toggle, on or off. More than that you can also target multiple elements with a single jQuery call, so use that to your advantage since the classes applied have the same name.
So you could simplify your code to
$(document).ready(function() {
$('.toggle-1').click(function() {
$('.toggle-1, .toggle-1-content').toggleClass('active');
$('.toggle-2, .toggle-2-content').toggleClass('active', false)
})
$('.toggle-2').click(function() {
$('.toggle-2, .toggle-2-content').toggleClass('active');
$('.toggle-1, .toggle-1-content').toggleClass('active', false)
})
})
.container {
width: 100%;
height: 1000px;
margin: 0 auto;
background-color: #eee;
}
.wrapper {
background-color: pink;
position: relative;
display: flex;
align-items: center;
}
.toggle-1,
.toggle-2 {
display: block;
width: 20px;
height: 20px;
float: left;
cursor: pointer;
color: white;
text-align: center;
background-color: green;
margin: 10px;
}
.toggle-1.active,
.toggle-2.active {
background-color: red;
}
.toggle-1-content,
.toggle-2-content {
display: none;
}
.toggle-1-content.active,
.toggle-2-content.active {
display: block;
background-color: white;
border: 1px solid black;
position: absolute;
top: 40px;
}
.toggle-1-content.active {
left: 0;
}
.toggle-2-content.active {
left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<div class="toggle-1">1</div>
<div class="toggle-1-content">
<p>Some content 1</p>
</div>
<div class="toggle-2">2</div>
<div class="toggle-2-content">
<p>Some content 2</p>
</div>
</div>
</div>
You can use the method "removeClass" to remove the active class from the other toggle
var oneToggle = $(document).ready(function() {
$(".toggle-1").click(function() {
$(".toggle-1").toggleClass("active")
$(".toggle-1-content").toggleClass("active")
$(".toggle-2").removeClass("active")
$(".toggle-2-content").removeClass("active")
})
})
var twoToggle = $(document).ready(function() {
$(".toggle-2").click(function() {
$(".toggle-1").removeClass("active")
$(".toggle-1-content").removeClass("active")
$(".toggle-2").toggleClass("active")
$(".toggle-2-content").toggleClass("active")
})
})
I have a number input type element. I want its value to be displayed in the span next to it. As I click or scroll on the increase or decrease button inside the input. I want the span's relative value to change. Is it possible??
I have tried to get the value and display in span but did not worked.
Javascript
var displayer = document.getElementById('displayer');
var day = document.getElementById('days');
var hrs = document.getElementById('hours');
var s_t = document.getElementById('s_t');
function funcday() {
day.style.border = "1.5px solid darkorange";
hrs.style.border = "1.5px solid mediumaquamarine";
s_t.style.border = "1.5px solid darkorange";
s_t.setAttribute("max", 365);
var d = s_t.value;
document.getElementById('display_d').textContent = d;
}
function funhrs() {
day.style.border = "1.5px solid mediumaquamarine";
hrs.style.border = "1.5px solid darkorange";
s_t.style.border = "1.5px solid darkorange";
s_t.setAttribute("max", 48);
var h = s_t.value;
document.getElementById('display_h').textContent = h;
}
#container {
display: flex;
}
.st {
width: 60px;
margin-right: 10px;
}
#days,
#hours {
color: #fff;
width: 70px;
margin-left: 10px;
padding: 6px;
cursor: pointer;
background-color: mediumaquamarine;
border: 1.5px solid mediumaquamarine;
text-align: center;
font-family: 'Courier';
}
.displayer {
align-content: center;
text-align: center;
line-height: 2;
margin-left: 20px;
margin-right: 20px;
font-size: 15px;
border: 1px solid white;
display: block;
float: right;
}
.displayer span {
margin-right: 5px;
margin-left: 5px;
}
<div id="container">
<input type="number" min="1" class="st" id="s_t" autocomplete="off">
<div id="days" onclick="funcday();">Days</div>
<div id="hours" onclick="funhrs();">Hours</div>
<div id="displayer" class="displayer">
<span id="display_d">00</span><span>Days</span>
<span id="display_h">00</span><span>Hours</span>
</div>
</div>
You should add onchange event handler to the input element and change text of the span element inside this handler.
im trying to make a average grade calculator, now thats is going fine but now i want to calculate the average immediately when a number gets inputted in one of the fields. I've been trying this with "on(), live(), onkeyup()" but can't get it to work.
The result of the average now displays beneath the inputfields 'onclick' on the button. I want the average displayed there but then as soon as you input numbers in one of the fields it should show there as it now does after the onclick.
What i've tryed with the 'on(), live(), onkeyup()' is to connect them to the input fields and connect them to the calculator() function.
Is there a easy way to do this or a other certain way?
greetings.
function calculator() {
var weight = 0;
var mark = 0;
var weights = document.querySelectorAll('[id^=weight-]');
var grades = document.querySelectorAll('[id^=mark-]');
var trs = document.getElementsByTagName('tr');
var tBody = document.getElementsByTagName('tbody')[0];
var totalWeight = 0;
var totalGrade = 0;
for (var i = 0; i < weights.length; i++) {
totalWeight += +weights[i].value;
}
for (var i = 0; i < grades.length; i++) {
totalGrade += +grades[i].value;
}
var finalGrade=totalGrade/totalWeight;
var display = document.getElementById('output-div');
var newTr = document.createElement('TR');
newTr.innerHTML = `<td><input id="weight-${trs.length + 1}" type="text" size=2 value=""></td><td><input id="mark-${trs.length + 1}" type="text" size=2 value=""></td>`;
tBody.appendChild(newTr);
display.innerHTML='Je gemiddelde is: ' +finalGrade.toFixed(2);
}
html {
background-color: ;
}
header {
background-color: ;
}
h2 {
text-align: center;
}
h3 {
text-align: center;
}
body {
font-family: 'Roboto', sans-serif;
}
table {
margin: auto;
}
tr {
background-color: ;
}
td {
background-color: ;
}
#table-title {
font-size: 20px;
font-style: italic;
text-align: center;
position: relative;
}
input {
text-align: center;
}
[id^="mark"] {
width: 100px;
}
[id^="weight"] {
width: 100px;
}
#calc-btn-div {
position: relative;
width: 150px;
margin: auto;
}
#calc-btn {
position: relative;
padding: 5px;
margin-top: 20px;
}
#calc-btn:hover {
border-color: black;
box-shadow: 8px 8px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
}
/* #add-input-div {
height: 50px;
text-align: center;
width: 300px;
margin: auto;
margin-top: 20px;
}
#add-input-btn {
position: relative;
padding: 5px;
margin-top: 20px;
}
#add-input-btn:hover {
border-color: black;
box-shadow: 8px 8px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
} */
#output-div {
background-color: ;
height: 50px;
text-align: center;
width: 300px;
margin: auto;
margin-top: 20px;
}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.modal-content {
background-color: #fefefe;
margin: 15% auto; /* 15% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
</head>
<header>
<h2>Gemiddelde cijfer</h2>
<h3>Voer hieronder je cijfers in</h3>
</header>
<body>
<table id="table">
<tr id="table-title">
<td>Weging</td>
<td>Cijfer</td>
</tr>
<tr>
<td><input id="weight-1" type="text" size=2 value=""></td>
<td><input id="mark-1" type="text" size=2 value=""></td>
</tr>
</table>
<div id="calc-btn-div">
<input id="calc-btn" type="button" value="Berekenen je gemiddelde" onclick="calculator()">
</div>
<!-- <div id="add-input-div">
<input id="add-input-btn" type="button" value="Voeg cijfer toe" onclick="addInput()">
</div> -->
<div id="output-div"></div>
</body>
</html>
Using vanilla JavaScript I would attach an eventListener to the inputfields like this
document.getElementById('weight-1').addEventListener('change',function(){
calculator();
});
document.getElementById('mark-1').addEventListener('change',function(){
calculator();
});
These addEventListener functions adds listeners to the "input" field's predefined 'change'-events, and fires the calculator(); function from your code.
Seeing that you are using some sort of dynamic generation of the inputfields, you could add the listeners to your inputfields using the same querySelector that you use to target them during calculation. It would mean replacing getElementById('weight-1') in my example above with querySelectorAll('[id^=weight-]') for the weight-fields.
Also, doing work with values, IO, and calculation between html and JavaScript, I would suggest using a library like jQuery. jQuery simplifies these processes a lot.
This is the documentation for the jQuery alternative onClick function:
https://api.jquery.com/change/
I think you could do that with an angularJS module. Take a look at this tutorial : https://www.w3schools.com/angular/angular_modules.asp
maybe it will help.
I have this flexible layout and some JS https://jsfiddle.net/7k8t3xgc/3/
<div class="window">
<div class="left">
<div class="optional">optional content</div>
</div>
<div class="right">
<div class="wordpool"></div>
<div class="category"></div>
</div>
</div>
The .wordpool element is filled with some words that need to be moved to the .category element by clicking on them.
What is happening now, is that the .window element is shrinking in width when you click the words. Is there a way to prevent this behaviour? Only way I can think of is to calculate wordpools width on render and set it into a style attribute, but it has its drawbacks with responsiveness.
I can't remove the flex functionality, because both left (optional) and right panels need to be same width and centered.
I can't use static width as it needs to be responsive.
It can't be something like .window { width: 90%; } because of short content looking silly on wide screens.
Both left and right content changes between pages in my app (think of a quiz or Google Forms - can be text, can be images, checkboxes, radiobuttons etc.) but the HTML template is the same.
As you want it to be dynamic, based on the actual text width on load, add this line to your script
$(".window").css('min-width', $(".window").width() + 'px');
Updated fiddle
Instead of monitoring the resize event for smaller screens, you can do like this instead
Note, the width: 100% needs to be set using the script, if set in CSS, the calculation will be wrong
$(".window").css({'max-width':$(".window").width() + 'px','width':'100%'});
Updated fiddle 2
Just to provide another solution, that may or not be what you want:
Don't change the elements from container, just have them on both containers, and toggle the opacity.
You can rearrange them using flexbox and order
var buttons = [{
name: "lorem"
},
{
name: "ipsum"
},
{
name: "dolor"
},
{
name: "sit"
},
{
name: "amet"
}
];
$(document).ready(function() {
for (b of buttons) {
$('.wordpool').append($("<span>", {
class: "word",
id: b.name
}).html(b.name));
$('.category').append($("<span>", {
class: "word hidden",
id: b.name
}).html(b.name));
}
$(".wordpool").on("click", "span", function() {
$(this).toggleClass('hidden');
$(".category #" + $(this).attr('id')).toggleClass('hidden');
});
$(".category").on("click", "span", function() {
$(this).toggleClass('hidden');
$(".wordpool #" + $(this).attr('id')).toggleClass('hidden');
});
$("body").on("click", ".showoptional", function() {
$(".left").toggle();
});
});
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
background: #f4efdc;
}
.showoptional {
position: absolute;
top: 5px;
left: 5px;
}
.window {
background: #fff;
box-shadow: 0 0 10px #ccc;
display: flex;
}
.left,
.right {
padding: 20px;
flex: 1 0 0px;
}
.left {
display: none;
}
.optional {
background: #eee;
text-align: center;
padding: 50px 0;
}
.word {
display: inline-block;
margin: 2px 5px;
padding: 3px 5px;
border: 1px solid #ddd;
cursor: pointer;
}
.hidden {
opacity: 0;
order: 99;
}
.wordpool {
text-align: center;
display: flex;
}
.category {
margin-top: 10px;
border: 1px solid #ccc;
min-height: 60px;
}
.category .word {
display: block;
text-align: center;
margin: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<input type="button" class="showoptional" value="Trigger optional content" />
<div class="window">
<div class="left">
<div class="optional">optional content</div>
</div>
<div class="right">
<div class="wordpool"></div>
<div class="category"></div>
</div>
</div>
</div>
for a project I'm working on, I have a console emulator (as shown below), but I have run into one problem; receiving user input. I need it to create a text box, wait for the user to hit enter, then return the value in the text box, OR if the textbox is empty when enter is pressed, move to the next line with another textbox (same thing until input is received), however, other methods are fine as long as they provide this style of input. the code that does this should be put in the function "input". In the below code, the div 'console' should read:
1
23[textbox]
[whatever the user entered]
if someone could show me a function that performs this, it would be greatly appereciated
<html>
<head></head>
<body>
<style>
div
{
font-family: Consolas;
color: #ffffff;
background: #000000;
height: 310px;
width: 670px;
overflow-y: scroll;
outline: 100px;
outline-color: #888888;
margin: 0;
}
p
{
margin: 0;
}
#headbar
{
background: #0000ff;
color: orange;
height: 20px;
overflow-y: auto;
width: 650px;
}
#redx
{
height: 20px;
width: 20px;
color: black;
background: red;
overflow: auto;
display: inline-block;
margin-left: 650px;
margin-top: -20px;
padding: auto;
}
#console
{
font-size: 15;
overflow-x: hidden;
}
br
{
margin: 0;
}
input
{
margin: 0;
}
</style>
<div id="headbar">
<p style ="margin-left: 5">file://C:/Documents%20and%20Settings/User/Desktop/th-df.html</p>
</div>
<div id="redx">
X
</div>
<div id = "console">
<script>
function output(text)
{
document.write(text);
}
function endl()
{
document.write("<br/>");
}
function input()
{
return 0;
}
output("1");
endl();
output("2");
output("3");
var foo = input();
output(foo);
</script>
</div>
</body>
</html>