jQuery multiple input changes - javascript

I am trying to use jQuery to change some HTML text by changing a slider, I figured out how to do that, but I also need to do it only if a checkbox is on, how do I put both in, and then how do I make it only do it when the checkbox is clicked, I am doing this with arrays, because I'm trying to do it in time, not decimals. Here is the link to my current code: https://codepen.io/2cheeky4you/pen/QqGKpy
$(document).on('input change', '#range-slider', '#voiceover', function() {
//Listen to slider changes (input changes)
var v=$(this).val(); //Create a Variable (v), and store the value of the input change (Ex. Image 2 [imageURL])
var q = document.querySelector('input[id="voiceover"]');
var voiceovermain = ["<span>$0.00</span>",voiceoverslider[0]];
$('#sliderStatus').html(imageUrl[v]);
$('#sliderPrice').html( sizeRange[v] );
$('#voiceoverslider').html( sizeRange[v] );
$('#voiceoverspan').html( voiceover[q] );
$("#img").prop("src", imageUrl[v]); // Modify the Images attribute src based on the sliders value, and input the value inside the imageURL[v] to display image
});
This is one of my first times using the code thing on this website, so pardon my messed up whitespaces.
I English very well :) so I'm sorry if something doesn't make sense. Just tell me in the comments if it doesn't.

I think you wish to show two prices based on the slider position, one being optionnal depending on the checkbox.
You array idea is not the best way to do it. I think you should use the slider value as an integer and calculate your prices with it.
So the first thing is to define your two prices. Then simply do some maths.
I defined your second price as $5 per slider knotch (which is 5 seconds of video duration), for this example.
Feel free to ask questions about the code if there is anything unclear.
var sliderUnit = 5; // 5 seconds of video duration per slider notch
var basePrice = 100;
var price = 10;
var subPrice = 5;
$(document).on('input change', '#range-slider, #voiceover', function() { //Listen to slider changes (input changes)
var slider=parseInt($('#range-slider').val());
var voiceOption = $('#voiceover');
console.log(slider); // returns an integer from 0 to 34
// Time
var seconds = (slider*5)%60;
var minutes = Math.floor(slider*5/60);
if(seconds<10){seconds= "0"+seconds} // Leading zero
$('#sliderStatus').html('<span>'+minutes+":"+seconds+'</span>');
// Price for video duration
var price1 = (slider*price) +basePrice;
$('#sliderPrice').html('<span>$'+price1+'.00</span>');
// Price for voiceover
var price2 = slider*subPrice;
if( voiceOption.is(":checked") ){
$('#voiceoverspan').html('<span>$'+price2+'.00</span>');
}else{
$('#voiceoverspan').html('<span>$0.00</span>');
}
});
// ::::: Range Slider Thumb ::::: //
$("#range-slider").on("mousedown mouseup", function() { //1. When user clicks their mouse down on the Range-Slider
$(this).toggleClass("thumb-down hover-ring thumb-up hover-ring-out");
});
#slider_count {
margin:0px auto;
width:200px;
padding:20px 20px;
text-align:center;
background-color:yellow;
}
/* ::::::::::::::::::::Range Slider Styles::::::::::::::::::::::::: */
.range-slider-block {
margin:0px auto;
width:90%;
}
#range-slider {
padding:40px 0px;
width:100%;
/*outline: 1px solid green;*/
}
/* Remove Range Sliders Default Styles*/
input[type=range]{
-webkit-appearance: none;
}
/* Track */
input[type=range]::-webkit-slider-runnable-track {
height: 10px;
background: #d7d7d7;
border: none;
border-radius: 6px;
}
input[type=range]:focus {
outline: none;
}
/* Thumb */
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: none;
height: 30px;
width: 30px;
border-radius: 50%;
background: #46947F;
margin-top: -9px;
transition: box-shadow 0.5s;
}
input[type=range]:hover::-webkit-slider-thumb {
box-shadow: 0 0 0 10pt rgba(190,190,190,0.4);
cursor:pointer;
}
/* JS Stykes */
/* Changes Thumb color to darker green when mousedownn */
input[type=range].thumb-down::-webkit-slider-thumb {
background:#316557;
}
/* Changes Thumb color back to light green when mouseup */
input[type=range].thumb-up::-webkit-slider-thumb {
background:#46947F;
}
/* Changes Ring color Green */
input[type=range].hover-ring::-webkit-slider-thumb {
box-shadow: 0 0 0 6pt rgba(70,148,127,0.46);
cursor:pointer;
}
input[type=range].hover-ring-out::-webkit-slider-thumb {
box-shadow: 0 0 0 0pt rgba(0,0,0,0);
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div class="range-slider-block">
<input type="range" id="range-slider" class="thumb-up hover-ring-out" value="0.0" min="0" max="34" step="1" />
</div>
<div id="slider_count">Time = <span id="sliderStatus">0:00</span></div>
<br/>
<div id="slider_count">Subprice (Video Duration) = <span id="sliderPrice">$0.00</span></div>
<br/>
<label for="voiceover">Would you like a voiceover?</label>
<input type="checkbox" id="voiceover" name="voiceover" checked>
<div id="slider_count">Subprice (for voiceover): = <span id="voiceoverspan">$0.00</span></div>
</form>
Notice that I also improved the handler to add/remove classes on the slider...
CodePen

Hey I found the issue with your code and put a new codepen up: https://codepen.io/anon/pen/LzbBOx?editors=1111
Imediately after
function() {
you should put:
var check = $('#voiceover')[0];
if (check.checked) {
// your entire function's code here
}

I added a section to your code and modified it a little. Basically I added an if statement that checked if the check was on or not and then copied the value of the slider price into it. Of course you can do anything you want with the value but I was not sure exactly what value you wanted for the subprice. Good luck.
var sizeRange = [" <span>$100.00</span>",
" <span>$110.00</span>",
"<span>$120.00</span>",
"<span>$130.00</span>",
"<span>$140.00</span>",
"<span>$150.00</span>",
" <span>$160.00</span>",
" <span>$170.00</span>",
" <span>$180.00</span>",
" <span>$190.00</span>",
" <span>$200.00</span>",
" <span>$210.00</span>",
" <span>$220.00</span>",
" <span>$230.00</span>",
" <span>$240.00</span>",
" <span>$250.00</span>",
" <span>$260.00</span>",
" <span>$270.00</span>",
" <span>$280.00</span>",
" <span>$290.00</span>",
" <span>$300.00</span>",
" <span>$310.00</span>",
" <span>$320.00</span>",
" <span>$350.00</span>",
" <span>$380.00</span>",
" <span>$410.00</span>",
" <span>$440.00</span>",
" <span>$470.00</span>",
" <span>$500.00</span>",
" <span>$530.00</span>",
" <span>$560.00</span>",
" <span>$590.00</span>",
" <span>$620.00</span>",
" <span>$650.00</span>",
" <span>$680.00</span>"
];
var imageUrl = [" <span>:10</span>",
" <span>:15</span>",
"<span>:20</span>",
"<span>:25</span>",
"<span>:30</span>",
"<span>:35</span>",
" <span>:40</span>",
" <span>:45</span>",
" <span>:50</span>",
" <span>:55</span>",
" <span>1:00</span>",
" <span>1:05</span>",
" <span>1:10</span>",
" <span>1:15</span>",
" <span>1:20</span>",
" <span>1:25</span>",
" <span>1:30</span>",
" <span>1:35</span>",
" <span>1:40</span>",
" <span>1:45</span>",
" <span>1:50</span>",
" <span>1:55</span>",
" <span>2:00</span>",
" <span>2:15</span>",
" <span>2:30</span>",
" <span>2:45</span>",
" <span>3:00</span>",
" <span>3:15</span>",
" <span>3:30</span>",
" <span>3:45</span>",
" <span>4:00</span>",
" <span>4:15</span>",
" <span>4:30</span>",
" <span>4:45</span>",
" <span>5:00</span>",
]; //adds the times instead of regular numbers.
var voiceoverslider = [" <span>$100.00</span>",
" <span>$110.00</span>",
"<span>$120.00</span>",
"<span>$130.00</span>",
"<span>$140.00</span>",
"<span>$150.00</span>",
" <span>$160.00</span>",
" <span>$170.00</span>",
" <span>$180.00</span>",
" <span>$190.00</span>",
" <span>$200.00</span>",
" <span>$210.00</span>",
" <span>$220.00</span>",
" <span>$230.00</span>",
" <span>$240.00</span>",
" <span>$250.00</span>",
" <span>$260.00</span>",
" <span>$270.00</span>",
" <span>$280.00</span>",
" <span>$290.00</span>",
" <span>$300.00</span>",
" <span>$310.00</span>",
" <span>$320.00</span>",
" <span>$350.00</span>",
" <span>$380.00</span>",
" <span>$410.00</span>",
" <span>$440.00</span>",
" <span>$470.00</span>",
" <span>$500.00</span>",
" <span>$530.00</span>",
" <span>$560.00</span>",
" <span>$590.00</span>",
" <span>$620.00</span>",
" <span>$650.00</span>",
" <span>$680.00</span>"
];
$('#sliderPrice').html(sizeRange[0]);
$("#voiceover").on("change",function(){
});
$(document).on("change", '#range-slider', function() { //Listen to slider changes (input changes)
var v = $(this).val(); //Create a Variable (v), and store the value of the input change (Ex. Image 2 [imageURL])
var q = $("#slider_count").val();
var voiceovermain = ["<span>$0.00</span>",
voiceoverslider[0]
];
$('#sliderStatus').html(imageUrl[v]);
$('#sliderPrice').html(sizeRange[v]);
$('#voiceoverslider').html(sizeRange[v]);
//---------------------------------------------------------
if($("#voiceover").is(":checked")){
$("#voiceoverspan").html("");
$('#sliderPrice').clone().appendTo("#voiceoverspan");
} else {
$('#voiceoverspan').html("$0.00");
}
//-----------------------------------------------------------
$("#img").prop("src", imageUrl[v]); // Modify the Images attribute src based on the sliders value, and input the value inside the imageURL[v] to display image
});
// ::::: Range Slider Thumb ::::: //
$("#range-slider").on("mousedown", function() { //1. When user clicks their mouse down on the Range-Slider
$(this).removeClass().addClass("thumb-down"); //1.1 Remove default class from CSS, and add the class .thumb-down (changes background color)
$(this).addClass("hover-ring"); //1.2 Remove default class from CSS, and add the class .hover-ring (changes box-shadow to a green color)
});
$("#range-slider").on("mouseup", function() { //2. When user mouse-up on Range-Slider
$(this).addClass("thumb-up"); //2.1 Changes thumb color back to light green
$(this).addClass("hover-ring-out"); //2.2 Remove Box-Shadow
});
#slider_count {
margin: 0px auto;
width: 200px;
padding: 20px 20px;
text-align: center;
background-color: yellow;
}
/* ::::::::::::::::::::Range Slider Styles::::::::::::::::::::::::: */
.range-slider-block {
margin: 0px auto;
width: 90%;
}
#range-slider {
padding: 40px 0px;
width: 100%;
/*outline: 1px solid green;*/
}
/* Remove Range Sliders Default Styles*/
input[type=range] {
-webkit-appearance: none;
}
/* Track */
input[type=range]::-webkit-slider-runnable-track {
height: 10px;
background: #d7d7d7;
border: none;
border-radius: 6px;
}
input[type=range]:focus {
outline: none;
}
/* Thumb */
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: none;
height: 30px;
width: 30px;
border-radius: 50%;
background: #46947F;
margin-top: -9px;
transition: box-shadow 0.5s;
}
input[type=range]:hover::-webkit-slider-thumb {
box-shadow: 0 0 0 10pt rgba(190, 190, 190, 0.4);
cursor: pointer;
}
/* JS Stykes */
/* Changes Thumb color to darker green when mousedownn */
input[type=range].thumb-down::-webkit-slider-thumb {
background: #316557;
}
/* Changes Thumb color back to light green when mouseup */
input[type=range].thumb-up::-webkit-slider-thumb {
background: #46947F;
}
/* Changes Ring color Green */
input[type=range].hover-ring::-webkit-slider-thumb {
box-shadow: 0 0 0 6pt rgba(70, 148, 127, 0.46);
cursor: pointer;
}
input[type=range].hover-ring-out::-webkit-slider-thumb {
box-shadow: 0 0 0 0pt rgba(0, 0, 0, 0);
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div class="range-slider-block">
<input type="range" id="range-slider" value="0.0" min="0" max="34" step="1" />
</div>
<div id="slider_count">Time = <span id="sliderStatus">:10</span></div>
<br/>
<div id="slider_count">Subprice (Video Duration) = <span id="sliderPrice">$0.00</span></div>
<br/>
<label for="voiceover">Would you like a voiceover?</label>
<input type="checkbox" id="voiceover" name="voiceover" checked>
<div id="slider_count">Subprice (for voiceover): = <span id="voiceoverspan">$0.00</span></div>
</form>

Related

Blank input adds short line to to-do list

When you click inside the input box of my to-do list and hit enter, a tiny line is added to the list. (When you enter text, the line height is regular height.) What could be causing this?
Please view my CodePen for my full code.
I'm not sure this is relevant, but here's my JavaScript:
$(function() {
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
// Inserts li as first child of ul
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});
// Upon hitting enter, triggers button click and prevents page from refreshing and event bubbling and capturing/trickling
$('input[name=listItem]').keypress(function(e) {
if (e.which == 13) {
$('.button').click();
e.preventDefault();
};
});
$('ul').on('click', 'li', function() {
// Upon list item click, toggleClass() adds class 'strike' for it and fadeOut() completely hides it
$(this).toggleClass('strike').fadeOut('slow');
});
});
Just check on the value you are adding:
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
// Inserts li as first child of ul
if( toAdd == ""){
return false; // return on empty value
}
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});
Both the below answers are right and hence upvoted but You can try and add validation to remove this situation
$(function() {
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
if (toAdd === '') {
alert("Input should not be blank");
$('input[name=listItem]').focus();
return;
}
// Inserts li as first child of ul
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});
// Upon hitting enter, triggers button click and prevents page from refreshing and event bubbling and capturing/trickling
$('input[name=listItem]').keypress(function(e) {
if (e.which == 13) {
$('.button').click();
e.preventDefault();
};
});
$('ul').on('click', 'li', function() {
// Upon list item click, toggleClass() adds class 'strike' for it and fadeOut() completely hides it
$(this).toggleClass('strike').fadeOut('slow');
});
});
body {
text-align: center;
background: #dfdfdf;
font-family: Helvetica;
font-size: 14px;
color: #666;
background: linear-gradient(to left, #da4453, #89216b);
}
.container {
padding: 20px;
padding-top: 5px;
width: 400px;
/* 0 is for top and bottom and auto (set to equal values for each by browser) for left-right */
margin: 0 auto;
margin-top: 40px;
background: #eee;
border-radius: 5px;
}
form {
/* Needed to display button next to input box */
display: inline-block;
}
input[type="text"] {
border: 1px solid #ccc;
height: 1.6em;
width: 29em;
color: #666;
}
/* Sets appearance of input box boundaries when user clicks inside it */
input:focus {
border-color: #da4453;
/* L to R: horizontal offset, vertical offset, blur radius. A in RGBA is alpha parameter, a number between 0.0 (fully transparent) and 1.0 (fully opaque) */
box-shadow: 0 0 8px rgba(229, 103, 23, 0.6);
outline: 0 none;
}
button.button {
margin-left: -29.8px;
/* 2px added to account for default 1px padding of input box set by user agent (browser) stylesheet */
height: -webkit-calc(1.6em + 2px);
height: calc(1.6em + 2px);
width: 25px;
color: grey;
border: none;
}
.button:hover {
cursor: pointer;
opacity: 0.8;
color: #9a9797;
}
/* Remove margins and padding from list */
ul {
margin: 0;
padding: 0;
}
/* Applies styling to any li descendants of ul (descendant combinator) */
ul li {
text-align: left;
/* Prevents default bullet points */
list-style-type: none;
margin: auto;
cursor: pointer;
position: relative;
background-color: #eee;
/* First value sets top and bottom padding; second value sets right and left */
padding: 1.5px 0;
}
/* Set all odd list items to a different color (zebra stripes) */
ul li:nth-child(odd) {
background: #f9f9f9;
}
/* Sets darker background color on hover over list items */
ul li:hover {
background-color: #ddd;
}
.strike {
text-decoration: line-through;
}
<html>
<head>
<meta charset="UTF-8">
<title>To-Do List</title>
<link rel="stylesheet" href="styles.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="designs.js"></script>
</head>
<body>
<div class="container">
<h2>To Do</h2>
<form name="listForm">
<input type="text" name="listItem" placeholder="Add new">
<button type="button" class="button">+</button>
</form>
<br><br>
<ul>
<li>Work on projects for one hour</li>
<li>Go for a walk</li>
<li>Call parents</li>
</ul>
</div>
</body>
</html>
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
// Inserts li as first child of ul
if(toAdd == ""){
alert("Input Should no be blank");
return;
}
$('ul').prepend('<li>' + toAdd + '</li>');
// Clears input box after clicking '+'
$('input[name=listItem]').val('');
});
Try adding a check to see if there's nothing in the input box first:
$('.button').click(function() {
let toAdd = $('input[name=listItem]').val();
if (toAdd === '') return;
Using ES6 Syntax
$('.button').on('click'() => {
let toAdd = $('input[name=listItem]').val();
toAdd === '' ? return : null

Simple "Math" CAPTCHA

everyone. I am a jquery beginner and want to ask a few questions.
I am coding a simple math captcha for form submission test, I wanna generate a set of new random number each time when I press the "reset button".
But I when I google for the solution, most are trying to reload the page or reload the whole function, So I wanna ask if there is a way to do this.
And I would be very pleased if you guys can help me improving the codes as I think I am writing quite dummy. Thanks so much!!!
Please have a look at my code in fiddle :)
https://jsfiddle.net/v7bcjj1q/#&togetherjs=2nOVnkI34j
my code:
$(document).ready(function(){
$('button[type=submit]').attr('disabled','disabled');
var randomNum1;
var randomNum2;
//set the largeest number to display
var maxNum = 20;
var total;
randomNum1 = Math.ceil(Math.random()*maxNum);
randomNum2 = Math.ceil(Math.random()*maxNum);
total =randomNum1 + randomNum2;
$( "#question" ).prepend( randomNum1 + " + " + randomNum2 + "=" );
// When users input the value
$( "#ans" ).keyup(function() {
var input = $(this).val();
var slideSpeed = 200;
$('#message').hide();
if (input == total) {
$('button[type=submit]').removeAttr('disabled');
$('#success').slideDown(slideSpeed);
$('#fail').slideUp(slideSpeed);
}
else {
$('button[type=submit]').attr('disabled','disabled');
$('#fail').slideDown(slideSpeed);
$('#success').slideUp(slideSpeed);
}
});
// Wheen "reset button" click, generating new randomNum1 & randomNum2
});
For re-usability, a separate function can be used to generate the question
var total;
function getRandom(){return Math.ceil(Math.random()* 20);}
function createSum(){
var randomNum1 = getRandom(),
randomNum2 = getRandom();
total =randomNum1 + randomNum2;
$( "#question" ).text( randomNum1 + " + " + randomNum2 + "=" );
//in case of reset
$('#success, #fail').hide();
$('#message').show();
}
Inside the document load, the function can be called to initialize and subsequently attached to the click event
$(document).ready(function(){
$('button[type=submit]').attr('disabled','disabled');
//create initial sum
createSum();
// On "reset button" click, generate new random sum
$('button[type=reset]').click(createSum);
//....
One step further would be to set the visibility in a function that (re)checks the input on both keyup and reset.
Example fiddle
Just add an onClick event on the reset button
Inside you have to generate new numbers, total, clear question and clear input
$('button[type=submit]').attr('disabled', 'disabled');
var randomNum1;
var randomNum2;
//set the largeest number to display
var maxNum = 20;
var total;
randomNum1 = Math.ceil(Math.random() * maxNum);
randomNum2 = Math.ceil(Math.random() * maxNum);
total = randomNum1 + randomNum2;
$("#question").prepend(randomNum1 + " + " + randomNum2 + "=");
// When users input the value
$("#ans").keyup(function() {
var input = $(this).val();
var slideSpeed = 200;
$('#message').hide();
if (input == total) {
$('button[type=submit]').removeAttr('disabled');
$('#success').slideDown(slideSpeed);
$('#fail').slideUp(slideSpeed);
} else {
$('button[type=submit]').attr('disabled', 'disabled');
$('#fail').slideDown(slideSpeed);
$('#success').slideUp(slideSpeed);
}
});
// Wheen "reset button" click, generating new randomNum1 & randomNum2
$("#reset").on("click", function() {
randomNum1 = Math.ceil(Math.random() * maxNum);
randomNum2 = Math.ceil(Math.random() * maxNum);
total = randomNum1 + randomNum2;
$("#question").empty();
$("#ans").val('');
$("#question").prepend(randomNum1 + " + " + randomNum2 + "=");
});
* {
padding: 0;
margin: 0;
}
html,
body {
font-family: 'Open Sans';
font-weight: lighter;
font-size: 12px;
width: 100%;
height: 100%;
}
#success,
#fail {
display: none;
}
#message,
#success,
#fail {
margin-top: 10px;
margin-bottom: 10px;
}
.container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
p {
display: inline;
margin-right: 5px;
}
input,
button {
font-family: 'Open Sans';
font-weight: lighter;
font-size: 12px;
}
input {
border: 1px solid #FFBBD7;
width: 30px;
height: 20px;
text-align: center;
}
button {
border: none;
border-radius: 1.5em;
color: #FFF;
background: #FFBBD7;
padding: 2.5px 10px;
width: 75px;
height: 30px;
cursor: pointer;
transition: background .5s ease-in-out;
}
button:hover:enabled {
background: #303030;
}
button:disabled {
opacity: .5;
cursor: default;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="question"></p>
<input id="ans" type="text">
<div id="message">Please verify.</div>
<div id="success">Validation complete :)</div>
<div id="fail">Validation failed :(</div>
<button type="submit" value="submit">Submit</button>
<button type="reset" id="reset" value="reset">Reset</button>
You can do it like this, add this piece of code:
$('#reset').click(function(e){
randomNum1 = Math.ceil(Math.random()*maxNum);
randomNum2 = Math.ceil(Math.random()*maxNum);
total =randomNum1 + randomNum2;
$( "#question" ).html( randomNum1 + " + " + randomNum2 + "=" );
});
#reset is in this case your reset button. You should just give it that ID, or change the selection depending on what you like most.
On click, you'll reset the variables, and change the HTML from the question.
I did it by just duplicating the code, but you might want to create a single function for it, as you are using it multiple times.

Javascript: Create draggable elements that push each other out of the way

I would like to have a series of boxes that can be dragged around in a frame. When when they touch another box, it is pushed out of the way - repelled if you will.
I just don't even know where to start beyond making them draggable!!
To expand on my comment and show you a possible proof of concept, I have created this small bit of code:
https://jsfiddle.net/Twisty/L03rks0y/
HTML
<div id="move-frame">
<div id="obj-1" class="drag">
<span class="top">T: 2</span>
<span class="left">L: 2</span>
<span class="bottom">B:</span>
<span class="right">R:</span>
</div>
<div id="obj-2" class="no-drag">
<span class="top">T: 125</span>
<span class="left">L: 175</span>
</div>
</div>
CSS
#move-frame {
border: 1px solid #000;
margin: 20px;
padding: 2px;
width: 300px;
height: 300px;
position: relative;
}
.drag,
.no-drag {
border: 0px solid #666;
width: 75px;
height: 75px;
}
.top,
.left,
.bottom,
.right {
display: block;
font-size: 85%;
font-family: Arial;
width: 100%;
text-align: center;
}
#obj-1 {
background: #6f6;
}
#obj-2 {
background: #ccf;
position: absolute;
top: 125px;
left: 175px;
}
jQuery UI
$(function() {
var stuff = {};
$(".no-drag").each(function(k, v) {
var id = $(v).attr("id");
var top = $(v).position().top;
var left = $(v).position().left;
var bottom = top + $(v).height();
var right = left + $(v).width();
stuff[k] = {
id: id,
top: top,
left: left,
bottom: bottom,
right: right
};
});
console.log(stuff);
$("#obj-1").draggable({
containment: '#move-frame',
drag: function(e, ui) {
var objW = ui.helper.width();
var objH = ui.helper.height();
var objP = ui.position;
var buffer = 2;
objP.right = objP.left + objW;
objP.bottom = objP.top + objH;
$(this).find(".top").html("T: " + objP.top);
$(this).find(".left").html("L: " + objP.left);
$(this).find(".bottom").html("B: " + objP.bottom);
$(this).find(".right").html("R: " + objP.right);
$.each(stuff, function(k, v) {
if (objP.right == v.left - buffer) {
var $el = $("#" + v.id);
$el.css("left", v.left + buffer);
v.left += buffer;
$el.find(".top").html("T: " + $el.position().top);
$el.find(".left").html("L: " + $el.position().left);
}
if (objP.bottom == v.top - buffer) {
var $el = $("#" + v.id);
$el.css("top", v.top + buffer);
v.top += buffer;
$el.find(".top").html("T: " + $el.position().top);
$el.find(".left").html("L: " + $el.position().left);
}
});
}
});
});
There are lots of ways to improve upon this. You can see that it's very easy to drag pas the buffer, yet if moved slowly, you nudge the blue box around with the green box. You can also see some gapping issues, like if you slowly bring the green box over, but are not on the same Y plane, the blue box can still be moved.

Drag and Drop for Math Game

I am having a hard time figuring out how to create a drag and drop feature in my app that will accept a draggable item and decide whether it is the correct answer and if it is correct it will display a message saying success!
My app displays two images. Both images are portions of a pizza pie, and then it will display 8 draggable numbers that you have to choose from and drag them into a droppable box which will check if it's correct. So I start with:
PizzaImageOne[1]="http://s23.postimg.org/6yojml8vb/Pizza_One.png"
PizzaImageOne[2]="http://s13.postimg.org/5d8zxnb2b/pizzatwo.png"
this happens 8 times so each number of the array represents how many slices it holds.
Then I call var whichImage = Math.round(Math.random()*(p-1));. I store a random number into the variable whichImage which holds the number of pizza slices because each array number correlates with the pizza slices image which I will use to generate random pizzas by doing this:
document.write('<img src="'+theImages[whichImage]+'">');
I do that all over again with a new array
PizzaImageTwo[1]="http://s23.postimg.org/6yojml8vb/Pizza_One.png"
PizzaImageTwo[2]="http://s13.postimg.org/5d8zxnb2b/pizzatwo.png"
same exact thing but with new variables so the random call can be different than the first one
var whichImage2 = Math.round(Math.random()*(p-1))
Then I have
<script>
$(function() {
$( "#draggable1" ).draggable();
});
</script>
I do that 8 times so #draggable1, #draggable2, #draggable3,... all the way to 8.
I then made an array and saved them into each array like this 8 times each draggable function represents numbers from 1 to 8 because we are adding pizza pies like fractions.
var theimagestwo = new Array();
Draggablenumber[1] = $("#draggable1");
DraggableNumber[2] = $("#draggable2");
I do this until I fill up 8 draggable numbers in each array
So the logic is MyAnswer = WhichImage + WhichImage2. Then I have to check if DraggableNumber[MyAnswer] is dropped then I have the right answer...
How would I go about creating this feature?
Here is a way to do it, you can change the SVG to Canvas and clone in your Pizza image if you like.
Working Example: https://jsfiddle.net/Twisty/x1uzqsxe/5/
HTML
<div id="NewSlice">
<p>Take a Slice</p>
<div class="pieSlice draggable"></div>
</div>
<div id="MakePie">
<p>
Make Pie Here
</p>
<svg id="EmptyPie">
<circle r="38" cx="75" cy="75" />
</svg>
<p id="Results">Pie is 0 / 8 (0%) Complete.</p>
</div>
CSS
.pieSlice {
width: 0px;
height: 0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 75px solid red;
border-radius: 50%;
/*transform:rotate(50deg);*/
}
svg {
width: 150px;
height: 150px;
margin: 10px 37px;
background: transparent;
border: 1px solid #000;
border-radius: 50%;
position: relative;
transform: rotate(-90deg);
}
circle {
fill: white;
stroke: red;
stroke-width: 75;
stroke-dasharray: 0 239;
}
#NewSlice {
width: 100px;
margin: 10px;
padding: 3px;
border: 1px solid #222;
}
#MakePie {
width: 225px;
height: 225px;
margin: 15px;
padding: 7px;
border: 1px solid #222;
background: white;
}
#NewSlice p,
#MakePie p {
width: 100%;
padding: 0;
margin: 0;
text-align: center;
}
JQuery
var myPie = 0;
var pieTotal = 8;
var c = 239; //2*pi*r
var arc = 30; // c / number of slices (8)
$(document).ready(function() {
$("#NewSlice div.draggable").draggable({
opacity: 0.7,
helper: "clone"
});
$("#MakePie").droppable({
hoverClass: "ui-state-hover",
drop: function(e, i) {
console.log("Slice dropped on Pie.");
if (myPie < pieTotal) {
myPie++;
$("#Results").html("Pie is " + myPie + " / " + pieTotal + " (" + ((myPie / pieTotal) * 100) + "%) Complete.");
$("circle").css("stroke-dasharray", (arc * myPie) + " 239");
}
}
});
});
Drag a slice onto the pizza pie area and a 1/8 slice is drawn using the Stroke Dash method. Grow the dash as more slices are added. Again you could do similar in Canvas. Clone a slice into the circle. Clone a second, rotate it etc.

My div won't change width with my javascript function

I have made a makeshift progress bar with two divs, styled with css to fit one in another to make the progress bar. I have a button that changes the width of the inside div to go up when I click the button, but the button click does not change the width of the div. I made sure I made no errors, the javascript console in my chrome browser gives no errors when I click the button. Anyways, here is my code:
function clickMe() {
var newExp = parseInt(document.getElementById("expHold").innerHTML);
document.getElementById("bar2").style.width = newExp + 'px';
document.getElementById("expHold").innerHTML += '+1';
document.getElementById("expHold").innerHTML = eval(document.getElementById("expHold").innerHTML);
}
#bar1 {
border: 2px solid gold;
height: 15px;
width: 100px;
background-color: blue;
border-radius: 8px;
}
#bar2 {
height: 15px;
width: 1px;
background-color: skyblue;
border-radius: 8px;
}
<div id="bar1">
<div id="bar2">
</div>
</div>
<p>
<input type="button" value="Click me" onClick="clickMe()" />
<span id="expHold" style="color:black;">1</span>
I would appreciate any help telling me what I am doing wrong, thanks!
Please do not use inline JavaScript. It reduces readability and maintainability.
You should use a JavaScript variable to store the exp, this way you don't have to repeatedly query the DOM, which is process intensive.
You should cache the DOM objects instead of creating new ones on each iteration.
You can increment the previously created exp variable by using the prefix increment modifier
The prefix increment modifier will return the incremented value.
The postfix increment modifier will return the value before incrementing.
var exp = 0, current;
var bar1 = document.getElementById("bar1");
var bar2 = document.getElementById("bar2");
var hold = document.getElementById("expHold");
var max = bar1.clientWidth;
document.getElementById('my-button').onclick = function() {
// Don't go past the end.
if(bar2.clientWidth < max) {
current = ++exp;
hold.textContent = current;
bar2.style.width = current + 'px';
}
}
#bar1 {
border: 2px solid gold;
height: 15px;
width: 100px;
background-color: blue;
border-radius: 8px;
}
#bar2 {
height: 15px;
width: 0px;
background-color: skyblue;
border-radius: 8px;
}
<div id="bar1">
<div id="bar2">
</div>
</div>
<p>
<input type="button" value="Click me" id="my-button" />
<span id="expHold" style="color:black;">0</span>

Categories

Resources