How to insert data into the DOM using JavaScript - javascript

I have this code in JS. Please tell me how i can increment a piece of this code so that articles are automatically inserted into HTML.
It is necessary that the data index [0] is incremented for example data [0], data [1], data [2] and beyond. title, author, content vary depending on the index number.Thanks!
document.querySelector(".title").textContent = data[1]["title"];
document.querySelector(".author").textContent = data[1]["author"]["username"];
document.querySelector(".content").textContent = data[1]["content"];
fetch("https://any-site/articles")
.then(function(resp) {
return resp.json();
})
.then(function(data) {
console.log(data);
document.querySelector(".title").textContent = data[1]["title"];
document.querySelector(".author").textContent = data[1]["author"]["username"];
document.querySelector(".content").textContent = data[1]["content"];
})
.catch(function() {
//catch any errors
});
// ---------- JSON on SITE ----------
[
{
"id": 1,
"title": "Some title",
"content": "Some content",
"author": {
"id": 1,
"username": "Leo",
},
},
{
"id": 2,
"title": "Some title2",
"content": "Some content2",
"author": {
"id": 2,
"username": "Vernon",
},
},
{
"id": 3,
"title": "Some title3",
"content": "Some content3",
"author": {
"id": 2,
"username": "Vernon",
},
},
]
<body>
<h1>News</h1>
<h2 class="title"></h2>
<h5 class="author"></h5>
<p class="content"></p>
</body>
<script src="data.js"></script>

The easiest method I've found is to map over the data and produce some HTML using a template literal, and then insert that into the document body with insertAdjacentHTML.
const data = [{"id":1,"title":"Some title","content":"Some content","author":{"id":1,"username":"Leo"}},{"id":2,"title":"Some title2","content":"Some content2","author":{"id":2,"username":"Vernon"}},{"id":3,"title":"Some title3","content":"Some content3","author":{"id":2,"username":"Vernon"}}];
function getHTML(data) {
// Iterate over the array of objects
return data.map((block) => {
// Destructure the title, author username, and content
// from the object
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
const { title, author: { username }, content } = block;
// For each object return those variables
// in a template literal
return `
<div class="block">
<p class="title">${title}</p>
<p class="author">${username}</p>
<p class="content">${content}</p>
</div>
`;
// `map` returns an array of information so make
// you join it up into one string of data
}).join('');
}
// Call the `getHTML` function with the data and insert
// it on the element you want
document.body.insertAdjacentHTML('beforeend', getHTML(data));
.block {
border: 1px solid #454545;
margin: 0.5em 0 0.5em 0;
padding: 0.5em;
}
.title { text-decoration: underline; }
.author { color: blue; }
<body>
<h1>News</h1>
</body>

Related

sort the Json data According to timestamp in Vuejs

I am rending a Json using api
new window.Vue({
el: '#containerwrapper',
data() {
return {
bannerData:""
}
},
created() {
axios.get('http://localhost:8080/pi.json')
.then(response => {
this.bannerData = response.data;
});
},
})
This gives me the Json data as follows
[
{
"id": 118,
"title": "Feuerwerk",
"location": "MUC",
"pressInformation": [
{
"id": 215,
"tstamp": "1577110478",
"created": "2019-09-10T12:13:53+02:00",
"title": "Chemi215",
"teaser": "",
"subline": "Ursachenforschung dauert"
}
]
},
{
"id": 144,
"title": "Testing Stage",
"location": "BER",
"pressInformation": [
{
"id": 254,
"tstamp": "1576838212",
"created": "2019-11-27T13:47:31+01:00",
"title": "Chemi254",
"teaser": "",
"subline": ""
},
{
"id": 250,
"tstamp": "1576838221",
"created": "2019-12-09T12:36:36+01:00",
"title": "Chemi250",
"teaser": "",
"subline": ""
}
]
}
]
I render the data in my template as follows
<div v-for="(eventTitle, i) in bannerData">
<div v-for="(title,index) in eventTitle.pressInformation" :key="title.id">
<div id="pressTimeStamp">{{title.created}} Uhr</div>
<div id="pressTitleTitle">{{title.title}}</div>
<div id="pressTitle">
<h2>{{eventTitle.title}}</h2>
<div id="pressSubline">{{title.subline}}</div>
</div>
</div>
And the output is coming as i expected. Can someone suggest me, how to write a method so my output would be sorted out depends on the 'created' timestamp
new window.Vue({
el: '#containerwrapper',
data() {
return {
bannerData:""
}
},
created() {
axios.get('http://localhost:8080/pi.json')
.then(response => {
response.data.pressInformation.sort(function(a, b){return b['tstamp']-a['tstamp']}));
this.bannerData = response.data;
});
},
})
You can use the sort method with a callback function.
From your data it seems that you already have the timestamp in seconds. It is easy so sort using that.
For example you can write something like this:
arr.sort(function(a, b) {
return +a.pressInformation.tstamp - +b.pressInformation.tstamp;
});
If you are writing a-b denotes ascending order, while b-a is descending order.
The extra + signs are used here to convert from string to int.
Docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Loop through json array with objects

I´ve got an array in this format:
var items = [{
"link": {
"0": "http://www.example.com/"
},
"title": {
"0": "example"
}
}, {
"link": {
"0": "http://www.example2.com"
},
"title": {
"0": "example2"
}
}]
I can´t figure out how to loop through it and display its values in HTML.
Im using jquery and have tried using an each-loop:
$.each( items, function(i, item) {
console.log(item); // Uncaught TypeError: Cannot use 'in' operator to search for '6271' in
})
Help appreciated. Thanks!
EDIT:
Your code works in the example i posted above. I will accept asasp.
I noticed however that the real json im trying to loop is not always properly formatted which leads to a crash:
var items = [{
"link": {
"0": "http://www.example.com/"
},
"title": {
"0": "example"
}
}, {
"link": {
"0": "http://www.example2.com"
},
"title": {
"0": "example2: "
some text here ""
}
}]
When looping this array i get:
Uncaught SyntaxError: Unexpected identifier
Is there a way to maybe skip all "broken" objects?
Here you go with a solution
var items = [{
"link": {
"0": "http://www.example.com/"
},
"title": {
"0": "example"
}
}, {
"link": {
"0": "http://www.example2.com"
},
"title": {
"0": "example2"
}
}];
$.each( items, function(i, item) {
$("body").append(`<span class="title">${item.title["0"]}:</span> <span>${item.link["0"]}</span><br/>`);
});
.title {
font-weight: bold;
font-size: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Each item is an object, to get the link value I've provided in the solution.
Fast and dirty:
for (item of items) {
console.log(item.link[0])
console.log(item.title[0])
}

VueJS filter doesn't work in v-for

I have an error on VueJS with a filter added in a v-for from an Axios response and doesn't understand how to solve it. The filter set_marked return a undefined value if i made a console.log on the value variable.
Here's the HTML:
<main id="app">
<div v-for="item in productList" :key="item.id">
<header>
<h2>{{ item.title }}</h2>
</header>
<article class="product-card">
{{ item.content | set_marked }}
</article>
</div>
</main>
And the Javascript:
var app = new Vue({
el: '#app',
data: {
loading: false,
loaded: false,
productList: []
},
created: function() {
this.loading = true;
this.getPostsViaREST();
},
filters: {
set_marked: function(value) {
return marked(value);
}
},
methods: {
getPostsViaREST: function() {
axios.get("https://cdn.contentful.com/spaces/itrxz5hv6y21/environments/master/entries/1Lv0RTu6v60uwu0w2g2ggM?access_token=a2db6d0bc4221793fc97ff393e541f39db5a65002beef0061adc607ae959abde")
.then(response => {
this.productList = response.data;
});
}
}
})
You can also try it on my codepen:
https://codepen.io/bhenbe/pen/deYRpg/
Thank you for your help !
You are iterating with v-for on productList, but in your code productList is not an array but an object (a dictionary in other words). In fact if you look at it, it has this structure:
{
"sys": {
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "itrxz5hv6y21"
}
},
"id": "1Lv0RTu6v60uwu0w2g2ggM",
"type": "Entry",
"createdAt": "2017-01-22T18:24:49.677Z",
"updatedAt": "2017-01-22T18:24:49.677Z",
"environment": {
"sys": {
"id": "master",
"type": "Link",
"linkType": "Environment"
}
},
"revision": 1,
"contentType": {
"sys": {
"type": "Link",
"linkType": "ContentType",
"id": "page"
}
},
"locale": "fr-BE"
},
"fields": {
"title": "Retour sur douze années de design",
"content": "Douze années ... vie."
}
}
Iterating through it, on the first iteration will assign to item the value of the "sys" key, which is:
{
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "itrxz5hv6y21"
}
},
"id": "1Lv0RTu6v60uwu0w2g2ggM",
"type": "Entry",
...
"locale": "fr-BE"
},
and on the second iteration the value of the "fields" key, which has the value:
{
"title": "Retour sur douze années de design",
"content": "Douze années ... vie."
}
Since you are accessing item.title and item.content, and title and content keys are not present in the first object, but only in the second, in the first iteration they will be undefined. So, in the first iteration you are passing undefined as the value of item.content to the set_marked filter.
productList is the response to the GET request, which as we have seen is not returning an array but an object.
If you add to the filter the check if (!value) return ''; it will work, but you are just hiding the problem of the discrepancy between what the API returns and what you are expecting.
If you build productList as an array by filtering through the sub-objects of result.data and keeping only those containing title and contents fields, it works:
function marked(value) {
return value.toUpperCase();
}
var app = new Vue({
el: '#app',
data: {
productList: []
},
created: function() {
this.loading = true;
this.getPostsViaREST();
},
filters: {
set_marked: function(value) {
// console.log(value);
return marked(value);
}
},
methods: {
getPostsViaREST: function() {
axios.get("https://cdn.contentful.com/spaces/itrxz5hv6y21/environments/master/entries/1Lv0RTu6v60uwu0w2g2ggM?access_token=a2db6d0bc4221793fc97ff393e541f39db5a65002beef0061adc607ae959abde")
.then(response => {
// this.productList = response.data;
let data = response.data;
let productList = [], key;
for (key in data) {
let val = data[key];
if ((val.title !== undefined) && (val.content !== undefined)) {
productList.push(val);
}
}
this.productList = productList;
});
}
}
})
#import url('https://fonts.googleapis.com/css?family=Lato');
body{
font-family: 'Lato', sans-serif;
font-size: 1.125rem;
}
#app > div{
max-width: 68ch;
margin: 0 auto;
}
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<main id="app">
<div v-for="item in productList" :key="item.id">
<header>
<h1>{{ item.title }}</h1>
</header>
<article class="product-card" v-html="$options.filters.set_marked(item.content)"></article>
</div>
</main>
Ok, i find in the documentation the solution.
I must add the following code to the filter set_marked to work properly:
if (!value) return '';
value = value.toString();
I currently don't know why this additional lines are required.
I had a second problem because the returned html is escaped by VueJS.
The easiest way to avoid this issue is to used the v-html directive.
To apply a filter in the v-html directive, you must use this syntax :
v-html="$options.filters.set_marked(item.content)"
You can find my pen here : https://codepen.io/bhenbe/pen/deYRpg
Usually I just create a method when I need filtering and then use it when needed in my component.
ie:
methods: {
getPostsViaREST: function() {
axios.get("https://cdn.contentful.com/spaces/itrxz5hv6y21/environments/master/entries/1Lv0RTu6v60uwu0w2g2ggM?access_token=a2db6d0bc4221793fc97ff393e541f39db5a65002beef0061adc607ae959abde")
.then(response => {
this.productList = response.data;
});
},
filterPost(post) {
return _.toUpper(post);
}
}
And then in your component:
<h1>{{ filterPost(item.title) }}</h1>
Find here the full example:
https://codepen.io/Venomzzz/pen/mLrQVm?editors=1011

Parse HTML into a specific JSON object

How can I create a specific JSON object from some HTML?
Example
This is very well formatted HTML page (rendered from markdown). I want to create a JSON representation of the sections on the page.
So each "h2" is a title. Each h3, h4, or h5, that follows it is a subtitle
Given this HTML:
<h2>Charts</h2>
<ul>...</ul>
<h5>Third Party</h5>
<ul>...</ul>
<h5>Reusable Chart Frameworks</h5>
<ul>...</ul>
<h2>Maps</h2>
<h5><a href="#third-party-1">Third Party</h5>
...
Return this JSON:
[
{
"title": {
"text": "Charts",
"href": "#charts"
}
"subtitles": [
{
"text": "Third Party",
"href": "#third-party"
},
{
"text": "Reusable Chart Frameworks",
"href": "#reusable-chart-frameworks"
}
]
},
{
"title": {
"text": "Maps",
"href": "#maps"
},
"subtitles": ]
"text": "Third Party",
"href": "#third-party-1"
]
},
...
]
Solutions I've considered
Seems like something jQuery could help a lot with. If the items were nested it would be very easy to do $('h2').each(...) and just loop through each section, appending it to my JSON object. However there is no nesting here, just siblings. Any ideas?
One other solution is to map it:
var mappedJSON = $('h2').map(function() {
var $selfA = $(this).children('a');
var subtiles = $(this).nextUntil('h2').filter(':header').children('a').map(function() {
return {
"text": $(this).text(),
"href": $(this).attr('href')
}
}).get();
return {
"title": {
"text": $selfA.text(),
"href": $selfA.attr('href')
},
"subtitles": subtiles
};
}).get();
console.log(mappedJSON);
$('<pre/>').appendTo($('body').empty()).text(JSON.stringify(mappedJSON, null, "\t"));
pre {
tab-size: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h2>Charts</h2>
<ul>...</ul>
<h5>Third Party</h5>
<ul>...</ul>
<h5>Reusable Chart Frameworks</h5>
<ul>...</ul>
<h2>Maps</h2>
<h5><a href="#third-party-1">Third Party</h5>
Here's a solution that just relies on jQuery's .nextUntil() function.
var sections = [];
var eTitles = $('article').find('h2');
$(eTitles).each(function(){
var section = {
"title": {
"text": $(this).text(),
"href": $(this).find('a').attr('href')
},
"subtitles": []
}
var eSubtitles = $(this).nextUntil('h2').filter('h3, h4, h5');
$(eSubtitles).each(function(){
var subtitle = {
"text": $(this).text(),
"href": $(this).find('a').attr('href')
}
section.subtitles.push(subtitle);
});
sections.push(section);
});

Filtering JSON data

I have a JSON file which contains data like the following:
{"posts": [
{ "title":"1", "url":"n1.png" },
{ "title":"2", "url":"n2.png" },
{ "title":"3", "url":"n3.png" },
{ "title":"4", "url":"n4.png" },
{ "title":"5", "url":"n5.png" },
{ "title":"6", "url":"n6.png" },
{ "title":"7", "url":"n7.png" },
{ "title":"8", "url":"n8.png" },
{ "title":"9", "url":"n9.png" },
{ "title":"10", "url":"n10.png" }
]}
I need to filter title by range with two text boxes: from and to.
Why not do this?
var json = JSON.parse('{"posts": [
{ "title":"1", "url":"n1.png" },
{ "title":"2", "url":"n2.png" },
{ "title":"3", "url":"n3.png" },
{ "title":"4", "url":"n4.png" },
{ "title":"5", "url":"n5.png" },
{ "title":"6", "url":"n6.png" },
{ "title":"7", "url":"n7.png" },
{ "title":"8", "url":"n8.png" },
{ "title":"9", "url":"n9.png" },
{ "title":"10", "url":"n10.png" }
]}');
var filteredJson = json.posts.filter(function (row) {
if(row.title matches your criteria) {
return true
} else {
return false;
}
});
Yes, its an ES5 method but that can be shimmed quite nicely
I use Linq JS on my current project and it works really well for filtering data.
http://jslinq.codeplex.com/
var posts = [
{ "title":"1", "url":"n1.png" },
{ "title":"2", "url":"n2.png" },
{ "title":"3", "url":"n3.png" },
{ "title":"4", "url":"n4.png" },
{ "title":"5", "url":"n5.png" },
{ "title":"6", "url":"n6.png" },
{ "title":"7", "url":"n7.png" },
{ "title":"8", "url":"n8.png" },
{ "title":"9", "url":"n9.png" },
{ "title":"10", "url":"n10.png" }
];
var filteredPost = JSLINQ(posts)
.Where(function(item){ return item.title >= "textBox1Value" && item.title <= "textBox2Value"; });
There is another solution to this: using jLinq.js (documentation), which has even more features. In this case, you can get the solution by using the following code:
var selectedPosts = jLinq.from(posts)
.betweenEquals("title",4,8)
.select();
try this
var q = new RegExp(req.query.q,'i');
posts = posts.filter(function(item){
if(item.title.match(q) || item.url.match(q)){
return item;
}
});
Read the json into an object/arr the parseJson function of jquery(http://api.jquery.com/jQuery.parseJSON/) and the try to splice the array using the splice function() Just make a copy of the object and splice that one.
Well i have this JSON array full of projects, each of project belong to a product:
[
{
"id": 1,
"parentProduct": {
"id": 12,
"productName": "Test 123"
},
"phase": "Phase 4",
"productNumber": "111223",
"projectName": "Test JPEG Apple",
"supplier1": "de",
},
{
"id": 2,
"parentProduct": {
"id": 12,
"productName": "Test from me"
},
"phase": "222",
"productNumber": "11122",
"projectName": "Test PNG",
"supplier1": "222"
}
]
I wanted to get only those with specific parent id, and i did it as below:
filterByProductId(projects, productId) : any[] {
var filteredArray = new Array;
for(var k in projects) {
if(projects[k].parentProduct.id == productId) {
filteredArray.push(projects[k]);
}
}
return filteredArray;
}
json data array of objects filter
<html>
<head>
<script type="text/javascript">
/*
var ss = JOSN.stringify(obj,function(key,value){ //serialization
if(key=='a'){
return undefined;
}else{
return value;
}
});
*/
var jsonStr = [
{
"name": "Bang Bang",
"outline": "A chance encounter with a mysterious charmer leads to a bank employee's wild adventure.",
"rating": 5.6,
"director": "Siddharth Anand",
"id": 250
},
{
"name": "Bang Bang",
"outline": "A chance encounter with a mysterious charmer leads to a bank employee's wild adventure.",
"rating": 5.6,
"director": "Siddharth Anand",
"id": 250
},
{
"name": "Bang Bang",
"outline": "A chance encounter with a mysterious charmer leads to a bank employee's wild adventure.",
"rating": 5.6,
"director": "Siddharth Anand",
"id": 250
},
{
"name": "Indian",
"outline": "After his daughter's tragic death, a freedom fighter steps up his war against corruption.",
"rating": 8.4,
"director": "Shankar",
"id": 251
},
{
"name": "Dilwale Dulhania Le Jayenge",
"outline": "Raj and Simran meet on a trip to Europe. After some initial misadventures, they fall in love. The battle begins to win over two traditional families.",
"rating": 8.4,
"director": "Aditya Chopra",
"id": 253
}
];
var jsonobj = jsonStr;
function filterMovieDirectorData(movie,director){
if(movie!='' && (director!='' && director!='Director')){
var data = jsonobj.filter(function(item){
return (item["name"].toLowerCase().indexOf(movie.toLowerCase())!=-1 && item["director"].toLowerCase().indexOf(director.toLowerCase())!=-1)
});
}else if(movie!='' && director=='Director'){
var data = jsonobj.filter(function(item){
return item["name"].toLowerCase().indexOf(movie.toLowerCase())!=-1
});
}else if(movie=='' && (director!='' && director!='Director')){
var data = jsonobj.filter(function(item){
return item["director"].toLowerCase().indexOf(director.toLowerCase())!=-1
});
}
return data;
}
function getFilterDirectorJson(){
var inputStr = document.getElementById("movie").value;
var e = document.getElementById("director");
var directorStr = e.options[e.selectedIndex].text;
if( (inputStr=='' || inputStr=='Enter movie name') && (directorStr=='' || directorStr=='Director') ){
alert("Please enter movie name or select director.");
document.getElementById("filter_data_div").innerHTML="";
document.getElementById("movie").focus();
return false;
}
var filterObjs = filterMovieDirectorData(inputStr,directorStr);
var text="";
for(var i=0; i<filterObjs.length; i++){
text+='<div id="filter_data"><div><h3>'+filterObjs[0].name+'</h3></div>';
text+='<div>Director : '+filterObjs[0].director+'</div></div><div class="clear"></div>';
}
if(filterObjs.length===0){document.getElementById("filter_data_div").innerHTML='<div id="filter_data"><div><h3>No movies found.</h3></div></div>';}else
document.getElementById("filter_data_div").innerHTML=text;
}
window.onload=function(){
getDirectors();
}
function getDirectors(){
for(var i=0; i<jsonobj.length; i++){
//console.log(jsonobj[i].director);
var option = document.createElement("option");
option.text = jsonobj[i].director;
option.value = i;
var daySelect = document.getElementById('director');
daySelect.appendChild(option);
}
}
</script>
<style>
#director{
line-height: 3px;
padding: 20px;
font-size: 21px;
color: #acacac;
}
#go{
background: #FFC000;
padding: 11px 14px 16px 11px;
font-size: 36px;
line-height: 3;
color: #fff;
margin: 0px;
text-align: center;
}
#movie{
width: 213px;
font-size: 21px;
margin-left: 12px;
padding: 20px;
color:#ACACAC;
}
#main_div{
background: #EEEEEE;
width: 554px;
min-height:120px;
}
#filter_data{
width: 335px;
background: #D8D8D8;
padding: 1px 0px 20px 13px;
margin: 20px 0px 0px 12px;
border: 1px solid #000;
}
a{text-decoration:none;}
.clear{clear: both;}
</style>
</head>
<body>
<div id="main_div">
<div style="display:block;">
<input type="text" id="movie" placeholder="Enter movie name">
<select id="director" ><option value="">Director</option></select>
Go
</div>
<div id="filter_data_div"></div>
</div>
</body>
</html>
First once you have all the json data, you need to traverse them. For that,
**$.each(data, function (i, data) {
if (data.title >= "textBox1Value" && item.title <= "textBox2Value")
//then the data;
});**
List item

Categories

Resources