Strip spaces before performing Luhn check - javascript

I have a function that performs a Luhn check on a card entry when a form is posted.
<script language="javascript">
function Calculate(Luhn)
{
var sum = 0;
for (i=0; i<Luhn.length; i++ )
{
sum += parseInt(Luhn.substring(i,i+1));
}
var delta = new Array (0,1,2,3,4,-4,-3,-2,-1,0);
for (i=Luhn.length-1; i>=0; i-=2 )
{
var deltaIndex = parseInt(Luhn.substring(i,i+1));
var deltaValue = delta[deltaIndex];
sum += deltaValue;
}
var mod10 = sum % 10;
mod10 = 10 - mod10;
if (mod10==10)
{
mod10=0;
}
return mod10;
}
function Validate(Luhn)
{
var LuhnDigit = parseInt(Luhn.substring(Luhn.length-1,Luhn.length));
var LuhnLess = Luhn.substring(0,Luhn.length-1);
if (Calculate(LuhnLess)==parseInt(LuhnDigit))
{
return true;
}
alert("\n\nYou have mis-typed your card number! \nPlease check and correct.\n\n")
return false;
}
I also have a function that removes any spaces that may have been entered in the card number onblur.
function stripChar(sValue, sChar) {
var i, tempChar, buildString;
buildString = ""
for (var i=0; i<sValue.length; i++) {
tempChar = sValue.charAt(i);
if (tempChar != sChar) {
buildString = buildString + tempChar;
}
}
return buildString;
How do I combine the functions so that the spaces are removed and the card number checked onblur.

In your onblur function you could use:
Validate(stripChar(sValue, sChar));

Related

JavaScript infinity loop in calculator

I'm developing a small calculator that allows you to input a string. So it has to recognize which sign has to be executed in first place.
My problem is that somewhere and by some reason it creates a stackoverflow. I was expecting if you could help me to find out.
The first for is to give each operator a precedence, so * is more important than +. Second loop is destinated to find the sign into the string, so if input.indexOf(signos[i]) is lower or than 0 it jumps off the operator. if its dalse it goes in and put the number in left side and right side into two aux values and in the end it solves the sign and replace it into the string so at the end it shows you the result.
Thanks.
var input;
var signos = ['*', '/', '+', '-'];
var cursor = 0;
var aux1 = "";
var aux2 = "";
var auxSigno = "";
var resuelto = 0;
var encontrado = false;
function lectura(){
input = document.getElementById("ans").value;
console.log(input);
for(i = 0; i < signos.length; i++){
cursor = input.indexOf(signos[i]);
//console.log(cursor);
if (cursor > -1){
auxSigno = input.charAt(cursor);
//console.log(auxSigno);
for(j = 0; j < input.length; i++){
for(k = cursor-1; comparar(k); k--){
aux1+=input[k];
}
for(l = cursor+1; comparar(l); l++){
aux2+=input[l];
}
operar();
var cadena = aux1+auxSigno+aux2;
var auxCadena = input.replace(cadena, resuelto);
input = auxCadena;
}
}
}
console.log(input);
}
function comparar(caracter){
for(m = 0; m < signos.length; m++){
if (caracter === signos[m]){
return true;
}
}
return false;
}
function operar(){
console.log(auxSigno);
console.log(aux1);
console.log(aux2);
if (signos.indexOf(auxSigno) == 0){
resuelto = parseFloat(aux1) * parseFloat(aux2);
console.log(resuelto + " opc1");
} else if (signos.indexOf(auxSigno) == 1) {
resuelto = parseFloat(aux1) / parseFloat(aux2);
console.log(resuelto + " opc2");
} else if (signos.indexOf(auxSigno) == 2) {
resuelto = parseFloat(aux1) + parseFloat(aux2);
console.log(resuelto + " opc3")
} else if (signos.indexOf(auxSigno) == 3){
resuelto = parseFloat(aux1) - parseFloat(aux2);
console.log(resuelto + " opc4")
} else {
console.log("opc no implementada");
}
}
if the input is "6+6*8", the result should be "54", but it doesn't show anything, just keep doing the for.

creating a new array out of an object

I've created a JavaScript object to get the number of times a character repeats in a string:
function getFrequency(string) {
// var newValsArray =[];
var freq = {};
for (var i=0; i<string.length;i++) {
var character = string.charAt(i);
if (freq[character]) {
freq[character]++;
} else {
freq[character] = 1;
}
}
return freq;
}
Now, I'm trying to construct a new string composed of the keys & their properties (the letters) & numbers of times the letters repeat if the number (property) is more than one but I keep getting undefined and I don't know why:
function newString(freq){
var newValsArray = [];
for (var prop in freq) {
if (freq[prop]>1){
newValsArray.push(prop + freq[prop]);
}
else if (freq[prop] < 2){
newValsArray.push(prop);
}
}
return newValsArray;
}
I feel like my syntax is off or something... if anyone has any suggestions, I'd really appreciate it...
You aren't explicitly returning anything from newString(), so it will return undefined. It sounds like you want something like this:
return newValsArray.join('');
at the end of newString() to construct an actual string (instead of returning an array). With that change, newString(getFrequency("Hello there") will return 'He3l2o thr'.
function getFrequency(string) {
// var newValsArray =[];
var freq = {};
for (var i = 0; i < string.length; i++) {
var character = string.charAt(i);
if (freq[character]) {
freq[character] ++;
} else {
freq[character] = 1;
}
}
return freq;
}
function newString(freq) {
var newValsArray = [];
for (var prop in freq) {
if (freq[prop] > 1) {
newValsArray.push(prop + freq[prop]);
} else if (freq[prop] < 2) {
newValsArray.push(prop);
}
}
return newValsArray.join("");
}
var mystring = "Here are some letters to see if we have any freq matches and so on.";
var results = newString(getFrequency(mystring));
var elem = document.getElementById("results");
elem.innerHTML = results;
<div id="results"></div>
You are not returning anything from the newString function. Add return newString; as the last line of the newString function. Adding that line does result in something being returned, though I can't tell if it is what you expected.
var text = "asdfjhwqe fj asdj qwe hlsad f jasdfj asdf alhwe sajfdhsadfjhwejr";
var myFreq = getFrequency(text);
show(myFreq);
var myNewValsArray = newString(myFreq);
show(myNewValsArray);
function getFrequency(string) {
// var newValsArray =[];
var freq = {};
for (var i=0; i<string.length;i++) {
var character = string.charAt(i);
if (freq[character]) {
freq[character]++;
} else {
freq[character] = 1;
}
}
return freq;
}
function newString(freq){
var newValsArray = [];
for (var prop in freq) {
if (freq[prop]>1){
newValsArray.push(prop + freq[prop]);
}
else if (freq[prop] < 2){
newValsArray.push(prop);
}
}
return newValsArray; // ******** ADD THIS LINE
}
function show(msg) {
document.write("<pre>" + JSON.stringify(msg, null, 2) + "</pre>");
}

Javascript: scope effect despite order of execution

Please note: This is not a question about scope, per se. I understand that in order to make the code work, I should make a deep copy of the variable board rather than assigning var tboard = board. However, I am not clear why making a shallow copy has the effect I describe below.
I am experiencing something I find baffling. Basically, a global variable (board) gets altered and I have no clue how. board is initialized in the function NewGame() (which is called from select()) as an empty array. After it is initialized, nothing else is called until the user clicks a square on the board (assuming the user has selected Xs for simplicity). When that happens, the function playerMove() is called. The baffling thing is that console.log(board) at the top of playerMove() prints out an array that has an x is the clicked position and os everywhere else (ie not empty). This is bizarre because the board is empty at the end of select() (which called NewGame()) and nothing else should happen in between. To demonstrate this, I print out the function name at the top of each function and I print out the board variable in the select() function and playerMove() function to show that it changes despite nothing else being called. Please note that to get this behavior, refresh the page (otherwise the board variable starts out full of os). I think this must be somewhat an issue of scope (because I am not making a deep copy of board) but it's strange because I have no clue what is being called that is changing the variable before it gets printed out at the top of playerMove().
Here is the link to my pen and the code: http://codepen.io/joshlevy89/pen/MKjxop?editors=101
$(document).ready(function() {
var pSym; // player's symbol
var cSym; // computer's symbol
var board;
var whosMove; // can be "player" or "computer" or "neither"
var gameOver;
setup();
$("#newgame").on('click', '#X', select);
$("#newgame").on('click', '#O', select);
$("#restart").on('click', setup);
$("table").on('click', 'td', playerMove);
function playerMove()
{
console.log('playerMove');
console.log(board);
if (whosMove === "player")
{
var val = $(this).data('value');
$('#g' + val).text(pSym);
var arr = PositionToCoords(val);
board[arr[0]][arr[1]] = pSym;
var tboard = board;
var gc = gameCheck(tboard);
if (gc>=0)
{
endGame(gc);
setTimeout(function(){setup();}, 1000);
return;
}
whosMove = "computer";
computerMove();
}
}
function computerMove() {
console.log('computerMove');
//var p1 = Math.floor(Math.random() * 3);
//var p2 = Math.floor(Math.random() * 3);
var tboard = board;
var pos = chooseMove(tboard);
var arr = PositionToCoords(pos);
board[arr[0]][arr[1]] = cSym;
DrawPosition(arr[0], arr[1], cSym);
var tboard = board;
var gc = gameCheck(tboard);
if (gc>=0) {
endGame(gc);
setTimeout(function(){setup();}, 1000);
return;
}
whosMove = "player";
}
function chooseMove(inboard) {
console.log('chooseMove');
// get the possible moves
var moves=[];
var scores = [];
for (var i=1;i<10;i++) {
var arr = PositionToCoords(i);
if (inboard[arr[0]][arr[1]] === undefined) {
moves.push(i);
var tboard = inboard;
tboard[arr[0]][arr[1]] = cSym;
var gc = gameCheck(tboard);
scores.push(gc);
}
}
//console.log(moves);
//console.log(scores);
return moves[0]; // TEMPORARY
}
function endGame(gc) {
console.log('endGame');
var str;
if (gc===1) { // somebody won
if (whosMove==="player"){
str = "You Won!"
}
else {
str = "You Lost :(";
}
}
else if (gc === 0){//draw
str = "It's a draw."
}
html = '<div id="closer">' + str + '</div>';
$('#endgame').html(html);
}
function gameCheck(tboard) {
console.log('gameCheck');
// get symbol to check for
var sym;
if (whosMove === "player") {
sym = pSym;
} else {
sym = cSym;
}
// check if in a row
var hrow;
var vrow;
// check for horizonal row
for (var i = 0; i < 3; i++) {
hrow = true;
vrow = true;
for (var j = 0; j < 3; j++) {
if (tboard[i][j] !== sym) {
hrow = false;
}
if (tboard[j][i] !== sym) {
vrow = false;
}
}
if ((hrow) || (vrow)) {
return 1;
}
}
var fdrow = true;
var bdrow = true;
for (var i = 0; i < 3; i++) {
if (tboard[i][i] !== sym) {
fdrow = false;
}
if (tboard[i][2 - i] !== sym) {
bdrow = false;
}
}
if ((fdrow) || (bdrow)) {
return 1;
}
// otherwise, check if board is full
var full = true;
for (var i = 1; i < 10; i++) {
var arr = PositionToCoords(i);
if (tboard[arr[0]][arr[1]] === undefined) {
full = false;
break;
}
}
if (full === true) {
return 0;
}
// if neither 0 (tie) or win (1), return -1 (game not over)
return -1;
}
function select() {
console.log('select');
pSym = $(this).data('value');
$('#newgame').html('');
NewGame();
console.log(board);
}
function setup() {
console.log('select');
$('#endgame').html('');
html = '<div id="opener">Xs or Os? <div id="buttons">';
html += '<div id="X" data-value="X" class="btn btn-default">Xs</div>';
html += '<div id="O" data-value="O" class="btn btn-default">Os</div>';
html += '</div></div>';
$('#newgame').html(html);
}
function NewGame() {
console.log('NewGame');
$('td').empty();
board = new Array(3);
for (i = 0; i < 3; i++) {
board[i] = new Array(3)
};
if (pSym === "X") {
cSym = "O";
whosMove = "player";
} else {
cSym = "X";
whosMove = "computer";
computerMove();
}
}
function DrawPosition(p1, p2, sym) {
console.log('DrawPosition');
var pos = p1 * 3 + (p2 + 1);
$("#g" + pos).text(sym)
}
function PositionToCoords(pos) {
console.log('PositionToCoords');
var p1 = Math.ceil(pos / 3) - 1;
var p2 = ((pos - 1) % 3);
var arr = [p1, p2];
return arr;
}
});
Thanks in advance.
Simply add the break in the for loop fixes the problem. Am I missing anything?
function chooseMove(inboard) {
console.log('chooseMove');
// get the possible moves
var moves = [];
var scores = [];
for (var i = 1; i < 10; i++) {
var arr = PositionToCoords(i);
if (inboard[arr[0]][arr[1]] === undefined) {
moves.push(i);
var tboard = inboard;
tboard[arr[0]][arr[1]] = cSym;
var gc = gameCheck(tboard);
scores.push(gc);
break; // <<<<<<<<<<<< This break guarantees that the computer only makes one move
}
}
//console.log(moves);
//console.log(scores);
return moves[0]; // TEMPORARY
}

Split array by tag and delete all similar element

I have some html page with text and need to output all inner HTML from tag b by alphabetical order in lower case. I'm just a begginer, so don't be strict.
My code is here (text is just for example): http://jsfiddle.net/pamjaranka/ebeptLzj/1/
Now I want to: 1) save upper case for inner HTML from tag abbr; 2) delete all similar element from the array (as MABs).
I was trying to find the way to split the array by tag, but all that I've done is:
for(var i=0; i<allbold.length; i++){
labels[i] = allbold[i].innerHTML;
}
var searchTerm = ['abbr'];
var abbr = [];
var keywordIndex;
$.each(labels, function(i) {
$.each(searchTerm, function(j) {
var rSearchTerm = new RegExp('\\b' + searchTerm[j] + '\\b','i');
if (labels[i].match(rSearchTerm)) {
keywordIndex = i;
for(var j=0; j<labels.length; j++){
abbr[i] = labels[i];
}
}
});
});
Vanilla JS solution (no library required, see jsFiddle):
var allbold = document.querySelectorAll("b"),
words = document.querySelector("#words"),
labels = {}, i, word, keys, label;
// first, collect all words in an object (this eliminates duplicates)
for(i = 0; i < allbold.length; i++) {
word = allbold[i].textContent.trim();
if (word === 'Labels:') continue;
labels[word.toLowerCase()] = word;
}
// then sort the object keys and output the words in original case
keys = Object.keys(labels).sort();
for(i = 0; i < keys.length; i++){
label = document.createTextNode("SPAN");
label.textContent = labels[keys[i]];
words.appendChild(label);
// add a comma if necessary
if (i < keys.length - 1) {
words.appendChild(document.createTextNode(", "));
}
}
with one helper:
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, "");
};
jQuery solution (see jsFiddle):
$(".content b").map(function () {
return $("<span>", {text: $.trim(this.textContent)})[0];
}).unique(function () {
return lCaseText(this);
}).sort(function (a, b) {
return lCaseText(a) < lCaseText(b) ? -1 : 1;
}).appendTo("#words");
with two helpers:
$.fn.extend({
unique: function (keyFunc) {
var keys = {};
return this.map(function () {
var key = keyFunc.apply(this);
if (!keys.hasOwnProperty(key)) {
keys[key] = true;
return this;
}
});
}
});
function lCaseText(element) {
return element.textContent.toLowerCase();
}
use the mapping element Is THIS FIDDLE for all upper case else this fiddle after your comment what you need
var maplabels = [];
for(var i=0; i<allbold.length; i++){
if (allbold[i].innerHTML != "Labels:") {
if(maplabels.indexOf(allbold[i].innerHTML) == -1){
maplabels.push(allbold[i].innerHTML);
labels.push('<i>' + allbold[i].innerHTML.toUpperCase() + '</i>');
}
}
}

Checking value in textbox against an array script not working

I have a script that I am checking values from textbox against an array, the array are all values from a drop down list. Cant seem to get it to work. Thanks.
<script type = "text/javascript">
function chkName() {
var ddlArray = new Array();
var ddl = document.getElementById('DropDownList1');
for (i = 0; i < ddl.options.length; i++) {
ddlArray[i] = ddl.options[i].value;
}
var str = document.getElementById("TextBox1").value;
str = str.replace(/^\s+|\s+$/g, ""); // strip leading and trailing spaces
str = str.toLowerCase().replace(/\b[a-z]/g, function (w) {
return w.toUpperCase()
}); // reformat to lower-case with initial capital
var match = false;
for (var i = 0; i < ddlArray.length; i++) {
if (str == ddlArray[i]) {
match = true;
}
}
if (match) {
alert("The name " + str + " does match our list!");
document.getElementById("TextBox1").value = "";
return false;
} else {
return true;
}
}
</script>
Try this:
function chkName() {
"use strict";
var ddlArray = [],
ddl = document.getElementById('DropDownList1'),
str = document.getElementById("TextBox1").value,
match = false;
for (var i = 0; i < ddl.options.length; i++) {
ddlArray[i] = ddl.options[i].value;
}
str = str.replace(/^\s+|\s+$/g, "");
str = str.toLowerCase().replace(/\b[a-z]/g, function( w ) {
return w.toUpperCase();
});
for (i = 0; i < ddlArray.length; i++) {
if ( str === ddlArray[i] ) {
alert("The name " + str + " does match our list!");
document.getElementById("TextBox1").value = "";
return false;
}
}
return true;
}

Categories

Resources