2

I have an issue with the following js. It sounds very silly but the following js keeps unchecking the 2 first checkbox (in <div id="shortcut1"></div> and <div id="shortcut2"></div>). I tested the script with different option, changing the params in cmdInfo. My conclusion is that no matter what the script will never check the 2 first checkbox at the end.

Do you have any idea regarding the issue. I spend hours on this but I can't figure out. Thanks a lot for your help !

https://jsfiddle.net/bqaude3h/2/

const URL_PLACEHOLDER = 'your url'

let commands = [
    { name: "shortcut1", description: null, shortcut: "Alt+W" },
    { name: "shortcut2", description: null, shortcut: "Alt+Q" },
    { name: "shortcut3", description: null, shortcut: "Alt+S" }
]
let cmdInfo = {
    "shortcut1": {
        "storeSearchHistory": true,
        "url": "https://test.com",
        "history": ['test']
    },
    "shortcut2": {
        "storeSearchHistory": false,
        "url": ""
    },
    "shortcut3": {
        "storeSearchHistory": true,
        "url": ""
    }
}

let html, div, existingHistory;
commands.forEach(cmd => {

    html = `
    <div id="${cmd.name}" class="sc-div">
        <div class="flex-container">
            <input type="text" class="shortcut" value="${cmd.shortcut}" />
            <input type="url" class="url" placeholder="${URL_PLACEHOLDER}"
                    value="${cmdInfo[cmd.name].url}" />
        </div>
        <div class="history-div">
            <button>View search history</button>
            <input type="checkbox" class="store-search-history" />
            <label><small>Save search history</small></label>
        </div>
    </div>
    `
    document.querySelector('#shortcuts').innerHTML += html;

    try {
        existingHistory = Boolean(cmdInfo[cmd.name].history.length)
    } catch {
        existingHistory = false;
    }

    div = document.getElementById(cmd.name);
    div.querySelector('button').disabled = !existingHistory;

    div.querySelector('.store-search-history').checked = cmdInfo[cmd.name].storeSearchHistory;
});

2 Answers 2

2

The issue is with this line: document.querySelector('#shortcuts').innerHTML += html;

You can read about Why is “element.innerHTML+=” bad code?. Basically, the browser will re-parse the constructed DOM multiple times which might cause to break reference.

This is a working example:

let commands = [{
    name: "shortcut1",
    description: null,
    shortcut: "Alt+W"
  },
  {
    name: "shortcut2",
    description: null,
    shortcut: "Alt+Q"
  },
  {
    name: "shortcut3",
    description: null,
    shortcut: "Alt+S"
  }
]
let cmdInfo = {
  "shortcut1": {
    "storeSearchHistory": true,
    "url": "https://some_url.com"
  },
  "shortcut2": {
    "storeSearchHistory": false,
    "url": ""
  },
  "shortcut3": {
    "storeSearchHistory": true,
    "url": ""
  }
}

let html, div, existingHistory, URL_PLACEHOLDER;
commands.forEach(cmd => {

  html = `
    <div id="${cmd.name}" class="sc-div">
        <div class="flex-container">
            <input type="text" class="shortcut" value="${cmd.shortcut}" />
            <input type="url" class="url" placeholder="${URL_PLACEHOLDER}"
                    value="${cmdInfo[cmd.name].url}" />
        </div>
        <div class="history-div">
            <button>
                <img src="icons/box-open-solid.svg"> View search history
            </button>
            <input type="checkbox" class="store-search-history" />
            <label><small>Save search history</small></label>
        </div>
    </div>
    `
  //document.querySelector('#shortcuts').innerHTML += html;
  document.querySelector('#shortcuts').insertAdjacentHTML('beforeend', html);

  try {
    existingHistory = Boolean(cmdInfo[cmd.name].history.length)
  } catch (e) {
    existingHistory = false;
  }

  div = document.getElementById(cmd.name);
  div.querySelector('button').disabled = !existingHistory;
  div.querySelector('.store-search-history').checked = cmdInfo[cmd.name].storeSearchHistory;
});
<div id='shortcuts'>

</div>

Sign up to request clarification or add additional context in comments.

Comments

1

You may use the conditional rendering for the input tag.


let commands = [
    { name: "shortcut1", description: null, shortcut: "Alt+W" },
    { name: "shortcut2", description: null, shortcut: "Alt+Q" },
    { name: "shortcut3", description: null, shortcut: "Alt+S" }
]
let cmdInfo = {
    "shortcut1": {
        "storeSearchHistory": true,
        "url": "https://some_url.com"
    },
    "shortcut2": {
        "storeSearchHistory": false,
        "url": ""
    },
    "shortcut3": {
        "storeSearchHistory": true,
        "url": ""
    }
    }

let html, div, existingHistory;
let URL_PLACEHOLDER="your placeholder"
commands.forEach(cmd => {

    html = `
    <div id="${cmd.name}" class="sc-div">
        <div class="flex-container">
            <input type="text" class="shortcut" value="${cmd.shortcut}" />
            <input type="url" class="url" placeholder="${URL_PLACEHOLDER}"
                    value="${cmdInfo[cmd.name].url}" />
        </div>
        <div class="history-div">
            <button>
                <img src="icons/box-open-solid.svg"> View search history
            </button>
            ${
                cmdInfo[cmd.name].storeSearchHistory?
                '<input type="checkbox" checked >'
                :'<input type="checkbox"  >'
            }
            <label><small>Save search history</small></label>
        </div>
    </div>
    `
    document.querySelector('#shortcuts').innerHTML += html;

    try {
        existingHistory = Boolean(cmdInfo[cmd.name].history.length)
    } catch {
        existingHistory = false;
    }

    div = document.getElementById(cmd.name);
    div.querySelector('button').disabled = existingHistory;
    // div.querySelector('.store-search-history').checked = cmdInfo[cmd.name].storeSearchHistory;
});


Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.