I need to find a way to use javascript to make multiple links for my left nav. I will have seperators dividing the links into categories.
This is my current code.
links = new Array();
links[1]="<span class='asep' style='border-top: 0px; margin-top: 0px;'>Welcome</span>";
links[2]="<a href='#'>Home</a>";
links[3]="<span class='asep'>Body Jewelry</span>";
links[4]="<a href='#'>Circular Barbells</a>";
links[5]="<a href='#'>Belly Button</a>";
links[6]="<a href='#'>Curved Barbells</a>";
links[7]="<span class='asep'>User Controls</span>";
links[8]="<a href='#' onclick='window.print(); return false'>Print This Page</a>";
function writeLinks() {
document.getElementById('nav1').innerHTML = links[1] + links[2] + links[3] + links[4] + links[5] + links[6] + links[7] + links[8];
document.getElementById('featured').innerHTML = ' <b>Featured Product</b><br><img src="icon1.gif" border="0"><br>Product Title';
}
setTimeout(writeLinks, 0); // Fires the function on page load without stopping other loads
Is there an easier way to do this?
There are various aspects of your methods which can be made "easier":
links = new Array();
Can be better-written as links = [];. (almost) everything you'll come across in Javascript is already an object, so being verbose about it doesn't add clarity.
links[1]="first..."
links[2]="second...";
can be better-written using .push(), so that you don't need to specify each index, eg:
links.push("first");
links.push("second");
or, if you're doing it all at once, using an array-literal, eg:
links = [
"first",
"second"
];
less-nice, in my opinion, but also an option, could be a mixture of both, using .concat():
links = [
"first",
"second"
];
links = links.concat([
"third",
"fourth"
]);
It might make sense to group things together using an array of bare objects, too:
sections = [
{
heading: '<span class="asep">First section...</span>',
links: [
'First',
'Second'
]
},
{
heading: '<span class="asep">Second section...</span>',
links: [
'Third',
'Fourth'
]
},
];
function writeLinks(){
var html = "";
for( var i = 0; i < sections.length; i++ ){
var section = sections[i];
html += section.heading + section.links.join("");
}
document.getElementById('nav1').innerHTML = html;
}
setTimeout(writeLinks, 0);
Note also the use of .join("") to join all elements of an array together as strings.
Next, you've got a lot of duplication in your code. You could specify only the parts which are different, eg:
sections = [
{
heading: "First section...",
links: [
"First",
"Second"
]
},
/* ...snip... */
];
function writeLinks(){
var html = "";
for( var i = 0; i < sections.length; i++ ){
var section = sections[i];
html += '<span class="asep">' + section.heading + "</span>";
for( var j = 0; j < section.links.length; j++ ){
html += '' + section.links[j] + "";
}
}
document.getElementById('nav1').innerHTML = html;
}
setTimeout(writeLinks, 0);
You could get rid of some of that raw HTML and simplify some of the loops, etc, by using a common library, such as jQuery or Prototype. This would also allow you to actually check that the document is ready for you to operate on it, rather than using that fragile setTimeout() hack. eg:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
/* ...snip... */
$(function(){
var nav = $("<div />").attr("id", "nav1");
$.each(sections, function(i,section){
nav.append( $("<span />").addClass("asep").text(section.heading) );
$.each(section.links, function(i,link){
nav.append( $("<a />").attr("href", "#").text(link) );
}
}
$("#nav1").replaceWith( nav );
});
</script>
All of those may be considered "easier" depending on your mood.
var arr = [];
arr[0] = <span class='asep'>Body Jewelry</span>;
arr[1] = <span class='asep'>Do Something</span>;
function writeLinks(){
document.getElementById("nav1").innerHTML = arr.join("");
}
Array.Join is faster than concat operation .
This might be a bit overkill, but you might want to look at a client side framework that supports models and templates, such as backbone.js. Then you could store all your links in a model which can easily be changed (and will automatically update the view for you through events), and you can also use underscore.js templates so you don't have to write any html as a string literal.
Related
I apologize in advance, this is the first Stack Overflow question I've posted. I was tasked with creating a new ADA compliant website for my school district's technology helpdesk. I started with minimal knowledge of HTML and have been teaching myself through w3cschools. So here's my ordeal:
I need to create a page for all of our pdf and html guides. I'm trying to create a somewhat interactable menu that is very simple and will populate a link array from an onclick event, but the title="" text attribute drops everything after the first space and I've unsuccessfully tried using a replace() method since it's coming from an array and not static text.
I know I'm probably supposed to use an example, but my work day is coming to a close soon and I wanted to get this posted so I just copied a bit of my actual code.
So here's what's happening, in example 1 of var gmaildocAlt the tooltip will drop everything after Google, but will show the entire string properly with example 2. I was hoping to create a form input for the other helpdesk personnel to add links without knowing how to code, but was unable to resolve the issue of example 1 with a
var fix = gmaildocAlt.replace(/ /g, "&nb sp;")
//minus the space
//this also happens to break the entire function if I set it below the rest of the other variables
I'm sure there are a vast number of things I'm doing wrong, but I would really appreciate the smallest tip to make my tooltip display properly without requiring a replace method.
// GMAIL----------------------------
function gmailArray() {
var gmaildocLink = ['link1', 'link2'];
var gmaildocTitle = ["title1", "title2"];
var gmaildocAlt = ["Google Cheat Sheet For Gmail", "Google 10-Minute Training For Gmail"];
var gmailvidLink = [];
var gmailvidTitle = [];
var gmailvidAlt = [];
if (document.getElementById("gmailList").innerHTML == "") {
for (i = 0; i < gmaildocTitle.length; i++) {
arrayGmail = "" + gmaildocTitle[i] + "" + "<br>";
document.getElementById("gmailList").innerHTML += arrayGmail;
}
for (i = 0; i < gmailvidTitle.length; i++) {
arrayGmail1 = "";
document.getElementById("").innerHTML += arrayGmail1;
}
} else {
document.getElementById("gmailList").innerHTML = "";
}
}
<div class="fixed1">
<p id="gmail" onclick="gmailArray()" class="gl">Gmail</p>
<ul id="gmailList"></ul>
<p id="calendar" onclick="calendarArray()" class="gl">Calendar</p>
<ul id="calendarList"></ul>
</div>
Building HTML manually with strings can cause issues like this. It's better to build them one step at a time, and let the framework handle quoting and special characters - if you're using jQuery, it could be:
var $link = jQuery("<a></a>")
.attr("href", gmaildocLink[i])
.attr("title", gmaildocAlt[i])
.html(gmaildocTitle[i]);
jQuery("#gmailList").append($link).append("<br>");
Without jQuery, something like:
var link = document.createElement("a");
link.setAttribute("href", gmaildocLink[i]);
link.setAttribute("title", gmaildocAlt[i]);
link.innerHTML = gmaildocTitle[i];
document.getElementById("gmailList").innerHTML += link.outerHTML + "<br>";
If it matters to your audience, setAttribute doesn't work in IE7, and you have to access the attributes as properties of the element: link.href = "something";.
If you add ' to either side of the variable strings then it will ensure that the whole value is read as a single string. Initially, it was assuming that the space was exiting the Title attribute.
Hope the below helps!
UPDATE: If you're worried about using apostrophes in the title strings, you can use " by escaping them using a . This forces JS to read it as a character and not as part of the code structure. See the example below.
Thanks for pointing this one out guys! Sloppy code on my part.
// GMAIL----------------------------
function gmailArray() {
var gmaildocLink = ['link1', 'link2'];
var gmaildocTitle = ["title1", "title2"];
var gmaildocAlt = ["Google's Cheat Sheet For Gmail", "Google 10-Minute Training For Gmail"];
var gmailvidLink = [];
var gmailvidTitle = [];
var gmailvidAlt = [];
if (document.getElementById("gmailList").innerHTML == "") {
for (i = 0; i < gmaildocTitle.length; i++) {
var arrayGmail = "" + gmaildocTitle[i] + "" + "<br>";
document.getElementById("gmailList").innerHTML += arrayGmail;
}
for (var i = 0; i < gmailvidTitle.length; i++) {
var arrayGmail1 = "";
document.getElementById("").innerHTML += arrayGmail1;
}
} else {
document.getElementById("gmailList").innerHTML = "";
}
}
<div class="fixed1">
<p id="gmail" onclick="gmailArray()" class="gl">Gmail</p>
<ul id="gmailList"></ul>
<p id="calendar" onclick="calendarArray()" class="gl">Calendar</p>
<ul id="calendarList"></ul>
</div>
I am trying to get prices from between span tags. I would like to have all prices in an array. I cant seem to get it to work, I am guessing my regex is incorrect.
I am looking for any span tags with the class 'amount', the tag has no other attributes set and only has one class. E.g. <span class="amount">£9.99</span>
var prices = resp.fragments['data'].match(/<span class=\"amount\">(.*?)<\/span>/g)
.map(function(val){
return val;
});
Output
[ '£9.99', '£100.00' ]
I am trying to get prices from between span tags. I would like to have all prices in an array. I cant seem to get it to work, I am guessing my regex is incorrect.
I am looking for any span tags with the class 'amount', the tag has no other attributes set and only has one class. E.g. <span class="amount">£9.99</span>
var prices = resp.fragments['data'].match(/<span class=\"amount\">(.*?)<\/span>/g)
.map(function(val){
return val;
});
Output
[ '£9.99', '£100.00' ]
* UPDATE *
Turns out it was an encoding with the ajax response resp.fragments['data'].
I was using regex as it is something I have not really used before in JS and thought I would have a play. I did look at many examples and after about 45 mins with no success I thought a fresh set of eyes would fix it.
#spaceman
Thanks for the helpful comment. Your one of those people if someone asked "Is there is a doctor in the house?", you would stand up and say "Sweet load there are loads of doctors out there".
While a regular expression could work for this, it might be easier to simply select the <span class='amount'> elements and map their innerHTML content to an array via the map() function:
// This would yield an array containing your values
var amounts = Array.prototype.slice
.call(document.querySelectorAll('span.amount'))
.map(function(a){ return a.innerHTML; });
You can see a working example of this demonstrated here.
Simplest method will be to add this to an invisible DOM object and then traverse it via DOM API
var text = '<span class="amount">£9.99</span><span class="amount">£9.99</span>'
//now append it to an DOM object
var wrapperDiv = "<div style='display:none' id='tmpDiv'>" + text + "</div>";
document.body.innerHTML += wrapperDiv;
var elements = document.querySelectorAll( "#tmpDiv amount" );
var output = Array.prototype.slice.call( elements ).map( function(val){
return val.innerText;
})
Another approach could be split the text by <span class="amount"> and get the value after first index
DEMO
var text = '<span class="amount">£9.99</span><span class="amount">£9.99</span>'
var output = [];
text.split('<span class="amount">').forEach( function(val, index) {
if (index > 0 )
{
output.push( val.replace( "</span>", "" ) );
}
});
document.body.innerHTML += JSON.stringify( output, 0, 4 );
You can use this instead.
var prices = document.getElementsByClassName('amount');
var price_array = [];
for (i= 0; i < prices.length; ++i) {
price_array.push(prices[i].innerHTML);
}
document.write(" | " + price_array);
<span class='amount'>£123</span>
<span class='amount'>£3</span>
<span class='amount'>£5</span>
<span class='amount'>£64</span>
You don't need to use regex or jQuery for this.
So I have successfully made a list using strictly HTML and CSS and that was simple enough. Now, I want to create the same list, while using JavaScript, for the most part. I'm not so sure why its so confusing for me.
Now I understand that in my HTML file, I must create a div for that list, and can implement the content in my .js file, while styling it however in my .css file. So here's what I have (and what I'm assuming is all I need) in my html file:
<div class="container">
<div class="row" id="content-list"></div>
</div>
I haven't really touched my css file yet because I like to save the styling for last.
I have a bit of a starting point in my .js file but let me explain a few things before showing my meaningless code (which I wrote based off what I was trying to understand from other examples or tutorials, but didn't fully know what I was doing). All I want, is to display a list of my favorite movies, along with an image aligned next to each movie title. That's all! I don't plan on adding any elements later, or removing... I just want my list but I can't figure it out! I feel so dumb.
Anyway, here's what I have (and yes I'm including the part I had commented out because I'm not sure which way is better, and I apologize for not finishing what I started with):
// JavaScript Document
function myMovies (movieTitle, movieThumb) {
this.movieTitle = movieTitle;
this.movieThumb = movieThumb;
}
/**
var contentList = [
{'content_title':'District 9', 'img_src':'district9.jpg', 'target_dir':''},
{'content_title':'Gladiator', 'img_src':'gladiator.jpg', 'target_dir':''},
{'content_title':'Django Unchained', 'img_src':'django.jpg', 'target_dir':''},
{'content_title':'Fantastic Mr. Fox', 'img_src':'fox.jpg', 'target_dir':''},
{'content_title':'Master and Commander', 'img_src':'master.jpg', 'target_dir':''}
];
**/
myMovies.prototype.myMovies = function (list) {
var html =
};
Please help me, I'm so lost. And if you could also please comment any code you give me, that would be so appreciated. Thank you!
Well, you can do this:
var contentList = [
{'content_title':'District 9', 'img_src':'district9.jpg', 'target_dir':''},
{'content_title':'Gladiator', 'img_src':'gladiator.jpg', 'target_dir':''},
{'content_title':'Django Unchained', 'img_src':'django.jpg', 'target_dir':''},
{'content_title':'Fantastic Mr. Fox', 'img_src':'fox.jpg', 'target_dir':''},
{'content_title':'Master and Commander', 'img_src':'master.jpg', 'target_dir':''}
];
var htmlStr = ''; // declare a variable which will hold the html for list
for(var i=0;i<contentList.length;i++) // create a loop to loop through contentList
{
htmlStr += "<div><img src='"+contentList[i].img_src+"'/>"+contentList[i].content_title+"</div>";
}
document.getElementById('content-list').innerHTML = htmlStr; // assign the innerhtml
I've commented the code.
LIVE DEMO
By the look of that var html =, I take it you're planning to build up a string of HTML code? I'm gonna assume you have your own plans on how to do that. It's mostly string concatenation, after all.
After you have html ready, use document.getElementById to get a reference to the container and set its innerHTML property to the string you've constructed.
document.getElementById('content-list').innerHTML = html;
In Javascript:
var contentList = [
{'content_title':'District 9', 'img_src':'district9.jpg', 'target_dir':''},
{'content_title':'Gladiator', 'img_src':'gladiator.jpg', 'target_dir':''},
{'content_title':'Django Unchained', 'img_src':'django.jpg', 'target_dir':''},
{'content_title':'Fantastic Mr. Fox', 'img_src':'fox.jpg', 'target_dir':''},
{'content_title':'Master and Commander', 'img_src':'master.jpg', 'target_dir':''}
];
var myList = document.createElement("ul"); // create the list
for (var i = 0; i < contentList.length; i++) { // for each Object in your Array
var myItem = document.createElement("li"); // create a item for the list
var myAnchor = document.createElement("a"); // create an anchor for the target_dir property
myAnchor.setAttribute("href", contentList[i].target_dir); // set the href attribute for the anchor
var myTitle = document.createTextNode(contentList[i].content_title); // create the text node to be inside the anchor (from the content_title property)
myAnchor.appendChild(myTitle); // append the text into the anchor
var myImage = document.createElement("img"); // create the DOMElement for the image
myImage.setAttribute("src", contentList[i].img_src); // set the attribute src (from the img_src property)
myImage.setAttribute("alt", contentList[i].content_title); // set the alt attribute only cause it's required for both XHTML and HTML5
myItem.appendChild(myAnchor); // append the anchor into the item list
myItem.appendChild(myImage); // append the image into the item list
myList.appendChild(myItem); // append the item list into the list
}
document.getElementById("content-list").appendChild(myList); // append the list into the div you've created
In jQuery:
var myList = $("<ul>")
for (var i = 0; i < contentList.length; i++) {
var myItem = $("<li>");
var myAnchor = $("<a>").attr("href", contentList[i].target_dir).text(contentList[i].content_title);
var myImage = $("<img>").attr("src", contentList[i].img_src).attr("alt", contentList[i].content_title);
myItem.append(myAnchor).append(myImage);
myList.append(myItem);
}
$("#content-list").append(myList);
In "ugly" (String concatanation) Javascript:
var myHTML = "<ul>";
for (var i = 0; i < contentList.length; i++) {
myHTML += "<li><a href='" + contentList[i].target_dir + "'>" + contentList[i].content_title + "</a><img src='" + contentList[i].img_src + "' alt='" + contentList[i].content_title + "' /></li>";
}
myHTML += "</ul>"
document.getElementById("content-list").innerHTML = myHTML;
I have to display images to the browser and I want to get the image from a JSON response and display it to the browser using Javascript. This is what the JSON response looks like:
[{
"0":"101",
"member_id":"101",
"1":"3k.png",
"image_nm":"3k.png",
"2":"\/images\/phones\/",
"image_path":"\/images\/"
},{
"0":"102",
"member_id":"102",
"1":"mirchi.png",
"image_nm":"mirchi.png",
"2":"images\/phones\/",
"image_path":"images\/phones\/"
},{
"0":"103",
"member_id":"103",
"1":"masti.png",
"image_nm":"masti.png",
"2":"images\/phones\/",
"image_path":"images\/phones\/"
}]
How do I do this (I am a beginner)?
here is the code what i wrote...
var jsonString = '[{"0":"101","member_id":"101","1":"3k.png","image_nm":"3k.png","2":"\/images\/phones\/","image_path":"\/images\/phones\/"},{"0":"102","member_id":"102","1":"mirchi.png","image_nm":"mirchi.png","2":"images\/phones\/","image_path":"images\/phones\/"},{"0":"103","member_id":"103","1":"masti.png","image_nm":"masti.png","2":"images\/phones\/","image_path":"images\/phones\/"}]';
var obj = JSON.parse(jsonString);
for(var i = 0, len = obj.length; i < len; i++){
var img = new Image();
img.setAttribute("src",obj[i][2] + obj[i][1]);
document.body.appendChild(img);
}
Assuming you parsed your json in a variable called json, this would add all images in a container with id yourcontainer:
var images = '';
for( var i=0, max<json.length; ++i ) {
images += '<img src="' + json[i]['image_path'] + json[i]['image_nm'] + '" />';
}
document.getElementById( 'yourcontainer' ).innerHTML = images;
Seems pretty straight forward. If this is json_encoded, then we can use json[key] to get the value, if you aren't familiar with the term 'key', json encodes arrays in the key:value, format, so for this, if we used json[member_id], we would get '101', if we used json[image_nm], we would get '3k.png', putting this all together it seems as if it's pretty well separated, you just have to know what goes where. I have an idea, but not 100%,I would expect you to do something like
var myImages = '';
for(var i = 0; i < json.length; i++){
myImages += '<img src="'+json[i]['image_path']+json[i]['img_nm']+'" />';
}
document.getElementById('myImgHolder').innerHTML = myImages;
Based on your json data, this would evaluate a variable and test it against the length of the json array. The statement also declares that while the variable is less than the total length of the json array, we will iterate to the next object. We would expect output along the format of -
<img src="/images/3k.png" />.
Then it would take the new images and place them in a Div with the id of myImgHolder.
Hope this helps.
EDIT 1
If you don't have a container to place these images inside of it, then you will need to create the container and place it somewhere.
var myImgHolder = document.createElement('div');
myImgHolder.setAttribute("id", "myImgHolder");
document.getElementById('ICanTargetThis').appendChild(myImgHolder);
The above code sets the variable myImgHolder to the creation of a new DIV element. Then, using the variable, we declare the attribute "id" to set as 'myImgHolder'. Now we have the element. But what do we do with it? Well we MUST target an existing element within our page, even if we're just targeting the tag...something. then we use the .appendChild method and use our variable...appendChild(myImgHolder);
You can use jQuery here.
Add following script in the head tag.
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(document).ready(function () {
var url = "entries.json";
$.getJSON(url, function (url){
var img= "";
$.each(url, function () {
img += '<li><img src= "' + this.images+ '"></li>';
});
$('body').append(img);
});
});
</script>
Can some one help me make the following JSON data:
{
"main": {
"label":"Main",
"url":"#main"
},
"project": {
"label":"Project",
"url":"#project"
},
"settings": {
"label":"Settings",
"url":"#settings",
"subnav":[
{
"label":"Privacy",
"url":"#privacy"
},
{
"label":"Security",
"url":"#security"
},
{
"label":"Advanced",
"url":"#advanced"
}
]
}
}
into the following bullets list using JS? Assuming you don't know what the first nodes are call labeled (e.g. "main", "project" <- these will be dynamically generated):
Main (#main)
Project (#project)
Settings (#settings)
Privacy (#privacy)
Security (#security)
Advanced (#advanced)
Thanks
Let's not use HTML string-hacking, shall we? That would break as soon as any of the data had characters like < or & in (or " in attribute values). Use DOM methods and you don't have to worry about character escaping:
function createNav(navs) {
var ul= document.createElement('ul');
for (name in navs) {
var nav= navs[name];
var a= document.createElement('a');
a.href= nav.url;
a.appendChild(document.createTextNode(nav.label));
var li= document.createElement('li');
li.id= 'nav-'+name;
li.appendChild(a)
if ('subnav' in nav)
li.appendChild(createNav(nav.subnav));
ul.appendChild(li);
}
return ul;
}
document.getElementById('navcontainer').appendChild(createNav(jsondata));
Most JS frameworks offer shortcuts to make this a bit less wordy. For example with jQuery:
function createNav(navs) {
var ul= $('<ul>');
for (name in navs) {
var nav= navs[name];
var li= $('<li>', {id: name});
li.append($('<a>', {href: nav.url, text: nav.label}));
if ('subnav' in nav)
li.append(createNav(nav.subnav));
ul.append(li);
}
}
$('#navcontainer').append(createNav(jsondata));
Note that either way, you're using an Object literal which means you get no control over the order the list of navs comes out. You have no guarantee that main will be above project. If you want a defined order, you will have to have the returned JSON data be an array.
My code is on JSfiddle.
As JSON parser I used this one.
The main code is a recursive renderer of the parsed JSON:
function recursive_parse(result) {
var html = '<ul>';
for (var k in result) {
html = html + '<li>' + result[k].label + ' (' + result[k].url + ')';
html = html + recursive_parse(result[k].subnav);
html = html + '</li>';
}
html = html + '</ul>';
return html;
}
var result = json_parse($("div#test1111").html());
var html = recursive_parse(result);
$("div#test2222").html(html);