Code
I am having a form like this in HTML:
<label for="alternativeGraph">Alternative graphs could be seen here:</label>
<select id="selGraph" onchange="graphUpdate()" aria-label="Graph">
<option value="1" selected="selected">Graph 1 (default)</option>
<option value="2">Graph 2</option>
<option value="3">Graph 3</option>
<option value="4">Graph 4</option>
<option value="5">Graph 5</option>
</select>
<button type="button" onclick="setDefault()"> Change default graph</button>
I am planning to load Graph 1 as my default option when the page is loaded, and to change my default graph with setDefault() function. Here is my JavaScript code for it:
function render(filename) {
fetch(filename).then(response => response.text()).then(textAsString =>
renderString(textAsString));
}
function graphUpdate(){
let value = document.querySelector('#selGraph');
let graph = ["graph_1.gv", "graph_2.gv", "graph_3.gv", "graph_4.gv", "graph_5.gv"]
render(graph[value.selectedIndex]);
}
// function setDefault(){ # I am not sure about what should be added here...
// let new_default_graph = document.querySelector("#selGraph");
// new_default_graph.value =
// }
Issues
The main problem is that when I load the website, Graph 1 ("graph_1.gv" file) is not loaded, despite of my choice as the default graph. Only when I clicked on the dropdown form did the graph show up. (Other graphs are still loaded, though).
Questions:
Are there any method that could read from my selected option and load it from the beginning? And also, what should I do with my setDefault()
function so that when users choose option 3 for example, the website could save this option as the default one when being refreshed?
CodePudding user response:
As the web page takes time to load all the DOM components, maybe you should include a window.onload event function in your script, to call the graphUpdate() function after the page is fully loaded for the first time:
window.onload = graphUpdate;
More info here: https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
To save the selected value you can use window.localStorage, which allows you to make the value persistent in the browser, so the event function can be as follows:
window.onload = function() {
// 1 by default, in case there is nothing saved
let selected = window.localStorage.getItem('selectedGraph') || 1;
document.querySelector('#selGraph').selectedIndex = selected;
graphUpdate();
}
Then the graphUpdate function should include a line to store the value:
function graphUpdate(){
let value = document.querySelector('#selGraph');
let graph = ["graph_1.gv", "graph_2.gv", "graph_3.gv", "graph_4.gv", "graph_5.gv"]
render(graph[value.selectedIndex]);
window.localStorage.setItem('selectedGraph', value.selectedIndex)
}
Link: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
CodePudding user response:
Provided your JS code runs after the document elements exist (either by placing the <script>
tag after or using defer
), you can simply execute your graphUpdate()
function.
To save default options, I would use localStorage.
Finally, attribute-based event listeners like onchange
and onclick
should be discouraged.
<label for="alternativeGraph">Alternative graphs could be seen here:</label>
<select id="selGraph" aria-label="Graph">
<!-- values are easier to work with than indexes -->
<option value="graph_1.gv">Graph 1</option>
<option value="graph_2.gv">Graph 2</option>
<option value="graph_3.gv">Graph 3</option>
<option value="graph_4.gv">Graph 4</option>
<option value="graph_5.gv">Graph 5</option>
</select>
<button type="button" id="setDefaultGraphBtn">Change default graph</button>
// Constants
const DEFAULT_GRAPH_KEY = "default-graph";
const DEFAULT_GRAPH = "graph_1.gv";
// Elements
const graphSelect = document.getElementById("selGraph");
const btn = document.getElementById("setDefaultGraphBtn");
// Functions
const render = async (filename) => {
const res = await fetch(filename);
if (!res.ok) {
throw new Error(`${filename}: ${res.status} ${res.statusText}`);
}
renderString(await res.text());
};
const graphUpdate = () => {
render(graphSelect.value);
};
const setDefaultGraph = () => {
const val = graphSelect.value;
localStorage.setItem(DEFAULT_GRAPH_KEY, val);
graphSelect.querySelectorAll("option").forEach((opt) => {
// remove any previous "default" text
opt.textContent = opt.textContent.replace(" (default)", "");
// add "default" text
if (opt.value === val) {
opt.textContent = " (default)";
}
});
};
// Bind event listeners
graphSelect.addEventListener("change", graphUpdate);
btn.addEventListener("click", setDefaultGraph);
// Get localStorage value or default
const defaultGraph = localStorage.getItem(DEFAULT_GRAPH_KEY) ?? DEFAULT_GRAPH;
// set default selected
graphSelect.value = defaultGraph;
// Now run functions to initialise
setDefaultGraph();
graphUpdate();