Create an horizontal description list from a json object - javascript

The structure I plan to have is an horizontal description list like
key key2 ...
value value2 ...
My code is:
html:
<dl class="horizonal_list">
<dt>Key</dt>
<dd>Value</dd>
</dl>
<dl class="horizonal_list">
<dt>Another key</dt>
<dd>Another value</dd>
</dl>
...
css:
dt, dd {
margin-left: 15px;
margin-right: 15px;
text-align:center;
}
.horizonal_list {
float: left;
}
Basically, I'd like to show into the above horizontal list some information retrieved from the server and then sent to a JSON object, like the following:
var current_status = {"REFERENCE":"1000006",
"NUMBER":108,
"DESCRIPTION":"SC1B",
"CONFIRMATION":"155248",
"CREATION_DATE":15584,
"YEAR":2013,
"NDOQ":161,
"NEZC":"161",
"STATUS":"LI"};
But, I'm very new to web dev and I'd like some tips. Thanks.

You can loop through each property in your object, and then add a new <dl> element for each key/value pair.
NOTE that this example JQuery for appending the html to the DOM.
function addItem(key, value) {
$("div").append('<dl class="horizonal_list"><dt>' + key + '</dt><dd>' + value + '</dd></dl>');
}
for (var key in current_status) {
addItem(key, current_status[key]);
}
Here is a working example
In the example above, <div> has been used to represent an empty container that each <dl> element will be added to. This may be different from what you current have so you will need to change that accordingly.
If you are going to be calling this function more than once you will want to clear the <div> element each time before you populate it:
$("div").empty();
Here is a more realistic example, which shows how to update the data on demand

Related

Why nested array dynamic update is not working in my case

Hi i have a problem with nested array dynamic update as shown in below image
Here is a steps to re-produce the problem
click on Add Likes button it will add likes for eg New Apple
my default like is Mango
click on Add about button it will add next row (Mango is not appeared) click on Add Likes to see the problem.
For reducing code readability i have put helper function into a mixin file called mixin.js
Expectation: i can add any number of Add about and Add Likes(with default value Mango)
Here is my code: https://codesandbox.io/s/musing-hawking-di4d3?file=/src/App.vue
First, you don't need a nested array for the tags property.
Use:
getLikesTemplate() {
let year = this.year;
let template = {
id: this.getUniqueId(),
like: `I'm ${year} Old and like things like`,
tags: [this.getTagsTemplate("Mango")] //nesting removed
};
this.year++;
return template;
}
Secondly, in JS objects are passed by reference, so you can do this:
method:
addLikes(like) { //removed the extra code
like.tags.push(this.getTagsTemplate("New Apple"));
},
template:
...
<div style="text-align: left; display: flex">
<div> //nesting removed
<div class="tags" v-for="tag in like.tags" :key="tag.id">
{{ tag.name }}
</div>
</div> //passing the reference to the object
<button style="margin-left: 20px" #click="addLikes(like)">
Add Likes
</button>
</div>
Result img

How to update some portion of a td title jquery

on ajax success, I have to update some portion of the title.
I am extracting the current td title as:
//with this I could get the current td title
let tdTitle = $('.amenity-review-table').find("td[data-unitid='"+resp.unit.id+"']").attr('title');
and consoling this tdTitle gives:
<div class='unit-title'><strong>Unit: 101</strong></div><span class=''>Washer/Dryer = <span>1</span></span></br><div class='sm-box unit-note-color d-inline-block'></div><span class='unit-note-popup'>note added 3</span>
Now, on ajax success I will receive the new updated title and this can be accessed via:
resp.unit.unit_note, now once I receive the update I have to update the note shown on the title of td. So, in above case:
I have to update the text inside unit-note-popup class to new note which could be received on resp.unit.note. So the final title looks like:
<div class='unit-title'><strong>Unit: 101</strong></div><span class=''>Washer/Dryer = <span>1</span></span></br><div class='sm-box unit-note-color d-inline-block'></div><span class='unit-note-popup'>"+resp.unit.unit_note+"</span> //my syntax could be wrong here, but this is what I needed
Update:
Here, is the jsfiddle to reproduce the scenario:
http://jsfiddle.net/a3t7yfe2/1/
You'll need to parse the HTML in the title attribute into something you can work with (like a jQuery object).
Then you can manipulate the .unit-note-popup text and write the HTML back into the attribute
// Mock data
const resp = {
unit: {
id: 1,
note: "Note added 4!"
}
}
const td = $(`.amenity-review-table td[data-unitid="${resp.unit.id}"]`)
const title = td.attr("title")
const titleEl = $(`<div>${title}</div>`) // parse into an element
titleEl.find(".unit-note-popup").text(resp.unit.note)
td.attr("title", titleEl.html())
/* Make the title attribute visible */
td[data-unitid]:after {
display: block;
color: red;
content: attr(title);
margin: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="amenity-review-table">
<tr>
<td data-unitid="1" title="<div class='unit-title'><strong>Unit: 101</strong></div><span class=''>Washer/Dryer = <span>1</span></span><br/><div class='sm-box unit-note-color d-inline-block'></div><span class='unit-note-popup'>note added 3</span>">
Check out my super awesome HTML title
</td>
</tr>
</table>
Here I've wrapped the title HTML text in a <div> so that it's encapsulated in a single parent element. That way, you can get the inner HTML back for writing the new value.

Repeating appended html with json data included

This is a bit of a learning exercise for me so please excuse the code I am about to present. I am sure it could be better. In the following code you will see that I have successfully created a variable that is pulling in properly formatted JSON data. I am then, creating a function that appends a block of html. Within that append, I am referencing specific pieces of JSON data to be displayed.
HTML
<table id="jobSearchResults" bgcolor="white" style="border: 1px solid #ddd;width:100%;">
<tbody>
</tbody>
</table>
Javascript
var json = (function () {
var json = null;
$.ajax({
'async': false,
'global': false,
'url': "../data/jobSearchResults.json",
'dataType': "json",
'success': function (data) {
json = data;
}
});
return json;
})();
$(jobSearchResults).each(function(index, element){
$('#jobSearchResults').append('<tr><th><div style="background-color:#ddd;height:55px;width:80px;"><img src="" style="height:55px;width:80px;"></div></th><td><h4 style="margin-top: 0;margin-bottom: 2px;font-size: 16px;"> '+json[0].job_header+' </h4> '+json[0].specialty_name+', '+json[0].facility_name+' </td><td><h4 style="margin-top: 0;margin-bottom: 2px;font-size: 16px;"> '+json[0].city+', '+json[0].state_name+' </h4> United States </td><td class="text-right"></td></tr>');
});
Now, I need to complicate matters by making that table row repeat X number of times and have the JSON record number increment with each new row. In this case, I am both interested in how to take what I have written and expand on it to include this new functionality and I am also interested in what a more concise way to approach this problem would have been had I written this more efficiently.
The callback function for jQuery's each is passed two values. They represent the index and value of the current iteration, respectively. You can use either of these to reference your original JSON data and output each row accordingly.
The $.each() function can be used to iterate over any collection, whether it is an object or an array. In the case of an array, the callback is passed an array index and a corresponding array value each time.
$.each( obj, function( key, value ) {
alert( key + ": " + value );
});
In my example below, I'm iterating over the json variable, which contains the JSON data returned from your AJAX call. In this context, you could use the index to reference the current iteration (e.g. json[index].job_header) or use the value directly (e.g. job.job_header).
function displayData(json) {
var $resultDisplay = jQuery('#jobSearchResults tbody');
if (!json) {
// variable is false. there was an ajax error.
$resultDisplay.html('<tr><td>There was an error.</td></tr>');
} else if (jQuery.isEmptyObject(json)) {
// variable is an empty object. no records were returned.
$resultDisplay.html('<tr><td>No data to display.</td></tr>');
} else {
// display the returned records.
$resultDisplay.empty();
jQuery.each(json, function(index, job) {
$resultDisplay.append('<tr>' +
'<td><div class="row-img"><img src="" alt=""></div></td>' +
'<td><h4>' + job.job_header + '</h4>' + job.specialty_name + ', ' + job.facility_name + '</td>' +
'<td><h4>' + job.city + ', ' + job.state_name + ' </h4>United States</td>' +
'</tr>');
});
}
}
jQuery.ajax({
'url': "https://epearson001.github.io/prototype-web-application/assets/data/jobSearchResults.json",
'dataType': "json"
})
.done(function(data) {
displayData(data);
})
.fail(function() {
displayData(false);
});
#jobSearchResults {
border: 1px solid #ddd;
width: 100%;
background-color: white;
}
div.row-img {
background-color: #ddd;
height: 55px;
width: 80px;
}
div.row-img img {
height: 55px;
width: 80px;
}
h4 {
margin-top: 0;
margin-bottom: 2px;
font-size: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="jobSearchResults">
<tbody>
<tr>
<td>Loading data...</td>
</tr>
</tbody>
</table>
Edit
I also notice that you're setting async to false in your AJAX call. This defeats the asynchronous functionality of AJAX and, unless there's a particular reason to do so, I advise against it. I've restructured my example to use a callback function, so that data will be displayed after it is returned from your asynchronous AJAX call. I also added a bit of error handling. I acknowledge that this might not be appropriate for your particular context, but I thought I'd offer the idea.
The answer given definitely shows the right way to do what you're asking. But I would've approached this differently if you are controlling the server as well. Instead of sending JSON data back, I'd send formatted HTML back and use:
$('#jobSearchResults tbody').load('../data/jobSearchResults/')

Accessing html elements from a div tree with javascript

I need to access title value from some img elements but these elements are deeply implemented in a div tree and after that into some tables.
Let me explain why I need them:
I use a portal where I have information regarding circuits from a network. This portal contains some locations with a few rows (2-3 usually -> circuits for that location). Each row starts with an img element and it can have a few values on title attribute. If the title value is != "No alarms" then I have to take all data from that row and I want to show them via a pop up notification on the bottom right corner near clock.
Below you have a screenshot for how are the html elements organized (for all locations).
http://imageshack.com/a/img661/962/ErjQOt.png
Below you have a screenshot for how is a location organized:
http://imageshack.com/a/img661/7453/QAP5oM.png
If title attribute == "Warning", for example, I have to take the data from the next td's in the same table. Each td has another div without id. Firsts 2 td's on each table have another element inside div: img on first one and a href on the second one.
I'm drawing the tree to show you exactly how are the html elements organized.
<table class="x-grid3-row-table">
<tbody>
<tr>
<td> <!--first td, this contains div->img-->
<div class="x-grid3-cell-inner x-grid3-col-0">
<img .... title="No alarms">
</div>
</td>
<td> <!--second td, this contains div->a href-->
<div class="x-grid3-cell-inner x-grid3-col-1">
<a href...>
</div>
</td>
<td> <!--3rd td, this contains div->string:Text1-->
<div class="x-grid3-cell-inner x-grid3-col-2">Text1</div>
</td>
<td> <!--4th td, this contains div->string:Text2-->
<div class="x-grid3-cell-inner x-grid3-col-2">Text2</div>
</td>
...
</tr>
</table>
Location-1 has 3 circuits, this means 3 tables. The above table is inserted in a div (div class="x-grid3-row x-grid3-row-first" from screenshot2). There are 2 more tables after this one on another div's (div class="x-grid3-row x-grid3-row-alt" & div class="x-grid3-row" from screenshot2) and I have to check the title attribute for each table.
Now my question is how to get the title attribute from each table on the same location? and if the title is != "No alarms" how can I get data from the next td's in that table?
Maybe I can use a loop for all 12 locations or maybe I can get them one by one. This is no big deal because there are only 12 locations but the nasty thing is inside each location to get info from each circuit.
I think there should be a syntax like this to reach each html elements and to get the right value.
var title = $('#ext-gen15-gp-location-1-bd table[0] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-1-bd table[0] td[1] div[0]').attr('innerHTML');
....
var title = $('#ext-gen15-gp-location-1-bd table[1] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-1-bd table[1] td[1] div[0]').attr('innerHTML');
...
var title = $('#ext-gen15-gp-location-9-bd table[0] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-9-bd table[0] td[1] div[0]').attr('innerHTML');
...
...and so on. I'm sure that this syntax is not correct but I think there should be a way to get that data.
I hope that now is explained better then the first time.
EDIT
Guys, thank you very much. You help me a lot. Your codes are working.
Anyway, I just want to ask you something else.
After 3 minutes the whole table is refreshing and I can't find a way to reload the function after that. When the content is refreshing, div ext-gen24 remains empty and after that is refilled with the content:
When is refreshing:
<div class="x-grid3-body" style="width: 1877px;" id="ext-gen24"></div>
After refresh is completed
<div class="x-grid3-body" style="width: 1877px;" id="ext-gen24">content</div>
Can you help me with a function you think it should work in this case ?
You'll need loop through multiple stages of the html: groups, tables, and columns:
var groups = $('.x-grid-group-body'); //hopefully all the '#ext-gen15-gp-location-X-bd' div have 'x-grid-group-body' as the class
groups.each(function () {
var tables = $(this).find('table');
tables.each(function () {
var columns = $(this).find('td');
var image = $(columns[0]).find('img');
var title = image.attr('title');
if (title !== 'No alarms') {
var allInnerHtml = '';
for (var i = 1; i < columns.length; i++) {
allInnerHtml += $(columns[i]).find('div').html() + '\n';
}
alert(allInnerHtml);
}
else {
//just to show that titles with 'No alarm' are skipped
alert('skipped');
}
});
});
See updated JSFiddle
Hope that helps! =)
If your Div tree has classes in the same format is now you can use something like this.
var title = $('.x-panel-bwrap').find('img').attr('title');
Or if the div class dependency is not confirmed, then assuming that img tag will always have a class name starting with 'tick', you can use this.
var title = $('img *[class^="tick"]').attr('title');
EDIT
Now that you have explained your problem more clearly, i've included a fiddle with the solution you need. Now you will have to expand it to suit your code more closely.
For example if you want to log each location separately, start looping through the locations first and then find tables inside them.
Basically you can use Jquery .find and .each to go through your comeplete html and do whetever you want.
var tableList = $('.x-grid3-row-table');
tableList.each(function() {
var imgTitle = $(this).find('img').attr('title');
alert(imgTitle);
if (imgTitle == 'Warning') {
infoTd = $(this).find('td:nth-child(3)');
text = infoTd.find('div').text();
alert(text);
}
});
FIDDLE

Process data-attributes: how to seralize

I'm trying to create and HTML chart with a jquery plugin and I'm using HTML5 data attributes to pass data from my rails app to jquery function.
My html, after the ruby hash conversion, is something like this:
<div class="chart" data-contents-01="0" data-contents-02="1" data-contents-03="3" data-contents-04="0" data-contents-05="0" data-contents-06="0" data-contents-07="0" data-contents-08="0" data-contents-09="0" data-contents-10="0" data-contents-11="0" data-contents-12="0" data-contents-13="0" data-contents-14="0" data-contents-15="0" data-contents-16="0" data-contents-17="0" data-contents-18="0" data-contents-19="0" data-contents-20="0" data-contents-21="0" data-contents-22="0" data-contents-23="2" data-contents-24="1" data-contents-25="4" data-contents-26="0" data-contents-27="0" data-contents-28="0" data-contents-29="2" data-contents-30="2" data-contents-31="0" id="chart_2" style="padding: 0px; position: relative;">
I have a lot if data-contents-xx and I must convert this data to an array of array.
My function take data as:
var contents = [
[x, y],
[x,y]
];
so I must process my data attributes to have an array of array, where each sub-array is a couple of data-contents-x
How can i serialize my data attribute?
The JQuery method .data() will pull all data objects into an array of key: value pairs. With your element names:
$('.chart').data();
For example, given:
<div class="chart" data-foo="1" data-bar="2"></div>
Use:
var data = $('.chart').data();
for(var i in data){
console.log("data attribute - " + i + ":" + data[i]);
}
Here's the fiddle: http://jsfiddle.net/WVfSg/260/
When playing with your code in the fiddle, it doesn't work. However, when I get rid of the second hyphen, it works as expected.

Categories