I’m trying to create a modular series of element handlers for an app that has pages with varieties of configurations (eg: ‘Hex T’ config has elements ‘A’ thru ‘O’ that each has at least 1 DOM element that can be modified in different ways, but ‘Square Pad’ only has ‘A’ thru ‘E’ and the same lettered elements don’t always refer to the same type of element, be it a dropdown or number input).
So what I’ve done is made classes like LengthElement
that has 2 number inputs, one for Feet and one for Inches, and so LengthElement
holds the value in inches, and then whenever one of the elements, Feet or Inches, gets updated, it registers that change to the inches
value and then changes the Feet and Inches elements to properly display the correct measurement (eg: 10ft 0in => 10ft -1in => 9ft 11in).
There’s also a config
array that holds the list of all the various configurations the app can have, and what order the elements are in and what they are. I ID active inputs as ‘input’ and disabled inputs as ‘box’, it just helps me keep things straight. So, a Hex T active input pair for ‘A’ would have elements foot: '#ht-a-ft-input'
and inch: '#ht-a-in-input'
. I did this so I don’t have to write out all the IDs for every single possible element (there are currently over 100 on just this page) more than once.
There’s also an app requirement where certain lengths have to be divisible by 7, and I’ve got the logic in here. It’s probably not relevant but I figured that I’d include it as it is just in case. Finally, there’s an OnChange()
function that gets passed into each object instance, that’s a function with a callback that appears elsewhere that’s working just fine so I don’t think it matters.
Here’s the class code in its entirety:
class LengthElement {
inches; //Value of the Two Elements in Inches
foot; //String of the Foot Element
inch; //String of the Inch Element
div7; //Flag to determine if change needs to be Divisible by 7
OnChange; //Function specific to the instance to be called whenever the input changes
constructor(i, cfg, abrv, oC) {
this.inches = i;
if (cfg.foot == 'input') {
this.foot = '#' + abrv + '-' + cfg.name + '-ft-input';
$(this.foot).on('input', this.InputVal);
}
else {
this.foot = '#' + abrv + '-' + cfg.name + '-ft-box';
}
if (cfg.inch == 'input') {
this.inch = '#' + abrv + '-' + cfg.name + '-in-input';
$(this.inch).on('input', this.InputVal);
}
else {
this.inch = '#' + abrv + '-' + cfg.name + '-in-box';
}
this.div7 = cfg.div7;
this.OnChange = oC;
}
GetFeet(i) {
return Math.floor(i / 12);
}
GetInches(i) {
return i % 12;
}
GetDiv7(i) {
if (i % 7 > 5) {
return i + (7 - (i % 7));
}
else {
return i - (i % 7);
}
}
GetVal() {
return this.inches;
}
UpdateVal(i) {
if (this.div7) {
this.inches = this.GetDiv7(i);
}
else {
this.inches = i;
}
$(this.foot).val(this.GetFeet(this.inches));
$(this.inch).val(this.GetInches(this.inches));
}
InputVal() {
var newInches = ($(this.foot).val() * 12) + $(this.inch).val();
var change = newInches - this.inches;
if (this.div7) {
if (change > 0) {
newInches = this.inches + ((Math.floor(change / 7) * 7) + 7);
}
else if (change < 0) {
newInches = this.inches - ((Math.floor(change / 7) * 7) + 7);
}
else {
newInches = this.GetDiv7(newInches);
}
}
this.UpdateVal(newInches);
this.OnChange();
}
}
So what’s the problem?
Whenever InputVal()
gets called, this
refers to a jQuery object, and not the object it’s inside of. I believe the critical lines are the $(this.foot).on('input', this.InputVal);
lines, but I’m not sure what exactly is wrong with them.
Again, this is to avoid writing out every single element’s ID more than the one time where it’s declared in the HTML, so any alternatives that I can use to perform the same task are appreciated.
I am about 4 months into solo development so I can’t change frameworks off of jQuery. I would have an aneurysm.
2
Answers
you could try inserting this at the top of your constructor
so that
this
inside of the InputVal function always refers to LengthElementthe simple trick for that you should declare a variable name
self
, in constructor you bindingself = this
, in other method or callback you can usingself
instead ofthis