Home > Software design >  Changing Div's based on dropdown and information in hash url
Changing Div's based on dropdown and information in hash url

Time:10-10

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:

  1. Add your <script> tag at the end of the body.
  2. Create reusable function from function in event onchange
  3. Use window.location.hash to get that hash
  4. Cut out the part you need
  5. Set that part to select value
  6. 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>

JS Fiddle demo.

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';     
}
  • Related