Search code examples
javascriptarraysfunctional-programmingiteration

In JavaScript how to make a variable to include potentially infinite amount of elements (or something else that has the same effect)


I have the code below, which works well:

window.addEventListener('load', () => {
    const values = ['input_1', 'input_2', 'input_3', 'input_4', 'input_5', 'input_6', 'input_7', 'input_8'];
    document.querySelectorAll('.box-ipt').forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box1', values[Array.prototype.indexOf.call(document.querySelectorAll('.box-ipt'), input)]));
  });  

But I need a way to not have to go back to this code and add more elements to the variable like "input_9", "input_10" etc when I add more input boxes to my HTML code.

Basically a way to make that variable to accept any amount of "input_X" elements (like "input_∞" - I know ∞ does not exist in JS, just making a point).

Or maybe something else like a for loop like the one below but it is not working because the input gets set to random input instead of the last active one, after the extension reloads:

window.addEventListener('load', () => {
  const inputElements = document.querySelectorAll('.box-ipt');
  const values = [];
  for (let i = 0; i < inputElements.length; i++) {
    values.push(`input_${i + 1}`);
  }
  inputElements.forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box2', values[Array.prototype.indexOf.call(inputElements, input)]));
});

I also tried this but it breaks the extension/browser:

window.addEventListener('load', () => {
  let i = 1;
  for (;;) {
    const values = [`input_${i}`];
    document.querySelectorAll('.box-ipt').forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box2', values[Array.prototype.indexOf.call(document.querySelectorAll('.box-ipt'), input)]));
    i++;
  }
});

Any suggestions?

PS:I know the title sucks. Please suggest something else if you have a better idea.

EDIT:

More context to the JS code I have:

// Set focus after checking local storage for last focus

window.addEventListener('load', () => {
    const baseanimdur = getComputedStyle(window.parent.document.documentElement).getPropertyValue('--base-anim-dur').replace('s', '');
    const focusDelay = getComputedStyle(document.documentElement).getPropertyValue('--parent-grid-searchbox-focus-onload');
    setTimeout(() => {
        const inputValue = localStorage.getItem("myInputFocused_box1") || "";
        const inputNumber = inputValue.match(/\d+/)?.[0];
        const input = inputNumber ? document.querySelectorAll(".box-ipt")[inputNumber - 1] : document.querySelectorAll(".box-ipt")[0];
        input.focus();
    }, baseanimdur / focusDelay);
});

// Function on get active input on Search BT click in order to if input box empty then BT click goes back to focused box

window.getActiveInputOnBTClick = () => {
    const inputNumber = localStorage.getItem("myInputFocused_box1").match(/\d+/)?.[0];
    const input = inputNumber ? document.querySelectorAll(".box-ipt")[inputNumber - 1] : document.querySelectorAll(".box-ipt")[0];
    input.focus();
};

/////////////// REFOCUS WHEN CLICKING BODY ( EMPTY SPACE ) ///////////////

window.addEventListener('load', () => {
    const body = document.querySelector('body');
    document.addEventListener('click', event => {
        event.composedPath().includes(body) ? getActiveInputOnBTClick() : getActiveInputOnBTClick();
    });
});

/////////////// Set local storage item for memorizing last focus

window.addEventListener('load', () => {
    const values = ['input_1', 'input_2', 'input_3', 'input_4', 'input_5', 'input_6', 'input_7', 'input_8'];
    document.querySelectorAll('.box-ipt').forEach((input) => input.onfocus = (event) => localStorage.setItem('myInputFocused_box1', values[Array.prototype.indexOf.call(document.querySelectorAll('.box-ipt'), input)]));
  });   

Solution

  • This worked:

    window.addEventListener('load', () => {
        const [inputElements, values] = [document.querySelectorAll('.box-ipt'), []];
        inputElements.forEach((input, i) => {
            values.push(`input_${i + 1}`);
        });
        document.querySelectorAll('.box-ipt').forEach((input) =>
            input.onfocus = (event) =>
                localStorage.setItem('myInputFocused_box1',
                    values[Array.prototype.indexOf.call(document.querySelectorAll('.box-ipt'), input)]));
    });