Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 2 of 2
  1. #1
    New to the CF scene
    Join Date
    Jan 2014
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Question Did a JavaScript build-a-calculator tutorial and JavaScript doesn't work. Why?

    I did a really cool tutorial here: http://thecodeplayer.com/walkthrough...ss3-calculator and designed my own calculator. The problem is the JavaScript doesn't work! It works on the tutorial but not with mine script. I've tried it with and without JQuery, and I am at a loss why it doesn't work.

    Here's the HTML/CSS:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    
    <script src=”https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js” type="text/javascript"></script>
    
    <script src="jan07_januaryjs.js" type="text/javascript"></script>
    <style type="text/css">
    
    * {
    	margin: 0;
    	padding: 0;
    	box-sizing:border-box;
    	
    	font:bold 14px Arial,sans-serif
    }
    /* BG gradient */
    html {
    	height:100%;
    	background:radial-gradient(circle,#fff 20%, #ccc);
    	background-size:cover;
    	
    
    }
    
    
    #calculator {
    	width:325px;
    	height:auto;
    
    	margin:100px auto;
    	padding:20px 20px 9px;
    
    	background:linear-gradient(#9dd2ea, #8bceec);
    	border-radius:3px;
    	box-shadow:0px 4px #009de4, 0px 10px 15px rgba(0,0,0,0.2);
    }
    
    /* Top portion */
    .top span.clear {
    	float:left;
    }
    
    .top .screen {
    	height:40px;
    	width:212px;
    	
    	float:right;
    	
    	padding:0 10px;
    	
    	background: rgba(0,0,0,0.2);
    	border-radius:3px;
    	box-shadow: inset 0px 4px rgba(0,0,0,0.2);
    	
    	/* Typography */
    	font-size:17px;
    	line-height:40px;
    	color:white;
    	text-shadow:1px 1px 2px rgba(0,0,0,0.2);
    	text-align:right;
    	letter-spacing:1px;
    }
    
    /* Clear floats */
    .keys, .top {
    	overflow: hidden;
    }
    
    .keys span, .top span.clear {
    	float:left;
    	position:relative;
    	top:0;
    
    	cursor:pointer;
    
    	width:66px;
    	height:36px;
    	
    	background:white;
    	border-radius:3px;
    	box-shadow:0px 4px rgba(0,0,0,0.2);
    	
    	margin: 0 7px 11px 0;
    	
    	color:#888;
    	line-height:36px;
    	text-align:center;
    	
    	user-select:none;
    	
    	/* Smoothing out hover and active states using css3 transitions */
    	transition: all 0.2s ease;
    }
    
    /*Remove right margin from operator keys */
    .keys span.operator {
    	margin-right:0;
    	background:#fff0f5;
    }
    
    .keys span.eval {
    	background:#f1ff92;
    	box-shadow:0px 4px #ff7c87;
    	color:white;
    }
    
    .top span.clear {
    	background: #ff9fa8;
    	box-shadow:0px 4px #ff7c87;
    	color:white;
    }
    
    .keys span:hover {
    	background:#9c89f6;
    	box-shadow:0px 4px #6b54d3;
    	color:white;
    }
    
    .keys span.eval:hover {
    	background:#abb850;
    	box-shadow:0px 4px #717a33;
    	color:#ffffff;
    }
    .top span.clear:hover {
    	background:#f68991;
    	box-shadow:0px 4px #d3545d;
    	color:white;
    }
    
    .keys span:active {
    	box-shadow:0px 0px #6b54d3;
    	top:4px;
    }
    
    .keys span.eval:active {
    	box-shadow:0px 0px #717a33;
    	top:4px;
    }
    
    .top span.clear:active {
    	box-shadow:0px 0px #d3545d;
    	top:4px;
    }
    
    
    
    
    </style>
    <script>
    
    
    
    </script>
    
    
    </head>
    <body>
    <div id = "calculator">
    	<div class="top">
    		<span class="clear">C</span>
    		<div class="screen">21254.23</div>
    	</div>
    	<div class = "keys">
    		<span>7</span>
    		<span>8</span>
    		<span>9</span>
    		<span class="operator">+</span>
    		<span>4</span>
    		<span>5</span>
    		<span>6</span>
    		<span class="operator">-</span>
    		<span>1</span>
    		<span>2</span>
    		<span>3</span>
    		<span class="operator">&divide</span>
    		<span>0</span>
    		<span>.</span>
    		<span class="eval">=</span>
    		<span class="operator">X</span>
    	</div>
    </body>
    </html>

    Here's the JavaScript:
    Code:
    $(document).ready(function(){
    
    var keys = document.querySelectorAll('#calculator span');
    var operators = ['+', '-', 'x', '÷'];
    var decimalAdded = false;
    
    // Add onclick event to all the keys and perform operations
    for(var i = 0; i < keys.length; i++) {
    	keys[i].onclick = function(e) {
    		// Get the input and button values
    		var input = document.querySelector('.screen');
    		var inputVal = input.innerHTML;
    		var btnVal = this.innerHTML;
    		
    		// Now, just append the key values (btnValue) to the input string and finally use javascript's eval function to get the result
    		// If clear key is pressed, erase everything
    		if(btnVal == 'C') {
    			input.innerHTML = '';
    			decimalAdded = false;
    		}
    		
    		// If eval key is pressed, calculate and display the result
    		else if(btnVal == '=') {
    			var equation = inputVal;
    			var lastChar = equation[equation.length - 1];
    			
    			// Replace all instances of x and ÷ with * and / respectively. This can be done easily using regex and the 'g' tag which will replace all instances of the matched character/substring
    			equation = equation.replace(/x/g, '*').replace(/÷/g, '/');
    			
    			// Final thing left to do is checking the last character of the equation. If it's an operator or a decimal, remove it
    			if(operators.indexOf(lastChar) > -1 || lastChar == '.')
    				equation = equation.replace(/.$/, '');
    			
    			if(equation)
    				input.innerHTML = eval(equation);
    				
    			decimalAdded = false;
    		}
    		
    		// Basic functionality of the calculator is complete. But there are some problems like 
    		// 1. No two operators should be added consecutively.
    		// 2. The equation shouldn't start from an operator except minus
    		// 3. not more than 1 decimal should be there in a number
    		
    		// We'll fix these issues using some simple checks
    		
    		// indexOf works only in IE9+
    		else if(operators.indexOf(btnVal) > -1) {
    			// Operator is clicked
    			// Get the last character from the equation
    			var lastChar = inputVal[inputVal.length - 1];
    			
    			// Only add operator if input is not empty and there is no operator at the last
    			if(inputVal != '' && operators.indexOf(lastChar) == -1) 
    				input.innerHTML += btnVal;
    			
    			// Allow minus if the string is empty
    			else if(inputVal == '' && btnVal == '-') 
    				input.innerHTML += btnVal;
    			
    			// Replace the last operator (if exists) with the newly pressed operator
    			if(operators.indexOf(lastChar) > -1 && inputVal.length > 1) {
    				// Here, '.' matches any character while $ denotes the end of string, so anything (will be an operator in this case) at the end of string will get replaced by new operator
    				input.innerHTML = inputVal.replace(/.$/, btnVal);
    			}
    			
    			decimalAdded =false;
    		}
    		
    		// Now only the decimal problem is left. We can solve it easily using a flag 'decimalAdded' which we'll set once the decimal is added and prevent more decimals to be added once it's set. It will be reset when an operator, eval or clear key is pressed.
    		else if(btnVal == '.') {
    			if(!decimalAdded) {
    				input.innerHTML += btnVal;
    				decimalAdded = true;
    			}
    		}
    		
    		// if any other key is pressed, just append it
    		else {
    			input.innerHTML += btnVal;
    		}
    		
    		// prevent page jumps
    		e.preventDefault();
    	} 
    }
    });

  • #2
    New Coder
    Join Date
    Jun 2008
    Posts
    81
    Thanks
    2
    Thanked 16 Times in 16 Posts
    There are some issues associated with this part of the markup ...

    Code:
    		<span class="operator">&divide</span>
    		<span>0</span>
    		<span>.</span>
    		<span class="eval">=</span>
    		<span class="operator">X</span>
    	</div>
    </body>
    Firstly, there is a missing </div> just before the closing body tag.

    Secondly, the multiplication operator is using a capital 'X' as content in that span, but it needs to be a lowercase 'x'. The Reg Exp used on it is case-sensitive, and is expecting to find a lowercase 'x' there so it can replace it with a '*' in the final arithmetic expression.

    Thirdly, there is a similar problem with the divisor span. It has '&divide' as the content, but the Reg Exp is expecting to find a single character there, namely '÷', which it can replace with a '/'. If in doubt, refer back to the original tutorial page, which shows it all correctly.

    One other thing that stands out is that you are currently using jQuery for the sole purpose of a ready-onload wrapper. It's not causing an error, it's just unnecessary. You can delete the jQuery (the very first and last lines of the script), and then relocate the rest of the script out of the head, to just before the closing body tag.


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •