I am getting Fib.inputValidate is not a function
I am wanting to run the inputValidate
method so that on keyup
the input validates both as an integer
and as a Fibonacci
number:
HTML looks like this:
<form id="fibonacci-form" action="" method="post">
<input id="fibonacci" type="text" name="fibonacci"/>
</form>
Javascript ES6:
class Fibonacci {
constructor() {
const isPerfectSquare = '';
const isFibonacci = '';
const isInt = '';
const inputValidate = '';
this.isPerfectSquare = isPerfectSquare;
this.isFibonacci = isFibonacci;
this.isInt = isInt;
this.inputValidate = inputValidate;
} // constructor
inputValidate(valueParsed, isInt) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
field.addEventListener("keyup", function(e) {
if (this.isInt(valueParsed) === false && field.value !== '') {
alert('Please enter a valid integer.');
}
if(this.isFibonacci(valueParsed)) {
alert(valueParsed + ' is a Fibonacci Number.');
} else {
alert(valueParsed + ' is not a Fibonacci Number.');
}
});
}
isInt(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
isPerfectSquare(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
if (field.value !== '') {
return (squaredValue * squaredValue == valueParsed);
}
}
isFibonacci(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return this.isPerfectSquare(5 * valueParsed * valueParsed + 4) || this.isPerfectSquare(5 * valueParsed * valueParsed - 4);
}
} // class
let Fib = new Fibonacci();
console.log(Fib.inputValidate());
The real problem is that the this
inside event handlers is not what you think it is. The this
inside the event handler will be the (DOM) element that fired the event, not the instance of your class.
Now while you were trying to fix the real problem, you ended up with another problem, which is that you are shadowing the class methods with properties that have as values the empty string ''
.
To fix this, just remove the constructor all together as it doesn't do anything, and fix the issue with the this
inside the event listener. To do that you have plenty of ways:
that
, assign this
to it and use that
instead of this
inside the event listener.Like so:
var that = this;
field.addEventListener("keyup", function(e) {
// use 'that' instead of 'this'
if(that.isInt(valueParsed) ...
});
this
value:Like so:
// notice the arrow function passed to addEventListener
field.addEventListener("keyup", e => {
// you can now use 'this' here with no problems
if(this.isInt(valueParsed) ...
});
bind
your event handler to the instance of your class. bind
ing a function will create a new function that always have its this
value set to whatever you set it to.Like so:
field.addEventListener("keyup", function(e) {
// you can now use 'this' here with no problems
if(this.isInt(valueParsed) ...
}.bind(this)); // bind the function to its surronding 'this' value so 'this' inside it will be the same as 'this' outside it
Working code: Using an arrow function
class Fibonacci {
inputValidate(valueParsed, isInt) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
field.addEventListener("keyup", e => {
if (this.isInt(valueParsed) === false && field.value !== '') {
alert('Please enter a valid integer.');
}
if (this.isFibonacci(valueParsed)) {
alert(valueParsed + ' is a Fibonacci Number.');
} else {
alert(valueParsed + ' is not a Fibonacci Number.');
}
});
}
isInt(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
isPerfectSquare(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
if (field.value !== '') {
return (squaredValue * squaredValue == valueParsed);
}
}
isFibonacci(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return this.isPerfectSquare(5 * valueParsed * valueParsed + 4) || this.isPerfectSquare(5 * valueParsed * valueParsed - 4);
}
} // class
let Fib = new Fibonacci();
<form id="fibonacci-form" action="" method="post">
<input id="fibonacci" type="text" name="fibonacci" />
</form>
Enhanced working code:
There still are some issues with your code that are related to the functionality rather than errors:
valueParsed
argument is not used at all by even though it is an argument in all functions, instead you are fetching it from the DOM element every time. Use the argument.valueParsed
(now used as argument) will be initialized inside inputValidate
. It should be fetched from within the event listener not from outside it (every time the event fires we should get a new value for valueParsed
).Number
instead of parseInt
if you want to exclude float numbers (using parseInt
will let float numbers pass validation as it takes only the integer bit from them). Also if validation fail, return
to stop further code from executing. It (validation) still not very good though, I'll leave that to you.keydown
input on the field which is annoying. Create a button, and when the user clicks the button then check if the number they entered in the field is a Fibbonacci one or not. You would only change a line or two of code to achieve that.class Fibonacci {
inputValidate() {
var field = document.getElementById('fibonacci');
field.addEventListener("keyup", e => {
var valueParsed = Number(field.value);
if (this.isInt(valueParsed) === false) {
alert('Please enter a valid integer.');
return;
}
if (this.isFibonacci(valueParsed)) {
alert(valueParsed + ' is a Fibonacci Number.');
} else {
alert(valueParsed + ' is not a Fibonacci Number.');
}
});
}
isInt(valueParsed) {
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
isPerfectSquare(valueParsed) {
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return (squaredValue * squaredValue == valueParsed);
}
isFibonacci(valueParsed) {
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return this.isPerfectSquare(5 * valueParsed * valueParsed + 4) || this.isPerfectSquare(5 * valueParsed * valueParsed - 4);
}
} // class
let Fib = new Fibonacci();
<form id="fibonacci-form" action="" method="post">
<input id="fibonacci" type="text" name="fibonacci" />
</form>
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments