How to populate div tables and dropdownboxes with JSON and Javascript? - javascript

I've been trying to populate div tables with dummy JSON data but I cannot seem to do it. What I want to do is display certain data depending of the selection in a dropdownbox. Also I need to create new row with a new dropdownbox when an item is selected. Could you give me some advice of what's the best way to do it. I'm able to create something close to what I need in Angular but I need it in pure JavaScript. Thanks in advance!
structure of my div tables

Suppose in data you have json object
var data = [
{
"line": "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.",
"author": "Brian W. Kernighan",
"num" : ["1","2","3"]
},
{
"line": "Walking on water and developing software from a specification are easy if both are frozen.",
"author": "Edward V Berard",
"num" : ["5","0","15"]
},
{
"line": "It always takes longer than you expect, even when you take into account Hofstadter's Law.",
"author": "Hofstadter's Law",
"num" : ["15","222","301"]
}];
and you want to populate all authors in above json object to table and num into respective dropdown element of table-row. Then following populateHTML() function populate object to table and num into respective dropdown element of table-row as shown in below image .
function populateHTML(data) {
if (typeof(data) == 'object') {
document.write('<table>');
for (var i in data) {
document.write('<tr><td>'+data[i].author+'</td><td><select>');
for(var j in data[i].num){
document.write('<option>' +data[i].num[j]+ '</option>');
}
document.write('</select></td></tr>');
}
document.write('</tr></table>');
} else {
document.write(' => ' + data);
}
}

This can be achieved with the following code: You can also check an example here: http://skillcram.com/JS_DivTable.htm
<script type="text/javascript" >
function populateTable() {
var tableData = {
products : [
{"id": 100,"name":"Laptop", "qty":1,"status": ["Delivered","Damaged","Missing"]},
{"id": 200,"name":"Monitor", "qty":2,"status":["Refused","Partial"]}
]
}
var tableBody = document.getElementsByClassName("divTableBody");
for (i in tableData.products){
tableBody[0].innerHTML += "<div class=\"divTableRow\"> " +
"<div class=\"divTableRowCell\">"+ tableData.products[i].id +" </div> " +
"<div class=\"divTableRowCell\">"+ tableData.products[i].name +" </div> " +
"<div class=\"divTableRowCell\">"+ tableData.products[i].qty +" </div> "+
"<div class=\"divTableRowCell\">"+ getSelectHTMl(tableData.products[i].status) +
" </div> "+
"</div>";
}
}
function getSelectHTMl(status) {
selectHTMlStr = "<select> ";
for (j in status){
selectHTMlStr +=
"<option value=\""+ status[j]+ "\" id=\"itemStatus\" >"+status[j]+ " </option>" ;
}
selectHTMlStr += "</select>" ;
return selectHTMlStr;
}
</script>

Related

Angular: Eventhandling Problems with JS generated Code OR not being able to add classes to HTML generated Code with *ngfor

My problem is the following:
I have stations I want to display inside a modal window, whereas the already selected Stations should be coloured blue and the not selected ones should be gray.
All stations are in an array called "allStations" and the already selected stations are in "currentStations".
However, I have multiple problems with this:
First off:
I either generate this in HTML with a *for loop, then I have the problem, that I am not able to assign the classes that should colour each one.
<jw-modal id="ov_stations">
<div id="allstationsdiv">
<p *ngFor="let st of allStations" id="{{ st.id }}" class="notselected"(click)="onstationclick({{st.id}})">
{{ st.name }}
</p>
</div>
<span (click)="closemodal()"><img src="../../../../assets/icons/x.png" alt=""></span>
</jw-modal>
I tried to solve this by generating the HTML inside the openmodal() function, which opens the modal in the first place instead of directly in the HTML:
openmodal(){
this.modalService.open("ov_stations");
let output = document.getElementById("allstationsdiv");
let dealtwith = [];
if (output.childElementCount == 0){
for (var i = 0; i < this.allStations.length; i++){
if (this.currentStations.length == 0)
output.innerHTML += "<p id='" + this.allStations[i].id + "' class='notselected' (click)='onstationclick(" + this.allStations[i].id + ")'>" + this.allStations[i].name + "</p>";
else {
// noch weiter testen
for (var j = 0; j < this.currentStations.length; j++){
if (this.currentStations[j].id == this.allStations[i].id){
output.innerHTML += "<p id='" + this.allStations[i].id + "' class='selected' (click)='onstationclick(" + this.allStations[i].id + ")'>" + this.allStations[i].name + "</p>";
dealtwith.push(this.allStations[i].id);
// console.log("selected: " + this.allStations[i].id + " and dealt with: " + dealtwith[i]);
} // && this.allStations[i].id != dealtwith[i]
else if (this.currentStations[j].id != this.allStations[i].id){
output.innerHTML += "<p id='" + this.allStations[i].id + "' class='notselected' (click)='onstationclick(" + this.allStations[i].id + ")'>" + this.allStations[i].name + "</p>";
dealtwith.push(this.allStations[i].id);
// console.log("notselected: " + this.allStations[i].id + " and dealt with: " + dealtwith[i]);
}
console.log(dealtwith);
console.log(this.allStations[i].id);
}
}
}
}
}
(I am aware that the loop doesn't work yet, but that is not my immediate concern)
However, now, when I try to click on a Station to access the function which would change it's class, it does not work anymore, the function is not called upon. I am guessing that this is because I now generate the code inside JS instead of from HTML.
How can I solve this problem?
Is there a way to give the p's the correct class with the conditions above?
Or is there a way to solve the problem of not being able to get a click function to work from JS?
I would prefer the latter, but if the first one is easier I am willing to try that too.
Thank you very much for your time.
Using the ngClass directive (https://angular.io/api/common/NgClass) will get you the outcome you are looking for. For example:
in your component.html
<div id="allstationsdiv">
<p *ngFor="let st of allStations"
[ngClass]="{
'selected':isStationSelected(st),
'notselected':!isStationSelected(st)
}"
(click)="onstationclick(st.id)">
{{ st.name }}
</p>
</div>
in your component.ts file
export class MyComponent {
allStations = [
{ id: 1, name: "station 1" },
{ id: 2, name: "station 2" },
{ id: 3, name: "station 3" },
{ id: 4, name: "station 4" },
{ id: 5, name: "station 5" }
];
selStations = [{ id: 3, name: "station 3" }, { id: 4, name: "station 4" }];
onstationclick(station): void {
//do something here
}
// will check to see if the currentStations array contains the station id you
// are passing from the all stations array
isStationSelected(station): boolean {
return this.currentStations.some(st=> st.id === station.id);
}
}
in your component.css
.selected {
color: blue
}
.notselected {
color: grey
}
Generally you should avoid generating html code via js in angular, since you have angular itself to do that.

Storing dynamic id for TD ID with JSON file

Okay, so i am pulling data from a json file and at the same time i am putting them in to a table. I've managed to give every td item a dynamic id. However, that id is only accessible inside the html and when i try to use for a function it is either undefined or it is getting the length of every row but not the id.
<script type='text/javascript'>
var dynID;
$(function() {
var data = [];
$.getJSON( 'f-data.json', function(data) {
$.each(data.data, function(i, f) {
var tblRow = "<tr><th>" + '<td id = "editable'+this.id+'">' + f.Title+ "</td></th>";
dynID = $(this).find("td").attr("id");
tblRow += '<th colspan="2"><button type ="submit" class="edit" onclick="editButton(dynID)"></i></button>';
$(tblRow).appendTo(".screens tbody");
});
});
});
<script type='text/javascript'>
function editButton(id) {
alert(id);
}
JSON :
{ "data":[
{
"Title": "Screen 1",
"id": 1
},{
"Title": "Screen 2",
"id": 2
}
The above produces a button and when the button is pressed the result is undefined. The strange thing is that the id's are generated correctly (e.g. editable1, editable2, etc). I guess am not selecting the id correctly?
You are running into reference issues within the $.each loop. Within the loop, the reference to $(this) is a jQuery object made of the element of data array. It does not have any HTML. I believe you meant to treat/parse tblRow as jQuery object and extract the id from it. Doing this is bad for performance. your current code simply the output of the button is:
<button onclick="editButton(dynID)"></button>
This is because dynID is becoming a part of the string -- there is no concatenating happening here. Hence, the output becomes a reference to a variable named dynID in the global scope window.
I would rewrite that code as below.
$.each(data.data, function(i, f) {
var id = this.id, // use id accross the loop.
tblRow = "<tr><th>" + '<td id = "editable' + id +'">' + f.Name + "</td></th>";
tblRow += '<th colspan="2"><button type ="submit" class="edit" onclick="editButton("' + id + '")"></i></button>';
$(tblRow).appendTo(".screens tbody");
});

jQuery Mobile load new data only

I'm working on this project for learning purposes. The tasks for now are very simple:
Populate data from DB using $.getJSON.
Check every 'n' seconds for new data and append it to the list.
Notify user about new data changes.
Here is the example of where I got so far: ( JSBin /Don't forget to run js)
All the issues will be visible when running the example.
Here is the JS code that i have:
$(document).bind('pageinit', function(){
var $myList = $( "#myList" );
var newItems = [];
function loadList(){
$.getJSON("http://jsbin.com/vayeni/2.js",function(data){
$.each(data, function( index, value ) {
newItems.push( "<li><a>" + value.airline + "</a></li>" );
if(data>newItems){
alert('New Entry');
data=newItems;
}
});
$myList.append( newItems.join( "" ) );
$myList.listview( "refresh" );
setTimeout(loadList,1000);
});
}
loadList();
});
Thanks for your help !
Your data comparison is not correct.
You are comapring this:
<li><a>JetBlue</a></li>
<li><a>Continental</a></li>
...
to this:
{
"id": "1",
"airline": "JetBlue",
"number": "222",
"people": "3",
"time": "12:20"
},
{
"id": "2",
"airline": "Continental",
"number": "222",
"people": "5",
"time": "23:21"
},
There will be always inequality.
You should use another approach. For example, if the id field from your JSON array is an unique one you can attach it to each item from the unordered list as an id attribute. For example:
newItems.push( "<li id=\"" + value.id + "\"><a>" + value.airline + "</a></li>" );
This way, at each iteration you can check if the incomming JSON item already exists into your list and add it when there is no match. Eg:
if (!$myList.find('#' + value.id).length) {
newItems.push( "<li id=\" + value.id + \"><a>" + value.airline + "</a></li>" );
}
Finally, you can append the newItems contents directly if there are items inside:
if (newItems.length > 0) {
$myList.append( newItems.join( "" ) );
}
Here is the edited snippet: JSBin

jQuery is not pulling data from a JSON and adding the data - What's wrong with my code?

I have a JSON file set up with data that, when a user on my site selects a music genre from a dropdown menu, songs of that music genre (the songs are stored in the JSON file, along with the artist) will be displayed in a combo box on my site. Sadly, this is not going according to plan.
I know that this error is based around some mistake that I am making, but I don't know where exactly! My browser's console is saying, "Uncaught TypeError: Cannot read property 'undefined' of undefined" on the following statement:
var selectedValue = dropDown.options[dropDown.selectedIndex].value;
However, I don't know what that means or if it's actually a legitimate runtime error. Anyways, here is my code. I would really appreciate it if you awesome people could look over my code and see what you think may be causing my code to not act in the way that I want to it to act (detailed in the first paragraph) :)
JSON
{
"library":
[
// ROCK
{
"title": "Your Love",
"artist": "The Outfield"
},
{
"title": "Voodoo Child",
"artist": "Jimi Hendrix"
},
{
"title": "When I'm Gone",
"artist": "Three Doors Down"
},
// ALTERNATIVE
{
"title": "Jumper",
"artist": "Third Eye Blind"
},
{
"title": "One Week",
"artist": "Barenaked Ladies"
},
{
"title": "The Middle",
"artist": "Jimmy Eat World"
}
]
}
JavaScript
$(document).ready(function()
{
// Declare our needed variables
var dropDown = $("#music-genre"); // <select id="music-genre">...</select>
var selectedValue = dropDown.options[dropDown.selectedIndex].value;
var target = $('#song'); // <select multiple id="song">...</select>
// If "Alternative" is chosen, choose the alternative songs
// I didn't add a conditional statement for choosing "Rock" because it's the same
if (selectedValue == "Alternative")
{
// "data/music.json" is the location of my JSON file
$.getJSON("data/music.json", function(data)
{
$.each(data, function(key, val)
{
target.innerHTML += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>';
}); // END $.each
}); // END $.getJSON
} // END if
}); // END ready()
HTML
<!-- Drop Down -->
<select id="music-genre">
<option id="rock" value="rock">Rock</option>
<option id="alternative" value="alternative">Alternative</option>
</select>
<!-- Combo Box -->
<select multiple id="song">
<!-- "Select one or more" is disabled because I don't want users selecting it -->
<option value="select" disabled>Select one or more</option>
</select>
Your the data you want from your returned JSON is in the library array, so you need to use data.library.
Also note that target will be a jQuery object which does not have a innerHTML property, so you need to use append instead:
$.each(data.library, function(key, val) {
target.append('<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>');
})
Finally as others mentioned you can use the val() property on a select element to get the selected value:
var selectedValue = $("#music-genre").val();
Try to use it like this:
JSON:
{
"library": {
"rock": [
{
"title": "Your Love",
"artist": "The Outfield"
},
{
"title": "Voodoo Child",
"artist": "Jimi Hendrix"
},
{
"title": "When I'm Gone",
"artist": "Three Doors Down"
}
],
"alternative": [
{
"title": "Jumper",
"artist": "Third Eye Blind"
},
{
"title": "One Week",
"artist": "Barenaked Ladies"
},
{
"title": "The Middle",
"artist": "Jimmy Eat World"
}
]
}
JAVASCRIPT:
$(function(){
// Declare our needed variables
var dropDown = $("#music-genre"); // <select id="music-genre">...</select>
// var selectedValue = dropDown.options[dropDown.selectedIndex].value;
var target = $('#song'); // <select multiple id="song">...</select>
dropDown.on("change", function(){
var genre = $(this).val();
var html = '';
$.getJSON("test.json", function(data){
$.each(data.library[genre], function(key, val){
html += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>'; // Save whole html in a var
}); // END $.each*/
target.html(html); // append it in target div
}); // END $.getJSON
});
}); // END ready()
Try to use:
var selectedValue = dropDown.find(':selected').val();
or:
var selectedValue = dropDown.val();
instead of:
var selectedValue = dropDown.options[dropDown.selectedIndex].value;
since dropDown is a jQuery object which required you to use jQuery method here.
Also note that data contains library array, so you need to access this array to get the value inside:
$.each(data.library, function(key, val) {
target.innerHTML += '<option value="' + val.title + '">' + val.title + 'by ' + val.artist + '</option>';
});

How to iterate a List of HashMap in jQuery [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I've a requirement where in I receive a List of HashMap from a database query and I've to display that on the JSP.
The JSON object looks like below:
[
{"UNIT_NM":"ATLANTA", "UNIT_CD":"A00"},
{"UNIT_NM":"ATLANTA CKO","UNIT_CD":"A00"},
{"UNIT_NM":"DALLAS", "UNIT_CD":"D00"},
{"UNIT_NM":"DALLAS CKO", "UNIT_CD":"D00"}
]
I've to display it in dropdown like:
"<option value='A00'> A00 ATLANTA</option>";
"<option value='A00'> A00 ATLANTA CKO</option>";
"<option value='D00'> D00 DALLAS</option>";
"<option value='D00'> D00 DALLAS CKO</option>";
The JS code is:
$.ajax({
url:indexContextRoot+"populateManualCsoCodes",
type:"post",
async:true,
success: function(data){
var listItems= "<option value=''>Please Select</option>";
$.each(data, function(key, value) {
listItems+= "<option value='" + key + "'>" + value + "</option>";
});
$("#manualCsoCodes").html(listItems);
}
});
I'm getting the dropdown as:
[object][Object]
[object][Object]
[object][Object]
[object][Object]
Any suggestions please!
The each() callback function has two parameters: 1) The index of the array element, and 2) The array element. So key is going to be 0, 1, 2, etc. and value is going to be the js object at that index position. So you need to do:
$.each(data, function(key, obj) {
var str = obj["UNIT_CD"];
listItems+= "<option value='" + str + "'>" + str + " " + obj["UNIT_NM"] + "</option>";
});
To make this a bit more modular and involve lesser HTML, here's my take on this :
var data = [
{
"UNIT_NM": "ATLANTA",
"UNIT_CD": "A00"
},
{
"UNIT_NM": "ATLANTA CKO",
"UNIT_CD": "A00"
},
{
"UNIT_NM": "DALLAS",
"UNIT_CD": "D00"
},
{
"UNIT_NM": "DALLAS CKO",
"UNIT_CD": "D00"
}
];
//init first option
var $option = $("<option/>", {
"value": '',
"html": "Please Select"
});
//add that to an array
var options = [$option];
//iterate over data
$.each(data, function (key, value) {
// value now contains a row eg., when key = 0, value = { "UNIT_NM": "ATLANTA", "UNIT_CD": "A00" }
//clone the default option, change the value and the HTML, then push into options array
options.push($option.clone().val(value.UNIT_CD).html(value.UNIT_CD + " " + value.UNIT_NM));
});
//add that array into select
$("#manualCsoCodes").html(options);
The idea is to create an options array, which fills up with jQuery objects with tag name option and then place that in the select tag. Here's a demo
Oh, before i forget, each iterates row-wise. So, in any iteration of each, you'll get a row of data. For example,
if key === 2, then value === {
"UNIT_NM": "DALLAS",
"UNIT_CD": "D00"
}
So, to access UNIT_NM & UNIT_CD, you'll have to use value.UNIT_NM & value.UNIT_CD respectively. For more info on each, see docs.
Hope that helps!
listItems+= "<option value='" + value.UNIT_CD + "'>" + value.UNIT_CD + " " + value.UNIT_NM + "</option>";
PS: you could do that yourself if you used console.log(value);

Categories

Resources