HTML, CSS, javascript calculator - javascript

Im having problems with my calculator. The buttons work and all align right but I can't get anything to show up on the monitor box or calculate anything. I listed my code below can anyone help me find where I went wrong? I feel it has to do with the true or false but I can't figure it out.
Here is the HTML code:
<body>
<table>
<tr>
<input id="display" type="text" value="0"/><span id="currOp"></span>
<tr>
<td>
<button id="7" class="num">7</button>
</td>
<td>
<button id="8" class="num">8</button>
</td>
<td>
<button id="9" class="num">9</button>
</td>
<td>
<button id="plus" class="operator">+</button>
</td>
<td>
<button id="clear">C</button>
</td>
</tr>
<tr>
<td>
<button id="4" class="num">4</button>
</td>
<td>
<button id="5" class="num">5</button>
</td>
<td>
<button id="6" class="num">6</button>
</td>
<td>
<button id="minus" class="operator">-</button>
</td>
<td>
<button id="root">√</button>
</td>
</tr>
<tr>
<td>
<button id="1" class="num">1</button>
</td>
<td>
<button id="2" class="num">2</button>
</td>
<td>
<button id="3" class="num">3</button>
</td>
<td>
<button id="mult" class="operator">x</button>
</td>
<td>
<button id="power" class="operator">x^y</button>
</td>
</tr>
<tr>
<td>
<button id="0" class="num">0</button>
</td>
<td>
<button id="decimal">.</button>
</td>
<td>
<button id="invert">±</button>
</td>
<td>
<button id="divid" class="operator">÷</button>
</td>
<td>
<button id="equals">=</button>
</td>
</tr>
Here is the CSS code:
button {
height: 40px;
width: 40px;
font-size: 110%;
}
#display{
font-size: 120%;
text-align: right;
}
span {
font-size: 150%;
}
and here is the javascript code:
var isOperating = true;
var isfloating = false;
var toBeCleared = true;
var operator;
var operand;
var display;
$(document).ready(init);
function init() {
display = $('#display');
$('.num').on('click', numClicked);
$('.operator').on('click', operatorClicked);
$('#invert').on('click', invertClicked);
$('#root').on('click', rootClicked);
$('#decimal').on('click', decimalClicked);
$('#equals').on('click', equalsClicked);
$('#clear').on('click', clearClicked);
}
function numClicked() {
var currVal = display.val();
var clickedNum = $(this).text();
if (currVal === "0" || toBeCleared) {
toBeCleared = true;
display.val(clickedNum);
} else {
display.val(currVal + clickedNum);
}
}
function invertClicked() {
display.val(display.val() * -1);
}
function rootClicked() {
display.val(Math.sqrt(evaluate()));
}
function decimalClicked() {
if (toBeCleared) {
display.val('0.');
toBeCleared = true;
} else {
if (!isFloating) {
display.val(display.val().concat('.'));
}
}
isFloating = false;
}
function equalsClicked() {
display.val(evaluate());
reset();
}
function clearClicked() {
reset();
display.val('0');
}
function reset() {
toBeCleared = true;
isOperating = true;
isFloating = false;
operator = null;
operand = null;
$('#currOp').text('');
}
function operatorClicked() {
if (isOperating) {
display.val(evaluate());
}
switch ($(this).attr('id')) {
case 'plus': operator = '+'; break;
case 'minus': operator = '-'; break;
case 'mult': operator = 'x'; break;
case 'divide': operator = '÷'; break;
case 'power': operator = '^'; break;
}
operand = parseFloat(display.val());
isOperating = true;
toBeCleared = true;
$('#currOp').text(operator);
}
function evaluate() {
`enter code here` var currVal = parseFloat(display.val());
var result;
switch (operator) {
case '+': result = operand + currVal; break;
case '-': result = operand - currVal; break;
case 'x': result = operand * currVal; break;
case '÷':
if (currVal === 0) {
result = 'Err';
} else {
result = operand / currVal;
}
break;
case '^': result = Math.pow(operand, currVal); break;
default: result = currVal;
}
return result;
}

You should set toBeCleared = false;
if (currVal === "0" || toBeCleared) {
toBeCleared = false;
display.val(clickedNum);
} else {
display.val(currVal + clickedNum);
}

Related

How to Sort the table column both ascending and descending using JQuery?

In the code below I can sort the table only in ascending order. When I click the table header a second time it does not switch the order to descending order.
Can anyone help me how sort the table column in both directions? Is there any alternative way available to sort the textbox value that is inside the table data?
$("#sortcol").click(function() {
const table = document.getElementById('tab_logic');
const headers = table.querySelectorAll('th');
const tableBody = table.querySelector('tbody');
const rows = tableBody.querySelectorAll('tr');
const directions = Array.from(headers).map(function(header) {
return '';
});
const transform = function(index, content) {
const type = headers[index].getAttribute('data-type');
switch (type) {
case 'number':
return parseFloat(content);
case 'string':
default:
return content;
}
};
const sortColumn = function(index) {
const direction = directions[index] || 'asc';
const multiplier = direction === 'asc' ? 1 : -1;
const newRows = Array.from(rows);
newRows.sort(function(rowA, rowB) {
const cellA = rowA.getElementsByTagName("td")[index];
const cellB = rowB.getElementsByTagName("td")[index];
const cellC = $(cellA).find('input').val();
const cellD = $(cellB).find('input').val();
const a = transform(index, cellC);
const b = transform(index, cellD);
switch (true) {
case a > b:
return 1 * multiplier;
case a < b:
return -1 * multiplier;
case a === b:
return 0;
}
});
[].forEach.call(rows, function(row) {
tableBody.removeChild(row);
});
directions[index] = direction === 'asc' ? 'desc' : 'asc';
newRows.forEach(function(newRow) {
tableBody.appendChild(newRow);
});
};
sortColumn(1);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tab_logic" style="width: 40%; border: 1px solid black;">
<thead>
<tr>
<th data-type="number">check</th>
<th id="sortcol">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" MySQL">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Python">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Javascript">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Angular JS">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Csharp">
</td>
</tr>
</tbody>
</table>
your code is perfectly fine only problem is when you are clicking on it direction variable is resetting and 'asc' value is not persisting into an array. please check the below code.
var rows;
var directions;
var headers;
var tableBody;
$(document).ready(function(){
const table = document.getElementById('tab_logic');
headers = table.querySelectorAll('th');
tableBody = table.querySelector('tbody');
rows = tableBody.querySelectorAll('tr');
directions = Array.from(headers).map(function(header) {
return '';
});
})
const transform = function(index, content) {
const type = headers[index].getAttribute('data-type');
switch (type) {
case 'number':
return parseFloat(content);
case 'string':
default:
return content;
}
};
const sortColumn = function(index) {
const direction = directions[index] || 'asc';
const multiplier = direction === 'asc' ? 1 : -1;
const newRows = Array.from(rows);
newRows.sort(function(rowA, rowB) {
const cellA = rowA.getElementsByTagName("td")[index];
const cellB = rowB.getElementsByTagName("td")[index];
const cellC = $(cellA).find('input').val();
const cellD = $(cellB).find('input').val();
const a = transform(index, cellC);
const b = transform(index, cellD);
switch (true) {
case a > b:
return 1 * multiplier;
case a < b:
return -1 * multiplier;
case a === b:
return 0;
}
});
[].forEach.call(rows, function(row) {
tableBody.removeChild(row);
});
newRows.forEach(function(newRow) {
tableBody.appendChild(newRow);
});
directions[index] = direction === 'asc' ? 'desc' : 'asc';
};
$("#sortcol").click(function() {
sortColumn(1);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tab_logic" style="width: 40%; border: 1px solid black;">
<thead>
<tr>
<th data-type="number">check</th>
<th id="sortcol">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" MySQL">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Python">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Javascript">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Angular JS">
</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>
<input type="text" Value=" Csharp">
</td>
</tr>
</tbody>
</table>

How to fix issue with .select() not working

I'm trying to modify a JS script to fix a problem for searching for a keyword, and I'm not sure what the issue is. The script works only in Internet Explorer, which is a minor issue.
Here is a JS Fiddle: https://jsfiddle.net/ettt14k7/5/
The purpose of this script is to find a keyword in a datagrid made with <telerik:RadGrid />. When the desired keyword is entered into the search field, the current instance, if any is present, is highlighted using .select().
I'm hoping someone could help me modify the script so that the current instance is wrapped with <span class="searchhighlighted"> ... </span> so that I can then control the highlighting with CSS, as well as also fixing the issue for why it only works in IE. I've already tried applying the following:
instances[currHighlighted].html = '<span class="searchhighlighted">' + instances[currHighlighted].text + '</span>';
But the above does nothing. If I change the above .html to use .text as in the following:
instances[currHighlighted].text = '<span class="searchhighlighted">' + instances[currHighlighted].text + '</span>';
It works. But .text outputs as a string and doesn't render html tags as tags.
Any help is greatly appreciated. Thanks
HTML:
<div class="formholder searchkeywordholder">
<div class="form_inner">
<div class="formrow form-col-1" tabindex="0">
<div id="find-in-page">
<div class="fielditem searchfielditem">
<input type="text"
id="search-term"
placeholder="Type in the phrase to search and click Next..."
title="Enter Search Phrase"
class="text searchfield"
aria-label="Search Keyword Field" />
<button id="next"
class="button bttn-clear btn-searchnext"
title="Next"
aria-label="Search Next Button">
Next
</button>
<button id="prev"
class="button bttn-find btn-searchprev"
title="Previous"
aria-label="Search Previous Button">
Previous
</button>
</div>
<label id="labelResult" class="searchInstance"></label>
</div>
</div>
</div>
</div>
<div class="RadGrid RadGrid_Default mydatagrid staticheaders nostripes" id="ctl00_MainContent_customProjectAssets_gridItems" tabindex="0">
<div class="rgDataDiv" id="ctl00_MainContent_customProjectAssets_gridItems_GridData">
<table class="rgMasterTable rgClipCells rgClipCells" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00">
<tbody>
<tr class="groupinghighlight" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00__0">
<td valign="middle">
<div>
</div>
</td>
<td>
<div>
<div>
<div id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl04_divChildAssetStyle">
Antenna B1
</div>
</div>
</div>
</td>
<td>
Equipment and Materials
</td>
<td>
C2 Equipment
</td>
<td>
Antenna
</td>
<td>
Basic
</td>
<td>
B1
</td>
<td>
<div class="rating_general rating_yellow" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl04_divRating" title="Asset's Rate">
0.36
</div>
</td>
<td align="center">
<span class="aspNetDisabled"><input disabled="disabled" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl04_checkboxOverride" name="ctl00$MainContent$customProjectAssets$gridItems$ctl00$ctl04$checkboxOverride" type="checkbox"></span>
</td>
<td>
<span id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl04_spanAssetTag" title="Incident Response/Recovery">IRR</span>
</td>
<td align="center">
<span id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl04_spanClassificationLevel" title="UNCLASSIFIED">U</span>
</td>
<td align="center">
<input id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl04_checkboxDelete" name="ctl00$MainContent$customProjectAssets$gridItems$ctl00$ctl04$checkboxDelete" onclick="$.onCheckDeleteChange('0');" type="checkbox">
</td>
</tr>
<tr class="groupinghighlight" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00__1">
<td valign="middle">
<div>
</div>
</td>
<td>
<div>
<div style="width: 200px; margin: 0 auto;">
<div id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl05_divChildAssetStyle">
Content 1
</div>
</div>
</div>
</td>
<td>
This is content
</td>
<td>
My text
</td>
<td>
lorem ipsum dolor
</td>
<td>
sit amet
</td>
<td></td>
<td>
<div class="rating_general rating_orange" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl05_divRating" title="Asset's Rate">
0.56
</div>
</td>
<td align="center">
<span class="aspNetDisabled"><input disabled="disabled" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl05_checkboxOverride" name="ctl00$MainContent$customProjectAssets$gridItems$ctl00$ctl05$checkboxOverride" type="checkbox"></span>
</td>
<td>
<span id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl05_spanAssetTag" title="No Asset Tag Assigned"></span>
</td>
<td align="center">
<span id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl05_spanClassificationLevel" title="UNCLASSIFIED">U</span>
</td>
<td align="center">
<input id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl05_checkboxDelete" name="ctl00$MainContent$customProjectAssets$gridItems$ctl00$ctl05$checkboxDelete" onclick="$.onCheckDeleteChange('1');" type="checkbox">
</td>
</tr>
<tr class="rgRow" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00__2">
<td valign="middle">
<div>
</div>
</td>
<td>
<div>
<div style="width: 200px; margin: 0 auto;">
<div class="iconGridSubordinateArrow" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl06_divChildArrowImage" style="float: left; width: 17px;"></div>
<div id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl06_divChildAssetStyle" style="float: left; width: 180px;">
equivalent
</div>
</div>
</div>
</td>
<td>
People
</td>
<td>
Individuals
</td>
<td>
lorem
</td>
<td>
ipsum
</td>
<td></td>
<td>
<div class="rating_general rating_yellow" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl06_divRating" title="Asset's Rate">
0.44
</div>
</td>
<td align="center">
<span class="aspNetDisabled"><input disabled="disabled" id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl06_checkboxOverride" name="ctl00$MainContent$customProjectAssets$gridItems$ctl00$ctl06$checkboxOverride" type="checkbox"></span>
</td>
<td>
<span id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl06_spanAssetTag" title="No Asset Tag Assigned"></span>
</td>
<td align="center">
<span id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl06_spanClassificationLevel" title="UNCLASSIFIED">U</span>
</td>
<td align="center">
<input id="ctl00_MainContent_customProjectAssets_gridItems_ctl00_ctl06_checkboxDelete" name="ctl00$MainContent$customProjectAssets$gridItems$ctl00$ctl06$checkboxDelete" onclick="$.onCheckDeleteChange('2');" type="checkbox">
</td>
</tr>
</tbody>
</table>
</div>
</div>
JS:
$(document).ready(function () {
$(document).on('click', '.btn-searchnext', findNextInstance);
$(document).on('click', '.btn-searchprev', findPrevInstance);
});
var currHighlighted = null;
var instances = null;
var str = null;
var pageChanged = false;
var isWhiteSpace = false;
var batchEdit = false;
//onkeydown = function (e) {
$(document).on('keydown', '#search-term', function(e) {
var search = $('#search-term');
var active = $(':focus');
if (e.which == 13) { // ENTER key
// fpsb-495: check that focus isn't on radconfirm, pager textbox, and make sure the control is visible
if (
active.hasClass("rwOkBtn") != -1 &&
active.hasClass("rwCancelBtn") &&
active.hasClass("rgPager") == -1 &&
$('#find-in-page').css('display') != 'none' &&
!batchEdit
) {
if (str != search.val()) {
findStrings();
}
findNextInstance();
}
}
});
//}
// returns true if txtRng is within a DIV tag with a classname "divClass"
function isInDivClass(elt, divClass) {
elt = elt.parentElement();
while (elt != null) {
// the button text shouldn't be picked up by the search control
if (elt.className == "rgButtonText") {
return false;
}
if (elt.tagName === "DIV" && elt.className.indexOf(divClass) !== -1) {
return true;
} else {
elt = elt.parentElement;
}
}
return false;
}
// finds all instances of string in textfield on page
function findStrings() {
//str = document.getElementById('search-term').value;
str = $('#search-term').val();
isWhiteSpace = str.trim() == "";
instances = new Array();
currHighlighted = null;
if (str && !isWhiteSpace) {
var strFound = true;
// used so that the next text range will only look forward on page for string
var prevTextRange = null;
while (strFound) {
// creates a text range obj
var currTextRange = self.document.body.createTextRange();
if (prevTextRange != null)
// starts current range at end point of last range, so no duplicate finds
currTextRange.setEndPoint("StartToEnd", prevTextRange);
strFound = currTextRange.findText(str);
var isInDiv = isInDivClass(currTextRange, "RadGrid RadGrid_Default mydatagrid");
if (
strFound &&
isInDiv &&
currTextRange.getClientRects().length > 0
) {
instances.push(currTextRange);
}
prevTextRange = currTextRange;
} // end while
} else { // end if
instances = null;
return;
}
if (instances.length > 0) {
// starts at -1 so it will rollover for Prev, start at 1 for Next
currHighlighted = -1;
}
return;
}
// highlights the next word in instances array for the current search term
function findNextInstance() {
// call findStrings() if page was changed
//if (pageChanged || str != document.getElementById('search-term').value) {
if (pageChanged || str != $('#search-term').val()) {
findStrings();
pageChanged = false;
}
// if nothing in text field or no instances of string on page
if (!instances || instances.length === 0 || !str) {
if (str != null || isWhiteSpace) {
if (str.length == 0 || isWhiteSpace) {
radalert("Please enter a phrase to search!", 250, 110);
$('.searchInstance').text("");
} else {
$('.searchInstance').text("No instances found on this page.");
radalert("Searched string not found on this page!", 250, 110);
}
return;
} else if (str == null) {
//alert("in find next when str i snull: " + str);
//radalert("Please enter a word to search!", 250, 110);
console.log('Field left empty. Nothing to search.');
}
$('.searchInstance').text("");
return;
}
// allows Next to "roll over" from last instance to first instance again
currHighlighted = currHighlighted + 1;
if (currHighlighted == instances.length || currHighlighted == -1) {
currHighlighted = 0;
}
instances[currHighlighted].select();
$('.searchInstance').text("Instance " + (currHighlighted + 1) + " of " + instances.length + " found on this page.");
return false;
}
// highlights the previous word in instances array for the current search term
function findPrevInstance() {
// call findStrings() if page was changed
//if (pageChanged || str != document.getElementById('search-term').value) {
if (pageChanged || str != $('#search-term').val()) {
findStrings();
pageChanged = false;
}
// if nothing in text field or no instances of string on page
if (!instances || instances.length === 0 || !str) {
if (str != null || isWhiteSpace) {
if (str.length == 0 || isWhiteSpace) {
radalert("Please enter a phrase to search!", 250, 110);
$('.searchInstance').text("");
} else {
radalert("Searched string not found on this page!", 250, 110);
$('.searchInstance').text("No instances found on this page.");
}
} else if (str == null) {
radalert("Please enter a phrase to search!", 250, 110);
}
return;
}
// allows Prev to "roll over" from first instance to last instance
if (--currHighlighted < 0)
currHighlighted = instances.length - 1;
instances[currHighlighted].select();
$('.searchInstance').text("Instance " + (currHighlighted + 1) + " of " + instances.length + " found on this page.");
return false;
}
function shouldRefresh() {
// next time Next or Prev is clicked, call findStrings again since grid state is changed
pageChanged = true;
//var searchTerm = document.getElementById('search-term').value;
var searchTerm = $('#search-term').val();
if (searchTerm != null && searchTerm !== '') {
$('.searchInstance').text("Page changed, press Next or Previous to refresh search!");
}
}
function clearSearchField() {
//document.getElementById('search-term').value = "";
$('#search-term').val("");
$('.searchInstance').text("");
instances = null;
isWhiteSpace = false;
}
function ToggleSearchDiv(status) {
// document.getElementById('find-in-page').style.display = status;
if (status == 'none') {
document.getElementsByClassName('searchkeywordholder')[0].style.display = 'none';
} else {
// We want to avoid using display: inline
document.getElementsByClassName('searchkeywordholder')[0].style.display = 'block';
}
}
function ToggleBatchEdit(status) {
batchEdit = status;
}
// END of find in page

Sample Calculator Application

I just made a simple calculator application with AngularJS.
What does this program can do:
Catch error input when I press . 2 times per series of numbers.
Only accept 10 numbers per series of numbers.
Check if not complete operate.
User only can do 1 formula per 1 series of numbers.
But there are still some bugs:
When max 10 numbers, if you press delete, the program still accepts more than 10 numbers?
Some time after calculation, the program allows to input max 12 numbers?
var mainApp = angular.module("mainApp", []);
mainApp.controller('CalCtrl', function($scope) {
$scope.output = "0";
$scope.curIndex = 0;
$scope.result = 0;
$scope.checkInput = function(num) {
var tmp = true;
if($scope.result != 0) {
$scope.result = 0;
$scope.output = "0";
tmp = true;
}
if(angular.equals('+', num) ||
angular.equals('-', num) ||
angular.equals('*', num) ||
angular.equals('/', num)) {
var index = "+|-|*|/".indexOf($scope.output.charAt($scope.output.length - 1));
if(index >= 0) {
tmp = false;
$scope.msg = "You only can do 1 formula per 1 time.";
}
$scope.curIndex = $scope.output.length + 1;
} else {
tmp = true;
if($scope.output.substring($scope.curIndex).length < 10) {
if(angular.equals(num, ".")) {
var k = 0;
for(var j = 0; j < $scope.output.substring($scope.curIndex).length; j++){
if(angular.equals(".", $scope.output.substring($scope.curIndex).charAt(j))) {
k = k + 1;
}
}
if(k >= 1){
$scope.msg = "You can't add '.' 2 times per series of numbers!";
tmp = false;
}
} else {
tmp = true;
}
} else {
$scope.msg = "You can't input more than 10 number per series of numbers!";
tmp = false;
}
}
return tmp;
}
$scope.operate = function(op) {
if($scope.checkInput(op)) {
$scope.output = $scope.output + op;
}
}
$scope.press = function(num) {
if($scope.checkInput(num)) {
if(angular.equals(num, 'x')){
$scope.output = $scope.output.slice(0 , $scope.output.length - 1);
} else {
if (angular.equals($scope.output, "0")) {
$scope.output = "";
$scope.msg = "";
$scope.output += num;
} else if (angular.equals(".", $scope.output)){
$scope.msg = "";
$scope.output = "0.";
$scope.output += num;
} else {
$scope.msg = "";
$scope.output += num;
}
}
} else {
if(angular.equals(num, 'x')){
$scope.msg = "";
$scope.output = $scope.output.slice(0 , $scope.output.length - 1);
}
}
}
$scope.equal = function() {
var isOpEnd = "+|-|*|/".indexOf($scope.output.charAt($scope.output.length - 1));
if(isOpEnd >= 0) {
$scope.msg = "You must complete the formula first!";
} else if(eval($scope.output) == 0){
$scope.output = "0";
} else {
$scope.msg = "";
$scope.result = eval($scope.output);
$scope.output = $scope.result;
}
}
});
table, th, td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
table tr:nth-child(odd) {
background-color: #f2f2f2;
}
table tr:nth-child(even) {
background-color: #ffffff;
}
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<div ng-app="mainApp" align="center">
<h2>AngularJS Calculator Application by Rain</h2>
<div ng-controller="CalCtrl">
<table width="250px" height="300px" align="center">
<tr>
<td colspan="4">
<input type="text" style="text-align:center; width: 236px; height:30px" name="output" id="res" value="{{output}}" disabled = "disabled">
</td>
</tr>
<tr>
<td colspan="4">
<button title="Number 1" style="width:56px" ng-click="press('1')">1</button>
<button title="Number 2" style="width:56px" ng-click="press('2')">2</button>
<button title="Number 3" style="width:56px" ng-click="press('3')">3</button>
<button title="Operate +" style="width:56px" ng-click='operate("+")' >+</button>
</td>
</tr>
<tr>
<td colspan="4">
<button style="width:56px" ng-click="press('4')">4</button>
<button style="width:56px" ng-click="press('5')">5</button>
<button style="width:56px" ng-click="press('6')">6</button>
<button title="Operate -" style="width:56px" ng-click='operate("-")' >-</button>
</td>
</tr>
<tr>
<td colspan="4">
<button title="Number 7" style="width:56px" ng-click="press('7')">7</button>
<button title="Number 8" style="width:56px" ng-click="press('8')">8</button>
<button title="Number 9" style="width:56px" ng-click="press('9')">9</button>
<button title="Operate *" style="width:56px" ng-click='operate("*")' >x</button>
</td>
</tr>
<tr>
<td>
<button title="Number 0" style="width:56px" ng-click="press('0')">0</button>
<button title="." style="width:56px" ng-click="press('.')">.</button>
<button title="Clear all" style="width:56px" ng-click="output = '0'">C</button>
<button title="Operate ÷" style="width:56px" ng-click='operate("/")' >÷</button>
</td>
</tr>
<tr>
<td>
<button style="width:175px" ng-click="equal()">=</button>
<button title="Delete" style="width:56px" ng-click="press('x')">⌫</button>
</td>
</tr>
</table>
<span align="center" style="color:red">{{msg}}</span>
</div>
</div>

Vanilla JavaScript calculator

So I've been working on a "very simple" calculator only using vanilla JavaScript. However I don't know why is it now working.
This is my JavaScript and HTML code:
(function() {
"use strict";
var elem = function(element) {
if (element.charAt(0) === "#") {
return document.querySelector(element);
}
return document.querySelectorAll(element);
};
// Variables
var screen = elem('.screen');
equal = elem('.equal');
nums = elem('.num');
ops = elem('.operator');
theNum = "";
oldNum = "";
resultNum;
operator;
// When: Number is clicked. Get the current number selected
var setNum = function() {
if (resultNum) {
theNum = this.getAttribute('data-num');
resultNum = "";
} else {
theNum += this.getAttribute('data-num');
}
viewer.innerHTML = theNum;
};
var moveNum = function() {
oldNum = theNum;
theNum = "";
operator = this.getAttribute('data-ops');
equal.setAttribute('data-result', '');
};
var displayNum = function() {
oldNum = parseFloat(oldNum);
theNum = parseFloat(theNum);
switch (operator) {
case "plus":
resultNum = oldNum + theNum;
break;
case "minus":
resultNum = oldNum - theNum;
break;
case "times":
resultNum = oldNum * theNum;
break;
case "divided by":
resultNum = oldNum / theNum;
break;
default:
resultNum = theNum;
}
viewer.innerHTML = resultNum;
equal.setAttribute("data-result", resultNum);
oldNum = 0;
theNum = resultNum;
};
var clearAll = function() {
oldNum = "";
theNum = "";
viewer.innerHTML = "0";
equals.setAttribute("data-result", resultNum);
};
for (var i = 0, l = nums.length; i < l; i++) {
nums[i].onclick = setNum;
}
for (var i = 0, l = ops.length; i < l; i++) {
ops[i].onclick = moveNum;
}
equals.onclick = displayNum;
elem("#clear").onclick = clearAll;
<div id="calculator">
<div class="top">
<button id="clear">C</button>
<div class="screen"></div>
</div>
<div class="btns">
<button class="num" data-num="7">7</button>
<button class="num" data-num="8">8</button>
<button class="num" data-num="9">9</button>
<button class="operator" data-ops="plus">+</button>
<button class="num" data-num="4">4</button>
<button class="num" data-num="5">5</button>
<button class="num" data-num="6">6</button>
<button class="operator" data-ops="minus">-</button>
<button class="num" data-num="1">1</button>
<button class="num" data-num="2">2</button>
<button class="num" data-num="3">3</button>
<button class="operator" data-ops="divided by">÷</button>
<button class="num" data-num="0">0</button>
<button class="num" data-num=".">.</button>
<button class="equal" data-result="">=</button>
<button class="operator" data-ops="times">x</button>
</div>
</div>
I'm not sure if what I'm doing is correct. I've been pretty much improvising but if anyone knows an easier way or correct way of making the calculator work I'd really appreciate the help.
I wrote a basic calculator for a school assignment back in 2003. Even though the code is 12+ years old, it still works in modern browsers today. Feel free to check it out any borrow any code you might find useful.
You can find the complete code below as well as in this github repository.
By the way, the behavior of my calculator is intended to work exactly like that of a real, physical, old school calculator... which means that you need to push the on/c button before you can do anything else ;-)
A screenshot :
The code :
var on = false, lastprinted = "", currentfunc ="", memory;
function testoverflow() {
var overflowflag;
if (memory >= 1000000000000) {
turn("error");
overflowflag = true;
} else
overflowflag = false;
return overflowflag;
}
function findmaxlength(location) {
var maxlength = 12;
if (location.indexOf("-", 0) != -1) maxlength++;
if (location.indexOf(".", 0) != -1) maxlength++;
return maxlength;
}
function showresult(lg, hf) {
memory = memory.toString();
memory = parseFloat(memory.substring(0,findmaxlength(memory)));
document.calculator.display.value = memory;
lastprinted = lg;
currentfunc = hf;
}
function turn(onoff) {
if (onoff == "ce") {
if (on) {
document.calculator.display.value="0";
}
} else {
switch (onoff) {
case "onc":
document.calculator.display.value="0";
on = true;
break;
case "error":
document.calculator.display.value = "ERROR";
break;
case "off":
document.calculator.display.value="";
on = false;
break;
}
currentfunc = "";
memory = null;
}
lastprinted = "";
}
function number(input) {
if (on) {
if ((document.calculator.display.value.length < findmaxlength(document.calculator.display.value)) || (lastprinted != "number")) {
if (!((document.calculator.display.value == "0") && ((input == "00") || (input == "0")))) {
if ((lastprinted == "number")&&(document.calculator.display.value != "0")) {
document.calculator.display.value += input;
lastprinted = "number";
} else if (input != "00") {
document.calculator.display.value = input;
lastprinted = "number";
}
}
}
}
}
function func(symbool) {
if ((on) && (document.calculator.display.value != "ERROR")) {
if (memory == null) {
memory = parseFloat(document.calculator.display.value);
lastprinted = "func";
currentfunc = symbool;
} else if ((document.calculator.display.value == "0") && (currentfunc == "/")) {
turn("error");
} else {
eval("memory = " + memory + currentfunc + "(" + document.calculator.display.value +");");
if (! testoverflow()) showresult("func", symbool);
}
}
}
function result(name) {
var value;
if ((on) && (document.calculator.display.value != "ERROR")) {
if (memory != null) {
value = document.calculator.display.value;
if (name == "procent") value = memory * parseFloat(document.calculator.display.value)/ 100;
eval("memory = " + memory + currentfunc + "(" + value +");");
if (! testoverflow()) {
showresult("name", "");
memory = null;
}
}
}
}
function dot() {
var maxlength = 12;
if ((on) && (document.calculator.display.value != "ERROR")) {
if (document.calculator.display.value.indexOf("-", 0) != -1) maxlength++;
if (((lastprinted == "number") || (document.calculator.display.value="0")) && !(document.calculator.display.value.length >= maxlength) && (document.calculator.display.value.indexOf(".", 0) == -1)) {
document.calculator.display.value += ".";
lastprinted = "number";
}
}
}
function negative() {
if ((on) && (lastprinted == "number") && (document.calculator.display.value != "ERROR")) {
if (document.calculator.display.value.indexOf("-", 0) == -1) document.calculator.display.value = "-" + document.calculator.display.value;
else document.calculator.display.value = document.calculator.display.value.substring(1,14);
}
}
body {background-color: #CCCCCC; color: #555555; font-family: Arial; font-weight: bold; font-size: 8pt;}
a {color: #CC5555; text-decoration: none}
a:visited {color: #CC5555; text-decoration: none}
a:active {color: #FF0000; text-decoration: none}
a:hover {color: #FF0000; text-decoration: none}
.button {height: 30px; width: 40px; background-color: #555555; border-color: #555555; color:#FFFFFF;}
.invisbutton {height: 28px; width: 40px; background-color: #7555C6; border-color: #7555C6; border-style:solid;}
.display {height: 50px; width: 217px; background-color: #D6D39F; border-color: #000000; color:#222222; border-style: solid; text-align: right; font-size: 22pt;}
.redbutton {height: 30px; width: 40px; background-color: #EE0000; border-color: #EE0000; color:#FFFFFF;}
.yellowbutton {height: 30px; width: 40px; background-color: #EEEE00; border-color: #EEEE00; color:#000000;}
.device {height: 30px; width: 40px; background-color: #7555C6; border-color: #7555C6; border-style:ridge;}
<table class="device" cellspacing="20" cellpadding="0">
<tr>
<td align="center">
<form name="calculator">
<table>
<tr>
<td colspan="5"><input type="text" name="display" class="display" readonly='readonly'></td>
</tr>
<tr>
<td colspan="5"><input type="text" class="invisbutton" style="height:15px;" readonly='readonly'></td>
</tr>
<tr>
<td><input type="text" name="hidden" class="invisbutton" readonly='readonly'></td>
<td><input type="text" name="hidden2" class="invisbutton" readonly='readonly'></td>
<td><input type="button" name="off" class="redbutton" value="off" onclick="turn(this.name);"></td>
<td><input type="button" name="ce" class="yellowbutton" value="ce" onclick="turn(this.name);"></td>
<td><input type="button" name="onc" class="yellowbutton" value="on/c" onclick="turn(this.name);"></td>
</tr>
<tr>
<td><input type="button" name="number7" class="button" value="7" onclick="number(this.value);"></td>
<td><input type="button" name="number8" class="button" value="8" onclick="number(this.value);"></td>
<td><input type="button" name="number9" class="button" value="9" onclick="number(this.value);"></td>
<td><input type="button" name="procent" class="button" value="%" onclick="result(this.name);"></td>
<td><input type="button" name="plusmin" class="button" value="+/-" onclick="negative();"></td>
</tr>
<tr>
<td><input type="button" name="number4" class="button" value="4" onclick="number(this.value);"></td>
<td><input type="button" name="number5" class="button" value="5" onclick="number(this.value);"></td>
<td><input type="button" name="number6" class="button" value="6" onclick="number(this.value);"></td>
<td><input type="button" name="func-" class="button" value="-" onclick="func(this.name.substring(4, 5));"></td>
<td><input type="button" name="func/" class="button" value="/" onclick="func(this.name.substring(4, 5));"></td>
</tr>
<tr>
<td><input type="button" name="number1" class="button" value="1" onclick="number(this.value);"></td>
<td><input type="button" name="number2" class="button" value="2" onclick="number(this.value);"></td>
<td><input type="button" name="number3" class="button" value="3" onclick="number(this.value);"></td>
<td rowspan="2"><input type="button" name="func+" class="button" value="+" style="height: 64px" onclick="func(this.name.substring(4, 5));"></td>
<td><input type="button" name="func*" class="button" value="x" onclick="func(this.name.substring(4, 5));"></td>
</tr>
<tr>
<td><input type="button" name="number0" class="button" value="0" onclick="number(this.value);"></td>
<td><input type="button" name="number00" class="button" value="00" onclick="number(this.value);"></td>
<td><input type="button" name="dot" class="button" value="." onclick="dot();"></td>
<td><input type="button" name="equals" class="button" value="=" onclick="result(this.name);"></td>
</tr>
</table>
</form>
</td>
</tr>
</table>
Are you closing your IIFE at the end of your code? If not, add
})();
to the end of your file.
separate
// Variables
var screen = elem('.screen');
equal = elem('.equal');
nums = elem('.num');
ops = elem('.operator');
theNum = "";
oldNum = "";
resultNum;
operator;
by commas, not semicolons.
Also, viewer is not defined.
There might be other things, but that should be a start
remove the function itself
add var before declaring variables: equal to viewer
use: var equal = elem('.equal')[0]; because you will get an array of DOM objects by className, you need the first one
use: var viewer = elem('.screen')[0]; because you will get an array of DOM objects by className, you need the first one
declare var viewer = elem('.screen');
Two words in the code 'equals' should be 'equal', remove the 's' in the end of the word
And the working code is:
"use strict";
var elem = function(element) {
if (element.charAt(0) === "#") {
return document.querySelector(element);
}
return document.querySelectorAll(element);
};
// Variables
var screen = elem('.screen');
var equal = elem('.equal')[0];
var nums = elem('.num');
var ops = elem('.operator');
var theNum = "";
var oldNum = "";
var resultNum;
var operator;
var viewer = elem('.screen')[0];
// When: Number is clicked. Get the current number selected
var setNum = function() {
if (resultNum) {
theNum = this.getAttribute('data-num');
resultNum = "";
} else {
theNum += this.getAttribute('data-num');
}
viewer.innerHTML = theNum;
};
var moveNum = function() {
oldNum = theNum;
theNum = "";
operator = this.getAttribute('data-ops');
equal.setAttribute('data-result', '');
};
var displayNum = function() {
oldNum = parseFloat(oldNum);
theNum = parseFloat(theNum);
switch (operator) {
case "plus":{
resultNum = oldNum + theNum;
break;
}
case "minus":
resultNum = oldNum - theNum;
break;
case "times":
resultNum = oldNum * theNum;
break;
case "divided by":
resultNum = oldNum / theNum;
break;
default:
resultNum = theNum;
}
viewer.innerHTML = resultNum;
equal.setAttribute("data-result", resultNum);
oldNum = 0;
theNum = resultNum;
};
var clearAll = function() {
oldNum = "";
theNum = "";
viewer.innerHTML = "0";
equal.setAttribute("data-result", resultNum);
};
for (var i = 0, l = nums.length; i < l; i++) {
nums[i].onclick = setNum;
}
for (var i = 0, l = ops.length; i < l; i++) {
ops[i].onclick = moveNum;
}
equal.onclick = displayNum;
elem("#clear").onclick = clearAll;

React doesn't chang state immediately [duplicate]

This question already has answers here:
Why does calling react setState method not mutate the state immediately?
(9 answers)
Closed 7 years ago.
Good day. I have the following problem: I have a class calculator and it changes state of firstOperand parameter on button click. But state doesn't change immediately, it changes the state of firstOperand only when I clicked one more button. Result is delay in 1 operation: I clicked 1 - indicator doesn't changed, I clicked 2 - indicator changed to 1, I clicked 5 - indicator changed to 12, etc.
Here is part of my code:
var Indicator = React.createClass({
render: function () {
return (
<div className="calc-indicator">
<input id="indicator" type="text" maxLength="20" size="20" value={this.props.value}/>
</div>
);
}
});
var Button = React.createClass({
render: function () {
return (
<div className="nav-button">
<button type="button" id={this.props.identifier} onClick={this.props.clickHandler}>
{this.props.digit}
</button>
</div>
);
}
});
var Calculator = React.createClass({
setFirstOperand: function (value) {
this.setState(
{
firstOperand: value
}
);
if (isDebug) {
console.log("First operand state is set to " + value + ".");
}
},
setSecondOperand: function (value) {
this.setState(
{
secondOperand: value
}
);
},
changeIndicator: function (value) {
if (isDebug) {
console.log("///Change indicator method is working///");
console.log("change indicator parameter is " + value);
console.log("first operand is " + this.state.firstOperand);
console.log("second operand is " + this.state.secondOperand);
console.log("operation is " + this.state.operation);
}
if (!value) { // if value hasn't been gotten
value = '';
if (this.state.firstOperand) {
value += this.state.firstOperand;
} else {
value = '0';
}
if (this.state.operation) {
value += this.state.operation;
}
if (this.state.secondOperand) {
value += this.state.secondOperand;
}
}
this.setState(
{
value: value
}
);
if (isDebug) {
console.log("indicator is changed to " + value);
console.log("/////////////////////////////////////");
}
},
getInitialState: function () {
calculator = this;
return {
firstOperand: null,
secondOperand: null,
operation: null,
divisionByZero: false,
value: '0'
};
},
cipherClicked: function (event) {
if (this.state.divisionByZero) {
this.setDivisionByZero(false);
}
var newValue = event.target.innerHTML;
var firstValue = this.state.firstOperand;
var secondValue = this.state.secondOperand;
var operation = this.state.operation;
if (operation) {
if (secondValue) {
secondValue = secondValue + newValue;
} else {
secondValue = newValue;
}
if (isDebug) {
console.log("Second operand state is setting to " + secondValue + ".");
}
this.setSecondOperand(secondValue);
} else {
if (firstValue) {
firstValue = firstValue + newValue;
} else {
if (newValue != 0) { // if indicator contains 0 and you have tried to add one 0 more
firstValue = newValue;
}
}
if (isDebug) {
console.log("First operand state is setting to " + firstValue + ".");
}
this.setFirstOperand(firstValue);
setOperand(firstValue);
}
if (isDebug) {
console.log("Calling changeIndicator function.");
}
this.changeIndicator();
},
render: function () {
return (
<div id="calculator">
<table>
<tr>
<td colSpan="4">
<Indicator value={this.state.value} />
</td>
</tr>
<tr>
<td>
<Button identifier="MC" digit="MC" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="MR" digit="MR" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="M+" digit="M+" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="M" digit="M" clickHandler={this.memoryNavigationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="BS" digit="BS" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="CL" digit="CL" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="C" digit="C" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="negate" digit="+-" clickHandler={this.negateClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="7" digit="7" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="8" digit="8" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="9" digit="9" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="divide" digit="/" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="4" digit="4" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="5" digit="5" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="6" digit="6" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="multiply" digit="*" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="1" digit="1" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="2" digit="2" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="3" digit="3" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="minus" digit="-" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="0" digit="0" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="dot" digit="." clickHandler={this.dotClicked}/>
</td>
<td>
<Button identifier="eq" digit="=" clickHandler={this.operationClicked}/>
</td>
<td>
<Button identifier="plus" digit="+" clickHandler={this.operationClicked}/>
</td>
</tr>
</table>
</div>
);
}
});
React.render(<Calculator />, document.body);
</script>
</body>
</html>
As per my React Native answer here, setState can be an asynchronous operation, not synchronous. This means that updates to state could be batched together and not done immediately in order to get a performance boost. If you really need to do something after state has been truly updated, there's a callback parameter:
this.setState({ searchString: event.nativeEvent.text }, function(newState) {
console.log('Changed State');
console.log('searchString = ' + this.state.searchString);
}.bind(this));
It’s also mentioned in the React Documentation.

Categories

Resources