Here is my code to change div based on selection from drop down menu:
<form name="AdditionalLayer" id="selectLayers">
<select size="1">
<option value="">Layer:</option>
<option value="">-----------------------</option>
<option value="day1">Day 1</option>
<option value="day2">Day 2</option>
<option value="day3">Day 3</option>
</select>
</form>
<script> document.getElementById("selectLayers").addEventListener('change', function handleChange(event) {
if (event.target.value === 'day1') {
document.getElementById("legend_day1").style.display = 'block';
} else {
document.getElementById("legend_day1").style.display = 'none'; {
if (event.target.value === 'day2') {
document.getElementById("legend_day2").style.display = 'block';
} else {
document.getElementById("legend_day2").style.display = 'none'; {
if (event.target.value === 'day3') {
document.getElementById("legend_day3").style.display = 'block';
} else {
document.getElementById("legend_day3").style.display = 'none';
}
});
</script>
<div id="legend_day1">day 1 Legend</div>
<div id="legend_day2" style="display: none;">day 2 Legend</div>
<div id="legend_day3" style="display: none;">day 3 Legend</div>
My issue is how to get the correct div to show based on the hash url "#4/38.00/-97.03/day3". How would I be able to have day2 or day3 to display the correct div without having to reselect in the drop down? Thanks in advance.
CodePudding user response:
- Add your
<script>
tag at the end of the body. - Create reusable
function
fromfunction
in eventonchange
- Use
window.location.hash
to get that hash - Cut out the part you need
- Set that part to
select
value - Call reusable
function
<body>
....................................
<script>
function onChange(el) {
document.getElementById("legend_day1").style.display = 'none';
document.getElementById("legend_day2").style.display = 'none';
document.getElementById("legend_day3").style.display = 'none';
if (el.value === 'day1') {
document.getElementById("legend_day1").style.display = 'block';
} else if (el.value === 'day2') {
document.getElementById("legend_day2").style.display = 'block';
} else if (el.value === 'day3') {
document.getElementById("legend_day3").style.display = 'block';
}
}
let selectLayersEl = document.getElementById("selectLayers")
let selectEl = document.querySelector("#selectLayers > select")
selectLayersEl.addEventListener('change', function handleChange(event) {
onChange(event.target)
});
let hash = window.location.hash;
let day = hash.slice(hash.lastIndexOf("/") 1)
selectEl.value = day;
onChange(selectEl)
</script>
</body>
CodePudding user response:
One approach is below, with explanatory comments in the code itself:
// simple utility functions to provide aliases
// document.createElement(), allowing properties to be
// assigned to the created element at the point of creation,
// and also for both querySelector() and querySelectorAll()
// for both the Document and Element interfaces (which is
// used depends on whether a context is passed to the function,
// and whether thatn context is an Element or Document,
// the function defaults to Document).
// The querySelectorAll() (getAll) alias returns an Array
// of nodes instead of a NodeList:
const D = document,
create = (tag, props) => Object.assign(D.createElement(tag), props),
get = (selector, context = D) => context.querySelector(selector),
getAll = (selector, context = D) => [...context.querySelectorAll(selector)],
// a simple function to generate a 'hash' that ends with
// 'day1', 'day2', or 'day3':
generateHash = () => {
// creating an Array, using Array.from() with an Object literal
let numbers = Array.from({
// which specicifies the length of the Array:
length: 3
// iterating over that Array using Array.prototype.map()
// along with an arrow function, in which we take the index
// of the array element/entry, and add 1; in order to
// generate an Array starting at 1 instead of 0:
}).map((_, i) => i 1),
// we then generate a random number in a range from 0
// to the size of the Array:
index = Math.floor(Math.random() * numbers.length);
// and return a template-literal string which forms a
// rtring that approximates the type of path/hash you're
// expecting (albeit simplified):
return `#uri/path/hash/day${numbers[index]}`;
},
// the function to handle the 'change' event:
handleChange = (evt) => {
// here we retrieve the current element to which the
// function was bound:
let current = evt.currentTarget,
// retrieving the current value:
value = current.value;
// we use the getAll() alias of document.querySelectorAll()
// to retrieve all <div> elements with an id attribute
// starting with 'legend'; and we iterate over that Array
// of nodes using Array.prototype.forEach():
getAll('div[id^=legend]').forEach(
// here we pass a reference to the current Node of the
// Array of Nodes, and update its 'hidden'
// property/attribute depending on whether the id of the
// current node ends with the value; because we want to
// show the element with the matching id; we first call
// String.prototype.endsWith() to see if it ends with
// the supplied value (if so the function returns
// Boolean true), and we invert the result so that
// if there's a match, the element.hidden property
// is set to false, so that it's shown in the page:
(el) => el.hidden = !el.id.endsWith(value)
);
},
// retrieving a hash-like string:
hashCache = generateHash();
// getting a reference to the <body> element, and prepending
// a newly-created <a> element:
get('body').prepend(create('a', {
// setting its href to the hash we retrieved:
href: hashCache,
// setting its text-content to the same string
// (we could have used a pseudo-element to do
// this, but it felt 'tidier' doing it this way):
textContent: hashCache
}));
// in production you should obviously use
// location.hash can be called on any Location
// whether that's document.location, window.location,
// or HTMLAnchorElement.location; in production you
// should obviously use document, or window, in place
// of the <a> element:
let fauxHash = get('a').hash;
// h ere we get the <select> element, and use
// EventTarget.addEventListener to bind the handleChange
// function (note the deliberate lack of parentheses, we're
// binding the function here and not calling it) as the
// 'change' event-handler:
get("select").addEventListener('change', handleChange);
// here we're adding an anonymous Event Listener on the
// Window, once the DOM content is loaded:
window.addEventListener('DOMContentLoaded', (e) => {
// finding the first <a> element in the document:
let anchor = get('a'),
// finding the first <select> element:
select = get('select'),
// retrieving the hash of the <a> element,
// splitting it on the '/' character, and
// retrieving last entry in that hash:
hash = anchor.hash.split('/').pop();
// from the <select> element we're retrieving the
// first <option> that has a value attribute which
// matches the retrieved last-part of the hash
// we retrieved earlier, and then we retrieve its
// index and update HTMLSelectElement.selectedIndex
// property to assign that <option> as the currently
// selected <option>:
select.selectedIndex = get(`option[value=${hash}`, select).index;
// here we trigger the change event on the <select>
// element, which triggers a call to the event-handler
// function we bound above:
select.dispatchEvent(new Event('change'));
})
<form name="AdditionalLayer" id="selectLayers">
<select>
<!-- here I've added the selected, and disabled,
attributes to the 'label' <option> to ensure
that if any JS fails the 'label' will be shown
and cannot be reselected by the user: -->
<option value="-1" selected disabled>Select Layer:</option>
<option value="day1">Day 1</option>
<option value="day2">Day 2</option>
<option value="day3">Day 3</option>
</select>
</form>
<div id="legend_day1">day 1 Legend</div>
<div id="legend_day2">day 2 Legend</div>
<div id="legend_day3">day 3 Legend</div>
Array.prototype.forEach()
.Array.prototype.from()
.Array.prototype.map()
.Array.prototype.pop()
.- Arrow functions.
document.createElement()
.document.querySelector()
.document.querySelectorAll()
.Element.prepend()
.element.querySelector()
.element.querySelectorAll()
.Event()
.EventTarget.addEventListener()
.EventTarget.dispatchEvent()
.HTMLAnchorElement
.HTMLOptionElement
.HTMLSelectElement
.Location.hash
.Math.floor()
.Math.random()
.Object.assign()
.String.prototype.endsWith()
.String.prototype.split()
.
CodePudding user response:
I did find this that seems to work:
if (window.location.href.indexOf('day1') > -1) {
document.getElementById("legend_day1").style.display = 'block';
}
if (window.location.href.indexOf('day2') > -1) {
document.getElementById("legend_day1").style.display = 'none';
document.getElementById("legend_day2").style.display = 'block';
}
if (window.location.href.indexOf('day3') > -1) {
document.getElementById("legend_day1").style.display = 'none';
document.getElementById("legend_day3").style.display = 'block';
}