Create Repeatable HTML Form and Load Info from a JS Array - javascript

I have a JS array with info in it. I want to populate some sort of repeatable object such that I can display all the info in the same way (formatted). I assumed I would need to use a HTML form, but now can't figure out how to exactly populate it with the information from my JS array. I want to make this happen on a page load, but for right now I am trying to test it with a button.
<html>
<head>
</head>
<body>
<script>
var myArray = [
{
"title" : "My First Place",
"address": "My First Address",
},
{
"title" : "Treehouse",
"address": "off in the woods",
},
{
"title" : "My New Place",
"address": "Home Sweet Home",
}
];
function addRow() {
var itm = document.getElementById("infoArea");
var cln = itm.cloneNode(true);
for(var i = 0; i < myArray.length; i++){
document.getElementById("repeatafterme").appendChild(cln);
}
}
</script>
<div id="repeatafterme"></div>
<form name="myform" id="infoArea">
<fieldset>
<legend><label id="myFormID"><output name="title"></output><label></legend>
<label><output name="address"></output></label>
</fieldset>
</form>
<INPUT TYPE="button" NAME="myButton" VALUE="Press This" onclick="addRow()">
</body>
</html>

itm.cloneNode(true) must be within the block for and set different id to element new.
To set value of array title and address should access to children for get elements out
function addRow() {
var itm = document.getElementById("infoArea");
for(var i = 0; i < myArray.length; i++){
var cln = itm.cloneNode(true);
cln.id = "id" + i;
var outTitle = cln.childNodes[1].childNodes[1].childNodes[0].childNodes[0];
outTitle.value = myArray[i].title;
var outAddress = cln.childNodes[1].childNodes[3].childNodes[0];
outAddress.value = myArray[i].address;
document.getElementById("repeatafterme").appendChild(cln);
}
}
result: https://jsfiddle.net/cmedina/sL0v07tt/1/

Related

JavaScript: Modifying DOM and populating it with JSON data [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
first time asking for help so if I need to present myself in a specific section please point it out!
As said in the title, i've got a JSON data base, and need to populate a website with it's content. It's the first time a try doing something like this (still learning JS).
Here is an image of the expected result. If you prefer, this is the expected output in HTML:
<div class="cardsection">
<div class="card">
<div class= "photoandname">
<div class="profilphoto">
</div>
<h2 class="name"> </h2>
</div>
<div class="informations">
<h3 class="location"> </h3>
<p class="caption"> </p>
<p class="price"> </p>
</div>
<div class="tags">
<button class="tagButton"> </button>
<button class="tagButton"> </button>
</div>
</div>
</div>
The problems I have are :
For the Tag section, each card doesn't have the same number of tags. I understand that i need a nested loop, to access the nested array in the JSON data. I tried somethings out but didn't fully manage nor understand how that works so could one of you guys help me out and explain or show me?
Also i keep having an error for the "for" section of my Items loop ( Cannot read property 'length' of undefined) wich I don't get as the property is defined just above (var items = json.items;)
I'm not 100% sure my code is correct. Coded as I did, is it going to properly create each card with it's children ? ( without the identic classnames between cards mislead the appending? And with the aria-labels properly set?)
HTML code :
<div class="cardsection"> </div>
JS code :
var json = {
"photographers": [
{
"name": "jonna",
"id": 125,
"city": "paris",
"country": "UK",
"tags": ["portrait", "events", "travel", "animals"],
"tagline": "Doing my best",
"price": 400,
"portrait": "MimiKeel.jpg"
}
]};
var cardsection = document.getElementsByClassName("cardsection")[0];
var items = json.items;
for(var i = 0; i < items.length; i++) {
var cards = document.createElement("div");
cards.classList.add('card');
cards.setAttribute("aria-label", "Photographe card");
cardsection.appendChild(cards);
var photoandname = document.createElement("div");
photoandname.classList.add('photoandname');
photoandname.setAttribute("aria-label", "Profil photo and name section");
photoandname.innerHTML = items[i].portrait;
cards.appendChild(photoandname);
//ariel and alt to check
var profilphoto = document.createElement("img");
profilphoto.src = items[i].portrait;
profilphoto.alt = "Photographer's profil image";
profilphoto.classList.add('profilphoto');
profilphoto.innerHTML
photoandname.appendChild(profilphoto);
var name = document.createElement("h2");
name.classList.add('name');
name.innerHTML = items[i].name;
divphotoname.appendChild(name);
var informations = document.createElement("div");
informations.classList.add('informations');
card.appendChild(informations);
var location = document.createElement("h3");
location.classList.add('location');
location.innerHTML = items[i].city + items[i].country;
informations.appendChild(location);
var caption = document.createElement("p");
caption.classList.add('caption');
caption.innerHTML = items[i].tagline;
informations.appendChild(caption);
var price = document.createElement("p");
price.classList.add('price');
price.innerHTML = items[i].price;
informations.appendChild(price);
var tags = document.createElement("div");
tags.classList.add('tags');
var tagItems = json.items[i].tags;
for(var j = 0; j < tagItems.length; j++) {
var tagButton = document.createElement(button);
tagButton.classList.add('tagButton');
tagButton.id = tagItems[j]; /*ID needs to be the tag itself for a further filter functionality*/
tagButton.innerHTML = tagItems[j]; /*And setting the innerhtml of the button as the tag itself*/
tags.appendChild(tagButton);
}
card.appendChild(tags);
}
Thanks for any help and advice you can give me
https://jsfiddle.net/chille1987/s35qz4wf/
Javascript
const jsonFile = {
"photographers": [
{
"name": "jonna",
"id": 125,
"city": "paris",
"country": "UK",
"tags": ["portrait", "events", "travel", "animals"],
"tagline": "Doing my best",
"price": 400,
"portrait": "MimiKeel.jpg"
}
]
};
var cardsection = document.getElementsByClassName("cardsection")[0];
var items = jsonFile;
console.log(items.photographers.length);
for(var i = 0; i < items.photographers.length; i++) {
var card = document.createElement("div");
card.classList.add('card');
card.setAttribute("aria-label", "Photographe card");
cardsection.appendChild(card);
var photoandname = document.createElement("div");
photoandname.classList.add('photoandname');
photoandname.setAttribute("aria-label", "Profil photo and name section");
photoandname.innerHTML = items.photographers[i].portrait;
card.appendChild(photoandname);
var profilphoto = document.createElement("img");
profilphoto.src = items.photographers[i].portrait;
profilphoto.alt = "Photographer's profil image";
profilphoto.classList.add('profilphoto');
photoandname.appendChild(profilphoto);
var photographerName = document.createElement("H2");
photographerName.classList.add('name');
photographerName.textContent = items.photographers[i].name;
photoandname.appendChild(photographerName);
var informations = document.createElement("div");
informations.classList.add('informations');
card.appendChild(informations);
var caption = document.createElement("p");
caption.classList.add('caption');
caption.textContent = items.photographers[i].tagline;
informations.appendChild(caption);
var price = document.createElement("p");
price.classList.add('price');
price.innerHTML = items.photographers[i].price;
informations.appendChild(price);
var tags = document.createElement("div");
tags.classList.add('tags');
var tagItems = items.photographers[i].tags;
console.log(tagItems)
for(var j = 0; j < tagItems.length; j++) {
var tagButton = document.createElement('button');
tagButton.classList.add('tagButton');
tagButton.id = tagItems[j]; /*ID needs to be the tag itself for a further filter functionality*/
tagButton.textContent = tagItems[j]; /*And setting the innerhtml of the button as the tag itself*/
tags.appendChild(tagButton);
}
card.appendChild(tags);
}
The javascript looks pretty good (except it should be json.photographers, not json.items). But why jump straight into the big heavy model? Try working on
"photographers" : [ { "name" : "jonna" } ]
Start small, make sure your code works, then expand. Baby steps get more things done.

Is it possible to use a for loop to display values using buttons?

Hello here is my code at the moment. I would like to be able to display "you have selected" and then the name of the player that you pressed the draft button with however when pressing the button then it says you have selected "undefined". Would anyone be able to help thank you very much
var players=["Patrick Mahomes",
"Tyreek Hill",
"Travis Kelce",
"Chris Jones",
"Tom Brady"];
len=players.length;
for (var i=1;
i < len;
i++) {
document.getElementById("draft").innerHTML+=players[i]+"<button type=\"button\" onclick=\"draft()\">Draft</button><br>"
}
function draft() {
document.getElementById("demo").innerHTML+="You have selected"+players[i]+"<br>";
players.splice(players[i]);
}
<p id="draft"></p>
<p id="demo"></p>
the problem is that you don't specify the index when calling draft. You have to call it with the current index. I modified your code for it to work.
It should be easy to understand.
I also changed your var to let as it is better practice in javascript
<script>
let players = ["Patrick Mahomes", "Tyreek Hill", "Travis Kelce", "Chris Jones", "Tom Brady"];
let len = players.length;
for (let i = 0; i < len; i++) {
document.getElementById("draft").innerHTML += players[i] + "<button type='button' onclick='draft("+i+")'>Draft</button><br>"
}
function draft(player) {
document.getElementById("demo").innerHTML += "You have selected " + players[player] + "<br>";
players.splice(players[player]);
}
</script>
yes you can pass the player name as arg for draft()
for (var i=1;i<len;i++) {
document.getElementById("draft").innerHTML+=players[i]+"<button type=\"button\" onclick=\"draft('"+players[i]+"')\">Draft</button><br>"
}
function draft(player){
document.getElementById("demo").innerHTML+="You have selected "+player+"<br>";
players.splice(players[i]);
}
Why not pass i
<!DOCTYPE html>
<html>
<head>
<title>
Draft
</title>
</head>
<body>
<p id="draft"></p>
<script>
var players=["Patrick Mahomes","Tyreek Hill","Travis Kelce","Chris Jones","Tom Brady"];
len=players.length;
for (var i=0;i<len;i++) {
document.getElementById("draft").innerHTML+=players[i]+"<button type=\"button\" onclick=\"draft("+i+")\">Draft</button><br>"
}
// use different variable name for function parameter as var has scope for i here
function draft(k){
document.getElementById("demo").innerHTML+="You have selected"+players[k]+"<br>";
players.splice(players[k]);
}
</script>
<p id="demo"></p>
</body>
</html>
I didn't test but should work. I don't know why you are using players.splice(players[i]); but if you want to remove the element from players use
players.splice(k, 1);
See more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice#Syntax
Just pass the index to your method draft so you can use it to display the right cell from your array:
var players = ["Patrick Mahomes", "Tyreek Hill", "Travis Kelce", "Chris Jones", "Tom Brady"];
for (var i = 1; i < players.length; i++) {
document.querySelector("#draft").innerHTML += players[i] + "<button type=\"button\" onclick=\"draft("+i+")\">Draft</button><br>"
}
function draft(index) {
document.getElementById("demo").innerHTML += "You have selected " + players[index] + "<br>";
}
<p id="draft"></p>
<p id="demo"></p>
I think you made a typo at declaring the "len" var.
try to use "var len = players.length" or use a comma after the players var declaration.

How can I control my Json with jquery?

I have JSON data and I have two array with cities and countries.When I clicked my input cities are opening automatically but I want to do this too:
if I cliked my input cities must open (this is okey I did it)
but at the same time if I wrote something for example denmark (this is the list of countries) than denmark must seen if is matching.. how can I do that ?
click to see if you see on codepen
var myJSON = '{ "cities":[ "copenhagen", "london", "hamburg" ], "countries":[ "denmark", "norway", "sweden" ] }';
var myObj = JSON.parse(myJSON);
var testInput = document.getElementById("test");
testInput.setAttribute("data-list", myObj.countries)
function showlist() {
}
var comboplete = new Awesomplete('input.dropdown-input', {
minChars: 0,
});
Awesomplete.$('#test').addEventListener("click", function() {
if (comboplete.ul.childNodes.length === 0) {
comboplete.minChars = 0;
comboplete.evaluate();
}
else if (comboplete.ul.hasAttribute('hidden')) {
comboplete.open();
}
else {
comboplete.close();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.1/awesomplete.min.js"></script>
<input id="test" class="dropdown-input" />
What I get from your question is that you want entries from both arrays to show when you type anything. To achieve that use (myObj.cities.concat(myObj.countries)) array instead of myObj.cities or myObj.countries array alone.

Get data from JSON based upon the input received

I need to fetch data based upon the input received.
For example, if the input is 'Royal python', I should get details of Royal python.but with the following code, i get error saying 'The file you asked for does not exist'. But I get the value into fname. But not sure if the function is correct to fetch data from from array.Also I wanted to know if there is any shorter way to do this. Please help?
I'm using JavaScript for this, my code and the web page look are below:
<!DOCTYPE html>
<html>
<body>
<form> <input type="text" name="fname" required>
<button onclick="myFunction()">OK</button> `enter code here`
</form>
<p id="demo"></p>
<script> var text = '{"animals":[' +
'{"Common Name":"Royal Python","Order":"Squamata","Family":"Boidae","Genus":"Python","Species":"regius","Zoo":"Blackpool Zoo","Number":4 },' +
'{"Common Name":"Emperor Penguin","Order":"Sphenisciformes","Family":"Spheniscidae","Genus":"Aptenodytes","Species":"forsteri",` "Zoo":"Welsh Mountain Zoo","Number":35 },' +`
'{"Common Name":"Chimpanzee","Order":"Primates","Family":"Pongidae","Genus":"Pan","Species":"troglodytes", "Zoo":"Blackpool Zoo","Number":8 }]}';
obj = JSON.parse(text);
//function to fetch data based on input
function myFunction(fname)
{ var ani = "";
if (document.getElementByname("fname")="Royal Python")
var ani = document.getElementById("demo").innerHTML = obj.animals[0].Zoo + " " + obj.animals[0].Species; }} </body> </html>
Here is a solution to your problem that uses a for loop to check each index of the animal array for a match. This match will be case-insensitive also.
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<input type="text" name="fname" required>
<button onclick="fetchAnimal()">OK</button> `enter code here`
<script>
var animalsArr = [{
"commonName": "Royal Python",
"order": "Squamata",
"family": "Boidae",
"genus": "Python",
"species": "regius",
"zoo": "Blackpool Zoo",
"number": 4
}, {
"commonName": "Emperor Penguin",
"order": "Sphenisciformes",
"family": "Spheniscidae",
"genus": "Aptenodytes",
"species": "forsteri",
"zoo": "Welsh Mountain Zoo",
"number": 35
}, {
"commonName": "Chimpanzee",
"order": "Primates",
"family": "Pongidae",
"genus": "Pan",
"species": "troglodytes",
"zoo": "Blackpool Zoo",
"number": 8
}]
function fetchAnimal() {
var i;
var len = animalsArr.length;
// convert input name to lower-case
var name = document.getElementsByName('fname')[0].value.toLowerCase();
for (i = 0; i < len; i++) {
// check to see if lower-case input is the same as lower-case animal name (this ensures the match is case-insensitive)
if (animalsArr[i].commonName.toLowerCase() === name) {
document.getElementById('demo').innerHTML = animalsArr[i].zoo + ' ' + animalsArr[i].species;
}
}
}
</script>
</body>
</html>
Note: It is highly recommended move the JS code into an external script file if you intend to add more interactivity to the page.
There are a number of issues in your code:
document.getElementByname("fname")="Royal Python" should be document.getElementsByName("fname")[0].value == "Royal Python"
Also, it's cumbersome to write the text string and then parse it as JSON. Just use a JavaScript object.
You're also making it difficult on yourself when trying to determine the animal. Use Array.findIndex() if your browser supports it.
Here's a working example:
var obj = {animals:[{CommonName:"Royal Python",Order:"Squamata",Family:"Boidae",Genus:"Python",Species:"regius",Zoo:"Blackpool Zoo",Number:4 }, {CommonName:"Emperor Penguin",Order:"Sphenisciformes",Family:"Spheniscidae",Genus:"Aptenodytes",Species:"forsteri",Zoo:"Welsh Mountain Zoo",Number:35 }, {CommonName:"Chimpanzee",Order:"Primates",Family:"Pongidae",Genus:"Pan",Species:"troglodytes", Zoo:"Blackpool Zoo",Number:8 }]};
//function to fetch data based on input
function myFunction() {
var name = document.getElementsByName("fname")[0].value;
var index = obj.animals.findIndex(function(item) {
return item.CommonName === name;
});
if (index >= 0) {
document.getElementById("demo").innerHTML = obj.animals[index].Zoo + " " + obj.animals[index].Species;
}
}
<input type="text" name="fname" required value="Royal Python">
<button onclick="myFunction()">OK</button>
<p id="demo"></p>

Javascript Multiple Dependant Dropdowns

I am new to javascript and I'm struggling with the following code that will be in a form for registration of multiple candidates.
It creates 2 dependant select boxes (country and area) for each candidate.
Clicking the button 'Add Candidate' once allows the dependant boxes to work fine but clicking the button again stops it working. Accessing the selected values from the form when there is more than one candidate is also impossible as they will overwrite each other.
I have tried creating the select names as arrays using a count variable which I increment each time the ff function is called but I can't get it to work.
All help will be much appreciated!
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<title>Select Populate Test</title>
<script>
var UnitedStates = new Array();
UnitedStates[0] = "Texas";
UnitedStates[1] = "California";
UnitedStates[2] = "Arizona";
UnitedStates[3] = "Nevada";
UnitedStates[4] = "Florida";
var UnitedKingdom = new Array();
UnitedKingdom[0] = "Surrey";
UnitedKingdom[1] = "Kent";
UnitedKingdom[2] = "Dorset";
UnitedKingdom[3] = "Hampshire";
function populateDropdown(arry)
{
document.myForm.stateSelect.options.length = 0;
for (var i = 0; i < arry.length; i++)
{
document.myForm.stateSelect.options[i] = new Option(arry[i], arry[i]);
}
}
function updateDropdown(str)
{
var stateArray
var selectedCountry;
var countryDropdown = document.myForm.countrySelect;
for (var i = 0; i < countryDropdown.options.length; i++)
{
if (countryDropdown.options[i].selected)
{
selectedCountry = countryDropdown.options[i].value;
}
}
if (selectedCountry == 1)
{
stateArray = UnitedStates;
populateDropdown(stateArray);
}
if (selectedCountry == 2)
{
stateArray = UnitedKingdom;
populateDropdown(stateArray);
}
}
counter = 0;
function ff()
{
counter++;
var box = document.getElementById("details"+counter);
var cselectBox = document.createElement("Select");
cselectBox.name="countrySelect";
cselectBox.onchange = function()
{
updateDropdown();
}
var option1 = document.createElement("OPTION");
option1.text="United States";
option1.value=1;
cselectBox.options.add(option1);
var option2 = document.createElement("OPTION");
option2.text="United Kingdom";
option2.value=2;
cselectBox.options.add(option2);
document.getElementById("details"+counter).innerHTML+="</p><p>"+counter+". Candidate Country";
box.appendChild(cselectBox);
var box2 = document.getElementById("detailsx"+counter);
var ccselectBox = document.createElement("Select");
ccselectBox.name="stateSelect";
document.getElementById("detailsx"+counter).innerHTML+="</p><p>"+counter+". Candidate City";
box2.appendChild(ccselectBox);
}
</script>
</head>
<body>
<form name="myForm" >
<input type="button" value="Add Candidate" onClick="ff(); populateDropdown(UnitedStates);"">
<!--- Note: 6 Candidates will be the maximum. -->
<div id="details1"><b></b></div>
<div id="detailsx1"><b></b></div>
<div id="details2"><b></b></div>
<div id="detailsx2"><b></b></div>
<div id="details3"><b></b></div>
<div id="detailsx3"><b></b></div>
<div id="details4"><b></b></div>
<div id="detailsx4"><b></b></div>
<div id="details5"><b></b></div>
<div id="detailsx5"><b></b></div>
<div id="details6"><b></b></div>
<div id="detailsx6"><b></b></div>
</form>
</body>
</html>
There are multiple problems here. We'll tackle the one you're dealing with first.
When you name multiple controls with the same name, like stateSelect, you'll get the first one each time you try to reference it. If you instead set the id to 'stateSelect' + counter, you'll get a unique id, which you can then retrieve with document.getElementById(). So in the function to populate the dropdown would look like this:
function populateDropdown(arry)
{
var stateSelect = document.getElementById('stateSelect'+counter);
stateSelect.options.length = 0;
for (var i = 0; i < arry.length; i++)
{
stateSelect.options[i] = new Option(arry[i], arry[i]);
}
}
here is the fiddle I used to verify those changes.
You'll also need to add an event to each country dropdown to repopulate the state dropdown when it changes, and the structure needs a little work for that. If you're not opposed to frameworks, knockout would make this incredibly simple to run.
Here is the fiddle with everything working correctly and comments added at key changes
Update: Added link to the fiddle(s)

Categories