2

I have an app that can save user input locations in localStorage. When a user goes to the saved locations page in the app, the JavaScript creates divs for each saved location and displays the key text. I want to be able to click each location and run a function. I'm stuck on getting the divs to have hyperlinks. I think the problem is in my loop. "JavaScript:Void(0)" is just a placeholder for the moment. Here is what I have so far:

myApp.onPageInit('saved_locations', function (page) {

             var fragment = document.createDocumentFragment();
             var parent = document.getElementById("saved");


             // iterate localStorage
             for (var i = 0; i < localStorage.length; i++) {

             // set iteration key name
             var key = localStorage.key(i);

             // use key name to retrieve the corresponding value
             var value = localStorage.getItem(key);

             // console.log the iteration key and value
             console.log('Key: ' + key + ', Value: ' + value);

             //var idNum = i.toString();

             let node = document.createElement("div");
             let a = document.createElement("a");
             a.textContent = key;
             a.href = "JavaScript:Void(0)";

             node.appendChild(a);


             fragment.appendChild(node);

             };

             parent.appendChild(fragment);

             var myForm = document.getElementById("enter_location");

             myForm.addEventListener('submit', function saveSearchLocation() {

                                     var lat = document.getElementById('Latitude').value;
                                     var lon = document.getElementById('Longitude').value;
                                     var locationStr = document.getElementById('Location').value;

                                     //Save location parameters to local storage
                                     savedLocationParams = [lat, lon, locationStr];
                                     window.localStorage.setItem(locationStr, JSON.stringify(savedLocationParams));

                                     document.getElementById("saved").onsubmit = function(){
                                     window.location.reload(true);
                                     }

                                });





    });

Here is the HTML page:

<body>
<div class="pages">
   <div data-page="saved_locations" id="saved" class="page navbar-through no- 
toolbar" align="center">
    <h2><br><u>Enter A Location<br><br></u>
        <form id="enter_location">
            Latitude: <input type="text" id="Latitude" value=""><br>
                Longitude: <input type="text" id="Longitude" value=""><br>
                    Location: <input type="text" id="Location" value=""><br>
                    <input type="submit" value="Submit">
        </form>
    <h2><u>Saved Locations</u></h2>
            </div>
</div>

Bill Hambone
  • 157
  • 2
  • 14
  • Do the `a` elements exist? Please edit your question to show the source of the page you are working with. – Ruzihm Oct 03 '18 at 15:59
  • If I understand your question, I'm trying to make the a elements on the fly based on the keys in localStorage. – Bill Hambone Oct 03 '18 at 16:10
  • Can you make a snippet ? Also your HTML syntax is not valid, `h2` tag open but doesn't close.. – ElJackiste Oct 03 '18 at 16:14
  • The `href` attribute is not valid on a `div` element. If you want the `div` to be a hyperlink you can wrap it in an `a` tag, but you should also style the `div` with `display: inline-block`. Or you can register a `click` handler and use `window.open()` to make the `div` act like a hyperlink. – Jake Holzinger Oct 03 '18 at 16:38

1 Answers1

0

You have to create the a elements, and then assign the text you want to them, and then you have to put the a elements in the div.

let a = document.createElement("a");
a.textContent = "this is the link text";
a.href = "JavaScript:Void(0)";
node.appendChild(a);

If you want the value text to be linked, you can do this instead of creating the text node:

a.textContent = key;

I modified your code slightly to show an example. Just click on the "Click Here" to see the effects of the function :

//myApp.onPageInit('saved_locations', function (page) {
var clickMeToDoLoad = function() {
  var fragment = document.createDocumentFragment();
  var parent = document.getElementById("saved");


  var fakeLocalStorage = {
    "key0": "value0",
    "key1": "value1",
    "key2": "value2"
  };

  // iterate localStorage
  //for (var i = 0; i < localStorage.length; i++) {
  for (var i = 0; i < 3; i++) {
    // set iteration key name
    //var key = localStorage.key(i);

    // use key name to retrieve the corresponding value
    //var value = localStorage[key);

    // set iteration key name
    let key = Object.keys(fakeLocalStorage)[i];

    // use key name to retrieve the corresponding value
    let value = fakeLocalStorage[key];

    // console.log the iteration key and value
    console.log('Key: ' + key + ', Value: ' + value);

    let idNum = i.toString();

    let node = document.createElement("div");
    let a = document.createElement("a");
    a.textContent = key;
    a.href = "JavaScript:Void(0)";
    node.appendChild(a);
    fragment.appendChild(node);

  }

  parent.appendChild(fragment);
}
<div class="pages">
  <div data-page="saved_locations" id="saved" class="page navbar-through no- 
   toolbar" align="center">
    <h2><br/><u>Enter A Location<br /><br /></u></h2>
    <form>
      Latitude: <input type="text" name="Latitude" value=""><br> Longitude: <input type="text" name="Longitude" value=""><br> Location: <input type="text" name="Location" value=""><br>
      <input type="submit" value="Submit" onclick="return false;">
    </form>
    <h2><br /><u>Saved Locations</u></h2>
    <button onclick="clickMeToDoLoad();">Click to demo function</button>
  </div>
</div>
Ruzihm
  • 19,749
  • 5
  • 36
  • 48
  • Thanks! That works. Eventually these won't be hyperlinks, they will prompt the user to run another JS function. I just wanted to get this working first. Another issue I'm having is that when the submit button is clicked, the location is saved, but the app automatically navigates to the index.html. I want the page to refresh with the new location listed. I added window.location.reload(true); in the submit event listener but it's not working. – Bill Hambone Oct 03 '18 at 17:14
  • In the event listener, you can try adding `event.preventDefault();` in the event listener, like: `function foobar(event){ event.preventDefault(); /* rest of function */ }` Also, if you feel that my answer was a good solution to your problem, please [accept it](https://stackoverflow.com/help/someone-answers), as it will help people find it if they find that answer while googling their own problems, and it also gives me some stack overflow reputation ;). – Ruzihm Oct 03 '18 at 17:36
  • I tried event.preventDefault(); but now it won't submit – Bill Hambone Oct 03 '18 at 19:15
  • OK, I misunderstood the problem there. You might want to look into AJAX if you don't want the page to navigate away when the form is submitted. That way, you can have the form submit to whatever, get the response and then update the page based on the response. If you can't/won't use ajax, you'll have to reconfigure the page you're submitting the form to so that it will redirect you to the correct page. – Ruzihm Oct 03 '18 at 19:18
  • OK thanks. One more question. When these hyperlinks are clicked and navigate to another html page, is there a way to pass the key (name) from that hyperlink into the other page's JS function as a global variable? For instance, I click on "Portland, OR" and it navigates to a new html page (a map) and uses that key to grab the lat/lon coordinates from localStorage and zooms into Portland, OR. I've been trying to set up global object variables outside of the saved_locations page JS function, but I just need a way to pass that key onclick. – Bill Hambone Oct 03 '18 at 19:30
  • The most typical way would be to [encode it and add it as a GET parameter](https://stackoverflow.com/questions/332872/encode-url-in-javascript) in the `a.href`, and then on the other side, [parse and decode it](https://stackoverflow.com/questions/8486099/how-do-i-parse-a-url-query-parameters-in-javascript). If you run into trouble with that, it would make a good second question! – Ruzihm Oct 03 '18 at 19:44
  • I was trying to add a class to the a element and then retrieve it. This hasn't worked so far: a.className = "link"; var link = document.getElementsByClassName('link'); link.onclick = function(e) { linkName = e.srcElement.attributes.href.textContent; console.log("link name: " + linkName); } – Bill Hambone Oct 03 '18 at 19:54
  • `getElementsByX` methods will only find elements that have been added to the document. You would need to do all of the `appendChild` calls you need to do before you try to do `getElementsByX`. Anyway, why not just use `a.onclick = function(e){...};`? – Ruzihm Oct 03 '18 at 19:59
  • Because if I put a.onclick = function(e){ console.log("Name: " + e.key); }; in the loop where a is defined, I get the last key in the list regardless of which hyperlink I've clicked. If I move this function out of the loop with a as a global variable, I can't even navigate to the page. – Bill Hambone Oct 03 '18 at 20:13