1

I'm not able to store the style of an element in a variable and use it as the route:

let store = element.style.height;

store = 100px;

I'm trying to reduce my code by creating a constant that limits the max value of an input like follows:

const limitMaxVal = (whatToLimit, whatToStyle) => {
    let maxVal = parseFloat(whatToLimit.max);
    let minVal = parseFloat(whatToLimit.min);

    if (whatToLimit.value >= maxVal) {
        whatToLimit.value = maxVal;
        whatToStyle = maxVal / 10 + "%";
    } else if (whatToLimit.value <= minVal) {
        whatToStyle = minVal / 10 + "%";
    } else {
        whatToStyle = whatToLimit.value / 10 + "%";
    }
}

The constant has two variable. whatToLimit is the input I'm limiting and whatToStyle is what the input is styling. In this case I'm styling the height of a canvas but I want to use the same constant for the width, background-color... Which brings me to my problem: I can't find a way to store the style of an element as a route. If I store it like it follows I'll get the value of the height:

inputHeight.oninput = function() {
    limitMaxVal(this, canvas.style.height);
};

Another example of using the same constant would be:

inputWidth.oninput = function() {
    limitMaxVal(this, canvas.style.width);
};

I also tried using eval() but it doesn't work either:

const limitMaxVal = (whatToLimit, whatToStyle) => {
    let maxVal = parseFloat(whatToLimit.max);
    let minVal = parseFloat(whatToLimit.min);

    if (whatToLimit.value >= maxVal) {
        whatToLimit.value = maxVal;
        eval(whatToStyle) = maxVal / 10 + "%";
    } else if (whatToLimit.value <= minVal) {
        eval(whatToStyle) = minVal / 10 + "%";
    } else {
        eval(whatToStyle) = whatToLimit.value / 10 + "%";
    }
    
    this.focus();
}


inputHeight.oninput = function() {
    let store = "canvas.style.height";
    limitMaxVal(this, store);
};

cicb
  • 94
  • 9

2 Answers2

2

With your code, what got passed into the limitMaxVal function is a value of the style property, not the reference, while the function needs to know where to assign new values to, not what the current value is. Read the answers in Pass variables by reference in JavaScript to understand more about it.

To explain using your own code:

// This creates a variable with name `store` and value '200px',
// assuming that `element.style.height` is '200px'
let store = element.style.height;

// This changes the value of `store` to '100px',
// nothing happened to `element.style.height`
store = 100px;

// At the end, `store` is '100px',
// `element.style.height` remains '200px'

Based on what you wrote there I suggest passing the style object and the property name to the function, something like this:

const limitMaxVal = (whatToLimit, styleObj,  propertyName) => {
    let maxVal = parseFloat(whatToLimit.max);
    let minVal = parseFloat(whatToLimit.min);

    if (whatToLimit.value >= maxVal) {
        whatToLimit.value = maxVal;
        styleObj[propertyName] = maxVal / 10 + "%";
    } else if (whatToLimit.value <= minVal) {
        styleObj[propertyName] = minVal / 10 + "%";
    } else {
        styleObj[propertyName] = whatToLimit.value / 10 + "%";
    }
}

And here is how to use it:

inputHeight.oninput = function() {
    limitMaxVal(this, canvas.style, 'height');
};

  • Yes! That was it! Thank you so much for your quick answer and for showing me styleObj[propertyName] and pass by reference. Made my day!! – cicb Dec 13 '20 at 10:06
0

@Kelvin nailed it already - kudos!

However, I played around a bit and came up with this alternative approach. Here you specify the whatToStyle object and property as a string. However, it requires the target object to be in the global name space (window).

And please note: the min and max limitation is now done in a single expression using Math.min() and Math.max().

const canvas=document.getElementById("canvas"),
      inp=   document.getElementById("inp");

function limitMaxVal(whatToStyle){
  return function(ev){
    let inp=ev.target
    let wts=whatToStyle.split('.'), ob=window[wts.shift()];
    while (wts.length>1) ob=ob[wts.shift()];
    ob[wts[0]]=Math.min(Math.max(inp.value,inp.min),inp.max)+'%'
  }
}

// this is how you apply it on an input element:
inp.oninput=limitMaxVal("canvas.style.height");
#main {height:150px; width:300px}
#canvas {height:15%; width:300px; background-color:blue}
<input id="inp" type="number" value="15" max="100" min="10"><br>
<div id="main"> <div id="canvas"></div> </div>
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43