Benjamin Benjamin - 3 months ago 9
HTML Question

Insert html based on array

Lines 12-22

Function

openManu
currently displays a block on load and makes a for loop for my array. What this does is then creates an
obj
variable based on the array and takes
Manufacturer
from the array that's defined by the links that calls the function. So a link in my HTML for instance will have an
onMouseOver
event tied to
openManu('manufacturer')
and manu will be defined as manufacturer, only the "Description" in the array corresponding to this manufacturer will be inserted into the HTML.

My problem is I'm trying to create another function that runs before this that goes through my array and creates the links depending on what's in the array. Then since this gets called once the body loads the links should be present and the links will also have the
onMouseOver
event where the second function from lines 12-22 can be called.

Currently only
openManu()
works
onMouseOver
and will insert the
Description
based on the specified manufacturer into an object in my HTML called content. The
createLinks()
function I have opens the array and defines URL as a variable and inserts it into a link tag that gets created.

Is this possible to do? And is the order messing it up?

javascript:



var arr =
[
{
"Manufacturer": "Any manufacturer",
"Description": "Traditional values",
"URL": "http://www.website.com"
},
{
"Manufacturer": "Different Manufacturer",
"Description": "Short description of said manufacturer",
"URL": "http://www.website2.com"
},
{
"Manufacturer": "A Similar Manufacturer",
"Description": "Not quite the same as the previous manufacturer",
"URL": "http://www.website3.com"
},
{
"Manufacturer": "Manufacturer",
"Description": "Essentially a ripoff of the first manufacturer",
"URL": "http://www.website4.com"
}
]

function createLinks() {
for (var i=0; i<arr.length; i++){
var obj = arr[i];
var m = obj["Manufacturer"];
if (manu == m) {
URL = obj["URL"];
}
}
document.getElementById('col').innerHTML = "<a onmouseover=\"openManu(\'" ++ m ++ "\')\" onmouseout=\"mouseOut()\" onClick=\"openWeb(\'" ++ URL ++ "\')\">" ++ m ++ "</a>");
}

function openManu(manu) {
document.getElementById('content').style.display = 'block';
for (var i=0; i<arr.length; i++){
var obj = arr[i];
var m = obj["Manufacturer"];
if (manu == m) {
desc = obj["Description"];
}
}
document.getElementById('content').innerHTML = desc;
}

window.onmousemove = function (e) {
var tooltipSpan = document.getElementById('content');
var x = e.clientX,
y = e.clientY;
tooltipSpan.style.top = (y - 20) + 'px';
tooltipSpan.style.left = x + 'px';
}

var mouseOut = function(){
document.getElementById('content').style.display = 'none'
}

function openWeb(URL) {
window.open(URL);
}

#container{
width:870px;
margin-top:2em;
font-size:1.1em;
position:relative;
padding-left:20px;
display:inline-block;
background-color:#3C3C4E;}

#content{
z-index:1;
display:none;
width:300px;
font-size:16px;
font-family: 'Raleway', sans-serif;
position:absolute;
padding:10px;
background-color:white;}

a {
cursor:pointer;
padding:0;
display:inline-block;
margin:0;
color: white;
font-family: 'Raleway', sans-serif;
position:inherit;
}

h4 {
padding:0;
z-index:0;
display:inline-block;
margin:0;
color: white;
font-family: 'Raleway', sans-serif;
font-weight:normal;
font-size:15px;
background-color:#3C3C4E;
position:absolute;
left:8px;
padding:24px;
top:400px;
width:842px;
}

pre {
display:block;
float:left;
line-height:21px;
}

<!DOCTYPE html>
<html onload="createLinks()">

<div id="content"></div>

<pre id="col"></pre>

</html>





The old HTML included links that looked like this.

<a onmouseover="openManu('Any manufacturer')" onmouseout="mouseOut()" onClick="openWeb('http://www.website.com/')">Any manufacturer</a>


@Zer00ne in response to your answer, I changed createLinks() to this. I can't get it to work I might not fully understand your solution.

function createLinks() {
arr[i]["Manufacturer"]
var obj = arr[i];
var m = obj["Manufacturer"];
document.getElementById('col').innerHTML = "<a onmouseover=\"openManu(\'" ++ m ++ "\')\" onmouseout=\"mouseOut()\" onClick=\"openWeb(\'" ++ URL ++ "\')\">" ++ m ++ "</a>");
}


JSFiddle

Answer

UPDATE

Added the tooltips back, I realized what your intention was and #content following the cursor now. That would explain the wacky styles I was having trouble with.

I fixed it, the concept was sound the code needed a ton of work. I removed the mousemove event handler because having a tooltip made no sense when you already have a description displayed in #content. The following Snippet has descriptions in the /* comments */ // comments.

SNIPPET

/* Wrapped in an anonymous function to avoid globals */
(function() {
  var mfc = [{
    "Manufacturer": "Any manufacturer",
    "Description": "Traditional values",
    "URL": "http://www.website.com"
  }, {
    "Manufacturer": "Different Manufacturer",
    "Description": "Short description of said manufacturer",
    "URL": "http://www.website2.com"
  }, {
    "Manufacturer": "A Similar Manufacturer",
    "Description": "Not quite the same as the previous manufacturer",
    "URL": "http://www.website3.com"
  }, {
    "Manufacturer": "Manufacturer",
    "Description": "Essentially a ripoff of the first manufacturer",
    "URL": "http://www.website4.com"
  }];

  /* It's better to declare variable of 'for' loop outside of loop */
  var i, len = mfc.length;


  for (i = 0; i < len; i++) {
    // Use of bracket notation requires quotes 
    var m = mfc[i]["Manufacturer"];
    var URL = mfc[i]["URL"];
    var desc = mfc[i]["Description"];
    var col = document.getElementById('col');
    /*
    /| When concatenating strings, alternate between single and double
    /| quotes and don't double up on '+'
    */
    // title attribute will be "Description"
    // Just use href attribute instead of a function that does the same thing (i.e. openWeb(URL)
    // The text of an anchor is m
    /* 
    /| Notice the '+=' operand, this allows us to accumulate strings 
    /| instead of overwriting them on every loop. 
    */
    col.innerHTML += '<a title="' + desc + '" href="' + URL + '">' + m + '</a>';
  }
  var content = document.getElementById('content');


  /*
  /| Instead of attribute events, use addEventListener() on the 
  /| parent of the links (i.e. #col). In order to determine which anchor
  /| was clicked, you assign a var to event.target.
  */

  col.addEventListener("mouseover", function(e) {
    // Find the e.target (i.e. element that was hovered over), and get it's title
    // display content with desc as it's content.
    var desc = e.target.getAttribute('title');
    content.style.display = "block";
    content.innerHTML = desc;
  }, false);

  col.addEventListener("mouseleave", function(e) {
    content.style.display = "none";
  }, false);


  col.addEventListener("mousemove", function(e) {
    var x = e.clientX,
      y = e.clientY;
    content.style.top = (y - 20) + 'px';
    content.style.left = x + 'px';
  }, false);

})();
#container {
  width: 870px;
  line-height: 1.2;
  margin-top: 2em;
  font-size: 1.1em;
  position: relative;
  padding-left: 20px;
  display: inline-block;
  background-color: #3C3C4E;
}
#content {
  z-index: 0;
  display: none;
  width: 400px;
  font-size: 16px;
  font-family: 'Raleway', sans-serif;
  position: absolute;
  padding: 10px;
  color: white;
  background-color: black;
  top: 0;
}
col {
  position: absolute;
  top: 70px;
}
a {
  cursor: pointer;
  padding: 0;
  display: inine-block;
  margin: 0 5px;
  color: white;
  font-family: 'Raleway', sans-serif;
}
h4 {
  padding: 0;
  z-index: 0;
  display: inline-block;
  margin: 0;
  color: white;
  font-family: 'Raleway', sans-serif;
  font-weight: normal;
  font-size: 15px;
  background-color: #3C3C4E;
  position: absolute;
  left: 8px;
  padding: 24px;
  top: 400px;
  width: 842px;
}
pre {
  display: block;
  float: left;
  line-height: 21px;
}
<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title></title>
</head>

<body>

  <div id="container">
    <div id="content"></div>
    <div id="col">
    </div>
  </div>
</body>

</html>