I've been working on a project that some other developers had started and I'm trying to understand the code while also completing the project. Currently what I have is some json with links and a url text (pretty much a quick description), what I need to do is on a button click I want to display each of the links with their correct text and make it a clickable link. The way this needs to be done is using nodes which I'm not 100% knowledgeable on. If I need to explain this more please let me know also I have provided an example of what I'm currently working with. Thanks
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>JavaScript And JSON</title>
</head>
<body bgcolor='#CED3F3'>
<button onclick="appendUrl()">Append</button><br>
<br><script id = "i">
function category()
//adding function with button click removes html page styling?
{
var category = {
"content": [
{
"links": "basic information",
"urlText": "Basis Information System",
"urlDesc": "portal for technology development, people search, a keyword search ."
},
{
"links": "http://site.com",
"urlText": "Net",
"urlDesc": "the entry page example"
},
{
"links": "http://newsgroups.com",
"urlText": "Newsgroups",
"urlDesc": "information internal newsgroups, usage, tools, statistics, netiquette"
},
{
"links": "http://site2.com",
"urlText": "Another site",
"urlDesc": "community for transfer of knowledge and technical information"
},
{
"links": "http://news.com",
"urlText": " some news",
"urlDesc": "place with news"
}
]
}
</script>
<script>
function appendUrl()
{
//there needs to be a loop here?
var link = "needs to loop through links?"
var node=document.createElement("LI");
var nodeA=document.createElement("A");
var textnode=document.createTextNode();
node.appendChild(nodeA);
nodeA.appendChild(textnode);
nodeA.href=(link);
nodeA.target="_blank";
document.getElementById("i").appendChild(node);
}
</script>
</body>
</html>
First you are going to need your category function to actually return the json data, otherwise it is of no use to anyone.
function category()
{
var category = {
"content": [
...
]
}
return category;
}
Then you can simply loop over the content array in the category object like this:
var content = category().content;
for (var i = 0; i < content.length; i++) {
var item = content[i];
var link = item.links;
var node=document.createElement("LI");
var nodeA=document.createElement("A");
var textnode=document.createTextNode(item.urlText);
node.appendChild(nodeA);
nodeA.appendChild(textnode);
nodeA.href=(link);
nodeA.target="_blank";
document.getElementById("i").appendChild(node);
}
However, if you're going to be creating list items in the markup, you are going to want to add them to a ul element, so you should have a ul somewhere in your markup like this:
<ul id="i"></ul>
And remove the id="i" from the script tag. You don't want to add the list items to the script.
This is the type of stuff jquery makes very easy to accomplish - if you can use it in your project.
var ul = $("<ul></ul">);
for(var i in category.content){
var li = $("<li></li>");
var a = $("<a href='" + category.content[i].links + "'>" + category.content[i].urlText + "</a>");
li.append(a);
ul.append(li);
}
containerDiv.append(ul);
In your example you also make list items children of a script tag. Not sure what your goal was there but I would have a plain div.
If you really have to do it in plain javascript:
var containerDiv = document.getElementById("parent");
var ul = document.createElement("ul");
for(var i in category.content){
var li = document.createElement("li");
var a = document.createElement("a");
a.href = category.content[i].links;
a.innerHTML = category.content[i].urlText;
li.appendChild(a);
ul.appendChild(li);
}
containerDiv.appendChild(ul);
A fiddle here
Related
Hello I am walking through the code which check if a user has visited websites before. and the code is as follows
<html>
<body>
<H1> Visited </H1>
<ul id = "visited"></ul>
<H1> Not visited</H1>
<ul id ="notvisited"></ul>
<script>
var websites =[
"http://www.facebook.com",
"http://www.instagram.com",
"http://google.com",
"http://twitter.com"
];
for( var i = 0; i < websites.length; i++)
{
var link = document.createElement("a");
var linebreak = document.createElement("br")
link.href = websites[i]
link.id = "id" + i
link.innerHTML = websites[i] + " "
document.write("<style>")
document.write("#id" + i + ":visited{ color: #FF0000; }");
document.write("</style>")
document.body.appendChild(link)
document.body.appendChild(linebreak)
var color = document.defaultView.getComputedStyle(link,null).getPropertyValue("color");
document.write(color)
document.body.appendChild(linebreak)
if (color == "rgb(255, 0, 0)"){
var item = document.createElement('li');
item.appendChild(link);
document.getElementById('visited').appendChild(item);
}
else {
var item = document.createElement('li');
item.appendChild(link);
document.getElementbyId('notvisited').appendChild(item);
}
}
</script>
</body>
</html>
When I check the colors of at the browser. it has changed visually but it has not change at document.write(color) showing rgb(0,0,238) still.
So, the problem I am facing and question would like to ask are is as follow :
Why does color does not change in value showing rgb(0,0,238) at document.write() although it changed visually?
'else' is not seemed to working here unless I replaced it with if (color == rgb(0,0,238) so why it happened there?
so please kindly help me the above problem. Many thanks in advance
Checking the color of :visited in JavaScript has been a security/privacy vulnerability that was closed long ago. That is why the underlying values have not changed.
I am trying to make a schema generator which will work something like this:
https://wtools.io/breadcrumb-json-ld-schema-generator
But the problem is i am able to add values and generate the schema list items but everytime i click "click me" a value is added to the schema as ListItem which is clearly not the intended behavior. Also, am failing to remove any added item from the generated schema even when i remove it from the list above.
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
background: silver;
}
.dis {
display: none;
}
</style>
</head>
<body>
<form>
<label for="item">Add an item: </label>
<input id="item" type="text" size="20"><br>
<input id="url" type="url" size="20"><br>
<input id="submitButton" type="button" value="Add!">
</form>
<ul id="ul">
</ul>
<p> Click an item to remove it from the list. </p>
<button onclick="myFunction();">Click me</button>
<br><br> <script type="application/ld+json"><br>
<div class="output">{ "#context": "https://schema.org", "#type": "BreadcrumbList", "itemListElement": [ { "#type": "ListItem", "position": 1, "name": "Google", "item": "google.com" } ] }</div></script>
</body>
</html>
window.onload = function() {
var button = document.getElementById("submitButton");
button.onclick = addItem;
}
function addItem() {
var textInput = document.getElementById("item"); //getting text input
var text = textInput.value; //getting value of text input element
var ul = document.getElementById("ul"); //getting element <ul> to add element to
var li = document.createElement("li"); //creating li element to add
li.setAttribute("class", "breadcrumb-item");
li.innerHTML = text; //inserting text into newly created <li> element
li.onclick = function() {
this.parentNode.removeChild(this);
setTimeout(function() {}, 1000);
}
ul.appendChild(li);
}
//script generation code here
// Create Script
var el = document.createElement('script');
el.type = 'application/ld+json';
// Set initial position
var position = 0;
// Create breadcrumb object
var breadcrumb = {
position: 0,
name: "",
item: ""
}
// Empty array for list items
var listArray = []
function myFunction() {
// Loop through each breadcrumb link and set attributes
var items = document.querySelectorAll('.breadcrumb-item');
for (var i = 0; i < 1; i++) {
var newItem = Object.create(breadcrumb);
var curItem = items[i];
newItem["#type"] = "ListItem";
position++;
newItem.position = position;
newItem.name = document.getElementById("item").value;
newItem.item = document.getElementById("url").value;
listArray.push(newItem);
}
// Create overarching Schema object
var breadcrumbSchema = {
"#context": "https://schema.org/",
"#type": "BreadcrumbList",
"itemListElement": listArray
};
var finalSchema = JSON.stringify(breadcrumbSchema);
// Add schema to Script
el.text = finalSchema;
// Set head variable with browser fallback
var head = document.head || document.getElementsByTagName("head")[0];
// Testing purposes - Show example of string in HTML
document.querySelector('.output').innerHTML = finalSchema;
// This won't work in codepen
head.appendChild(el);
// Testing purposes - Inspect source to see script generated inside of the "output" div
document.querySelector('.output').appendChild(el);
}
This is my first time working with JS so any help will be appreciated.
When you create the function to remove an item from your unordered list try adding a call to remove it from the listArray.
let textInput = document.getElementById("item"); //getting text input
let text = textInput.value; //getting value of text input element
let ul = document.getElementById("ul"); //getting element <ul> to add element to
let li = document.createElement("li"); //creating li element to add
li.setAttribute("class", "breadcrumb-item");
li.innerHTML = text; //inserting text into newly created <li> element
li.onclick = function() {
this.parentNode.removeChild(this);
//call to remove from listArray goes here
setTimeout(function() {
}, 1000);
}
ul.appendChild(li);
It might look like:
function removefromlist(item_position)
{
for(l in listArray){
if(listArray[1].position == item_position){
listArray.splice(l,1);
break;
}
}
}
Unless I'm missing something I'm not sure what other type would be added to your schema, because on line 92 of your code "ListItem" is the only type you ever assign.
I have a JSON file that's storing some data as an array of objects:
{
"projects": [
{
"title": "title0",
"content": "content0"
},
{
"title": "title1",
"content": "content1"
},
{
"title": "title2",
"content": "content2"
}
]
}
I'm using JQuery to try and put these into a list, one after another:
$.getJSON("projects.json", function( data ) {
console.log(typeof jsondataect);
var features = document.getElementById('featuredProjects');
var ul = document.createElement('ul');
for (var i = 0; i < data.length; ++i) {
var li = document.createElement('li');
$('li').html(data[i].content);
ul.appendChild(li);
}
features.appendChild(ul);
});
But this produces an empty HTML list in my document.
I want the HTML to list the elements of the JSON array like this:
<div>
<ul>
<li>title0</li>
<li>content0</li>
<li>title1</li>
<li>content1</li>
<li>title2</li>
<li>content2</li>
</ul>
</div>
What am I doing wrong?
Your main issue is that you're trying to loop through data which is just one thing - an object called projects. You need to loop through data.projects, including using data.projects.length in your for(). Also, you've done most everything in regular javascript, except the one line $('li')... That is jQuery, so I changed it for regular JS. But it wouldn't have worked anyways since the line
$('li').html(data[i].content);
Is saying 'Find every <li> element on the page and change it's inner text to be data[i].content. I changed that to just use the li reference you made the line before, and used innerHTML instead of $(id).html()
Finally, I see after all this that in your title, you want to do this in jQuery. So I added a second loop to show how to do that.
window.onload = () => {
var data = {
"projects": [{
"title": "title0",
"content": "content0"
},
{
"title": "title1",
"content": "content1"
},
{
"title": "title2",
"content": "content2"
}
]
}
var features = document.getElementById('featuredProjects');
var ul = document.createElement('ul');
for (var i = 0; i < data.projects.length; ++i) {
var li = document.createElement('li');
ul.appendChild(li);
li.innerHTML = data.projects[i].title;
li = document.createElement('li');
ul.appendChild(li);
li.innerHTML = data.projects[i].content;
}
features.appendChild(ul);
// here's the jQuery way
// Also showing a different way that you can loop through an array
let new_ul=[];
data.projects.forEach( obj => {
new_ul.push("<li>"+obj.title+"</li>");
new_ul.push("<li>"+obj.content+"</li>")
})
// join all the li's
$('#featuredProjectsJQ').html("<ul>" + new_ul.join("") + "</ul>")
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body><h3>Regular JS</h3>
<div id='featuredProjects'></div>
<h3>jQuery JS</h3>
<div id='featuredProjectsJQ'></div>
</body>
</html>
I'm new to JS. I'm trying to delete the parent node with all the children by clicking a button. But the console tells me that undefined is not a function. What am I missing?
Fiddle:
http://jsfiddle.net/vy0d8bqt/
HTML:
<button type="button" id="output">Get contacts</button>
<button type="button" id="clear_contacts">clear contact</button>
<div id="output_here"></div>
JS:
// contact book, getting data from JSON and outputting via a button
// define a JSON structure
var contacts = {
"friends" :
[
{
"name" : "name1",
"surname" : "surname1"
},
{
"name" : "name2",
"surname" : "surname2"
}
]
};
//get button ID and id of div where content will be shown
var get_contacts_btn = document.getElementById("output");
var output = document.getElementById("output_here");
var clear = document.getElementById("clear_contacts");
var i;
// get length of JSON
var contacts_length = contacts.friends.length;
get_contacts_btn.addEventListener('click', function(){
//console.log("clicked");
for(i = 0; i < contacts_length; i++){
var data = contacts.friends[i];
var name = data.name;
var surname = data.surname;
output.style.display = 'block';
output.innerHTML += "<p> name: " + name + "| surname: " + surname + "</p>";
}
});
//get Children of output div to remove them on clear button
//get output to clear
output_to_clear = document.getElementById("output_here");
clear.addEventListener('click', function(){
output_to_clear.removeNode(true);
});
You should use remove() instead of removeNode()
http://jsfiddle.net/vy0d8bqt/1/
However, this also removes the output_to_clear node itself. You can use output_to_clear.innerHTML = '' if you like to just delete all content of the node, but not removing the node itself (so you can click 'get contacts' button again after clearing it)
http://jsfiddle.net/vy0d8bqt/3/
You want this for broad support:
output_to_clear.parentNode.removeChild(output_to_clear);
Or this in modern browsers only:
output_to_clear.remove();
But either way, make sure you don't try to remove it after it has already been removed. Since you're caching the reference, that could be an issue, so this may be safer:
if (output_to_clear.parentNode != null) {
output_to_clear.remove();
}
If you were hoping to empty its content, then do this:
while (output_to_clear.firstChild) {
output_to_clear.removeChild(output_to_clear.firstChild);
}
I think using jQuery's $.remove() is probably the best choice here. If you can't or don't want to use jQuery, The Mozilla docs for Node provides a function to remove all child nodes.
Element.prototype.removeAll = function () {
while (this.firstChild) { this.removeChild(this.firstChild); }
return this;
};
Which you would use like:
output_to_clear.removeAll();
For a one-off given the example provided:
while (output_to_clear.firstChild) { output_to_clear.removeChild(output_to_clear.firstChild); }
Ok, in essence I want to create a short quiz that has a next and previous button. I want to loop through two arrays, questions and choices, and have a score at the end. I have read chapters on the DOM and Events and it is just not clicking apparently.
Really I need a little bit of code that shows a concrete example of how to manipulate the DOM. What I have so far are only the arrays, and a function declaring that x is in fact getting my element by id. haha.
Sorry I don't have more code to give. I tried to attach the id to a paragraph, and then get it by it's id and document.write the array, but that replaces the button. If you run the code below you'll see what I'm saying.
<!DOCTYPE html>
<html>
<head>
<title>Bom</title>
</head>
<body>
<input type="button" value="Iterate" id="myButton" onclick="iter_onclick()">
<p id="qArray">Some Text</p>
<script>
var qArray = ["Who is my dog?", "who is the prez?", "Who is my girlfriend?", "Who am I?"];
var cArray = [["Bill","Billy", "Arnold", "Tyler"],["Oz"," Buffon","Tupac","Amy"],["Tony Blair","Brack Osama","Barack Obama","Little Arlo"],["Emma Stone","Tony the Tiger","","The Smurf Girl"]];
function iter_onclick () {
var x = document.getElementById("qArray");
document.write("Hello World");
}
</script>
</body>
</html>`
Like I said, this is my first attempt at truly manipulating the DOM, and I know what I want to do. I just don't know how to do it. I am understanding all the syntax and events and objects and such. But, I'm not really sure how to apply it. Also, no Jquery. I want to know how to create applications with Javascript and then work my way into Jquery. Thanks people.
This will loop through your questions, hope this helps you to proceed.
var qArray = ["Who is my dog?",
"who is the prez?",
"Who is my girlfriend?",
"Who am I?"];
var cArray = [
["Bill", "Billy", "Arnold", "Tyler"],
["Oz", " Buffon", "Tupac", "Amy"],
["Tony Blair", "Brack Osama", "Barack Obama", "Little Arlo"],
["Emma Stone", "Tony the Tiger", "Amy Dahlquist", "The Smurf Girl"]
];
var index = 0;
function iter_onclick() {
//if this is the last question hide and displays quiz ends
if (index >= qArray.length) {
document.getElementById('qArray').innerHTML = '<div>Quiz End, Thank you</div>'
document.getElementById('myButton').style.visibility = 'hidden ';
return false;
}
var html = ' <div> ' + qArray[index] + ' </div> <div>';
for (var i = 0; i < cArray[index].length; i++) {
html += '<label><input type="radio" name="ans" value="'
+ cArray[index][i] + '"/ > ' + cArray[index][i] + ' </label>';
}
html += '</div > ';
document.getElementById('qArray').innerHTML = html;
index++;
}
Here's a very basic example you can work from. This modifies the existing DOM items. You cannot use document.write() on a document that is already loaded or it will clear everything you have and start over and it's not the most efficient way to put content into the DOM.
This example has a number of fields on the page, it loads a question and then checks the answer when you press the next button.
HTML:
<div id="question"></div>
<input id="answer" type="text"><br><br>
<button id="next">Next</button> <br><br><br>
Number Correct So Far: <span id="numCorrect">0</span>
Javascript (in script tag):
var qArray = ["Who is my dog?", "who is the prez?", "Who is my girlfriend?", "Who am I?"];
var cArray = [["Bill","Billy", "Arnold", "Tyler"],["Oz"," Buffon","Tupac","Amy"],["Tony Blair","Brack Osama","Barack Obama","Little Arlo"],["Emma Stone","Tony the Tiger","Amy Dahlquist","The Smurf Girl"]];
var questionNum = -1;
var numCorrect = 0;
function loadQuestion() {
++questionNum;
if (questionNum >= qArray.length) {
alert("all questions are done");
} else {
document.getElementById("question").innerHTML = qArray[questionNum];
document.getElementById("answer").value = "";
}
}
loadQuestion();
function checkAnswer() {
var answer = document.getElementById("answer").value.toLowerCase();
var allowedAnswers = cArray[questionNum];
for (var i = 0; i < allowedAnswers.length; i++) {
if (allowedAnswers[i].toLowerCase() == answer) {
return true;
}
}
return false;
}
document.getElementById("next").addEventListener("click", function(e) {
if (checkAnswer()) {
++numCorrect;
document.getElementById("numCorrect").innerHTML = numCorrect;
loadQuestion();
} else {
alert("Answer is not correct");
}
});
Working demo: http://jsfiddle.net/jfriend00/gX2Rm/