A question about javascript

I don’t really know javascript. I’m coming from the perspective of “can I port this python function”, rather than trying to build things up properly. I’m trying to write an interactive webpage that relies on sliders and other inputs to control a drawing on screen.

So, an typical drawing will have half a dozen sliders, coupled with half a dozen “input type=number” fields for inputting precise values.

And each of those functions is sort of like this:

document.getElementById(“ALPHASlider”).onchange=function(){
ALPHAinput=this.value; //assigns a numeric label to the slider
redraw();
}

document.getElementById(“ALPHAInput”).onchange=function(){
ALPHAslider=this.value; //moves the slider to match the newly typed value
redraw();

essentially, lots of code that can be autogenerated by a simple program.
And, I have written such an program (in python, since that’s where I’m comfortable). If I paste this autogenerated code into my js file, it works.

But it looks like a maintenance nightmare.

So, how would someone with a bit more javascript experience wire up the webpage?

2 Likes

I haven’t really used React yet, it’s still on my list of things to learn. But you might be interested in giving it a look. It’s pretty popular now and was designed for that sort of thing. Scroll down to the example “A Component Using External Plugins” and you can see an example of elements wired together into a component. You could define the component and then have something that creates and initializes an array or mapping of them.

If you don’t want to use a library like that, (and I’m a fan of keeping things simple and avoiding dependencies) about the only thing that I’d do differently from what I can see of your code is encapsulate it in an object/module and either pass the ids as variables instead of hard-coding them and/or use data-something attributes to link the related controls together. That would allow you to just define the object once, instantiate multiple instances of it in a loop, and each instance would ‘know’ which elements it controlled. (vs autogenerating a lot of repetitive code)

[ETA: This is a good explanation of the module pattern in JS: https://toddmotto.com/mastering-the-module-pattern/ The ‘Revealing Module Pattern’ section is basically how I begin when structuring my code.]

2 Likes

Can’t you just put that function into a library so you can write it once and reuse from multiple places? Or am I just misunderstanding the problem…

1 Like

Sounds pretty cool to me. You think in Python, you needed Javascript, you made it happen.

2 Likes

yeah, I may have overthought the problem

function wireUpControl(attribute){
var sliderInput = document.getElementById(attribute+‘Slider’);
var textInput=document.getElementById(attribute+‘Text’);
sliderInput.oninput = function() {
textInput.value=this.value;
doStuff(false);
}
sliderInput.onchange = function() {
textInput.value=this.value;
doStuff(true);
}
textInput.oninput = function() {
sliderInput.value=this.value;
doStuff(false);
}
textInput.onchange = function() {
sliderInput.value=this.value;
doStuff(true);
}

}

works well enough.

3 Likes

Simple, clear, and direct. That would pass a code review.

4 Likes

anytime i as a human am doing repetitive work i try to offload it to the machine. it’s just always a trick of learning what’s possible in the environment you’re working in. ( nothing wrong with brute force though, just to get the !$%! thing done. :wink: )

two thoughts:

first, in javascript ( unlike python ), you can add variables to things as you see fit. so, you could have something like:

   sliderInput.other= textInput;
   textInput.other= sliderInput;
   var update= function(evt) {
      this.other.value= this.value;
      doStuff( evt.type === "change" )
   };

   sliderInput.onchange= 
   textInput.onchange= 
   sliderInput.oninput= 
   textInput.onchange= update;

the other thing is that you can use html to your advantage. ( especially if you have lots, or arbitrary numbers of these pairings. )

for instance, you could encapsulate each pair in a “div”, give that div some class “myPair”, then operate on all such pairings uniformly.

 var allPairs= document.getElementsByClassName('myPair');
 Array.prototype.forEach.call(allPairs, pairIt);

where pairIt (parrot?) is something like:

var pairIt= function(myPair) {
 var input= myPair.getElementsByTagName("input").item(0);
 var slider= myPair.getElementsByTagName("slider").item(0);
 input.other= slider;
 slider.other= input;
 // set to update, same as before.
};

jquery could be a good tool for you in that it helps smooth out the uglies. ie. the getElements… syntax, and the fact that things like “element collections” are not true arrays ( which is why you need silly calls like .item(0), and Array.prototype instead of [0] and just plain .forEach )

does any of that help at all?

3 Likes