how to create a multidimensional json array - javascript

var items = [{
title: 'sample 1',
image: 'http://www.lorempixel.com/700/600/'
}, {
title: 'sample 2',
image: 'http://www.lorempixel.com/900/1200/'
}, {
title: 'sample 3',
image: 'http://www.lorempixel.com/400/300/'
}, {
title: 'sample 4',
image: 'http://www.lorempixel.com/600/600/'
}, {
title: 'sample 5',
image: 'http://www.lorempixel.com/400/310/'
}, {
title: 'sample 6',
image: 'http://www.lorempixel.com/410/300/'
}, {
title: 'sample 7',
image: 'http://www.lorempixel.com/500/300/'
}, {
title: 'sample 8',
image: 'http://www.lorempixel.com/300/300/'
}, {
title: 'sample 9',
image: 'http://www.lorempixel.com/450/320/'
}, {
title: 'sample 10',
image: 'http://www.lorempixel.com/500/400/'
}];
Instead of hard coding this, I would like to create this exact same array dynamically - here is my code.
for(var key in pics) {
var items[];
items.push(pics[key].source);
}
I dont think this works because it just pushes the images into a standard array like this:
items = [1.jpg, 2.jpg....];
How can I accomplish this,cheers.

I don't know where you get the img url and i assume pics.source is the title:
var items = [];
for(var key in pics) {
items.push({title: pics[key].source, image: <img url>});
}

Related

Loop through array of objects, if value exists, return another value

With the information below I am trying loop through cards, if there is a nested object of helper, return that objects title. But am either receiving undefined or errors. I was thinking maybe reduce would be viable here?
Sample Array:
cards: [
0: {
title: 'Something',
logo: 'logo link here',
},
1: {
title: 'Something 2',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
2: {
title: 'Something 3',
logo: 'logo link here',
},
]
code:
cards.filter((item) => {
if (item.helper) setHelperActive({...helperActive, item.title: true})
})
let cards = [
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Something else',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Lorem Epsum',
logo: 'logo link here',
helper: {
text: 'helper text',
},
}
]
let filtered = []
for(let i = 0; i < cards.length; i++) {
if(cards[i].helper) {
filtered.push(cards[i].title)
}
}
console.log(filtered);
Using .filter() and checking if the object has a prop named helper. In case of multiple objects matching the criteria, their title's will be joined as a comma-separated string.
Snippet
let cards = [
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Something 2',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
{
title: 'Something',
logo: 'logo link here',
},
{
title: 'Something 4',
logo: 'logo link here',
helper: {
text: 'helper text',
},
},
]
// to list titles from all matching objects as a comma-separated string
console.log(cards.filter(ob => 'helper' in ob).map(({ title }) => title).join());
// suppose only the first matched object's title is required
console.log(cards.find(ob => 'helper' in ob)?.title ?? 'no match found');
the solution is to use map not filter should be like this:
var titles = cards.map(card=>{ return card.title })

How could I merge duplicate elements from object arrays? [duplicate]

I have this array of objects, that I need to modify to make it easier the rendering.
const items = [
{
tab: 'Results',
section: '2017',
title: 'Full year Results',
description: 'Something here',
},
{
tab: 'Results',
section: '2017',
title: 'Half year Results',
description: 'Something here',
},
{
tab: 'Reports',
section: 'Marketing',
title: 'First Report',
description: 'Something here',
},
...
];
and I'm trying to modify it, grouping them by specific keys. The idea is to have this output. As you can see the names of the keys could be different than the actual names in the items. I think that makes a bit different from previous posts.
const output = [
{
tab: 'Results',
sections: [
{
section: '2017',
items: [ { 'item that belongs here' }, { ... } ],
},
},
{
tab: 'Reports',
sections: [
{
section: 'Marketing',
items: [ { ... }, { ... } ],
},
},
...
]
I tried using lodash.groupby, but it doesn't do exactly what i'm looking for.
Any idea about how to approach it?
Many thanks!!
This can be done with a clever combinartion of _.map and _.groupBy.
const items = [
{
tab: 'Results',
section: '2017',
title: 'Full year Results',
description: 'Something here',
},
{
tab: 'Results',
section: '2017',
title: 'Half year Results',
description: 'Something here',
},
{
tab: 'Reports',
section: 'Marketing',
title: 'First Report',
description: 'Something here',
}
];
function groupAndMap(items, itemKey, childKey, predic){
return _.map(_.groupBy(items,itemKey), (obj,key) => ({
[itemKey]: key,
[childKey]: (predic && predic(obj)) || obj
}));
}
var result = groupAndMap(items,"tab","sections",
arr => groupAndMap(arr,"section", "items"));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
You could use an object without additional libraries.
The object contains a property _ which keeps the nested arrays of the given nested group.
var items = [{ tab: 'Results', section: '2017', title: 'Full year Results', description: 'Something here' }, { tab: 'Results', section: '2017', title: 'Half year Results', description: 'Something here' }, { tab: 'Reports', section: 'Marketing', title: 'First Report', description: 'Something here' }],
keys = { tab: 'sections', section: 'items' }, // or more if required
result = [],
temp = { _: result };
items.forEach(function (object) {
Object.keys(keys).reduce(function (level, key) {
if (!level[object[key]]) {
level[object[key]] = { _: [] };
level._.push({ [key]: object[key], [keys[key]]: level[object[key]]._ });
}
return level[object[key]];
}, temp)._.push({ title: object.title, description: object.description });
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to run a function every 5 sec with difference value everytime?

i try to run a notification message on my page but i just wondering is there any siimple ways to code this?
<script>
window.setTimeout(function(){
iziToast.show({
hyperlink: '?id=002',
title: 'Title 2',
message: 'message 2',
image: 'img/2.jpg',
timeout: 7500,
});
}, 5000);
window.setTimeout(function(){
iziToast.show({
hyperlink: '?id=003',
title: 'Title 3',
message: 'message 3',
image: 'img/3.jpg',
timeout: 7500,
});
}, 17500);
window.setTimeout(function(){
iziToast.show({
hyperlink: '?id=004',
title: 'Title 4',
message: 'message 4',
image: 'img/4.jpg',
timeout: 7500,
});
}, 30000);
window.setTimeout(function(){
iziToast.show({
hyperlink: '?id=005',
title: 'Title 5',
message: 'message 5',
image: 'img/5.jpg',
timeout: 7500,
});
}, 42500);
</script>
How can i use much simple code to run those function? Sorry im very new in programming and self learner.
I think you need this
var i = 0;
var interval;
//taken from Ma Kobi answer
var options = [
{
hyperlink: '?id=002',
title: 'Title 2',
message: 'message 2',
image: 'img/2.jpg',
timeout: 7500,
},
{
hyperlink: '?id=003',
title: 'Title 3',
message: 'message 3',
image: 'img/3.jpg',
timeout: 7500,
},
{
hyperlink: '?id=004',
title: 'Title 4',
message: 'message 4',
image: 'img/4.jpg',
timeout: 7500,
},
{
hyperlink: '?id=005',
title: 'Title 5',
message: 'message 5',
image: 'img/5.jpg',
timeout: 7500,
}];
//taken from Ma Kobi answer
function myfunction() {
interval= setInterval(function () {
iziToast.show(options[i]);
i++;
if (i == 6) {
i = 0;
clearInterval(interval);
}
}, 1000);
}
Maybe so:
var options = [
{
hyperlink: '?id=002',
title: 'Title 2',
message: 'message 2',
image: 'img/2.jpg',
timeout: 7500,
},
{
hyperlink: '?id=003',
title: 'Title 3',
message: 'message 3',
image: 'img/3.jpg',
timeout: 7500,
},
{
hyperlink: '?id=004',
title: 'Title 4',
message: 'message 4',
image: 'img/4.jpg',
timeout: 7500,
},
{
hyperlink: '?id=005',
title: 'Title 5',
message: 'message 5',
image: 'img/5.jpg',
timeout: 7500,
}
];
var timeout = [
5000, 17500, 30000, 42500
];
for (var i = 0; i < options.length; i++) {
window.setTimeout(function(){
iziToast.show(options[i]);
}, timeout[i]);
}
For another toast you can add an entry to options and a timeout to timeout array.
If you want to repeat a function in php you can use loop.
for (init counter; test counter; increment counter) {
code to be executed;
}
if you want to repeat a function in javascript you can use the following code:
for (statement 1; statement 2; statement 3) {
code block to be executed
}
if you want to repeat a function for an specified time you can use the following code:
setInterval(function(){
foFuction()
},50000;
Try window.setInterval();
Ex:
setInterval(function(){
alert("Hello");
},12500);`
The above code runs for every 12500ms.
Try to figure out a way to pass a dynamic object for each time interval.

JSTree: move all child nodes

I'm using JSTree, and this is my setup for the contextmenu plugin:
"contextmenu":{
"items": function($node) {
return {
"Remove": {
"separator_before": false,
"separator_after": false,
"label": "Delete group",
"action": function (obj) {
$tree.jstree("get_children_dom", $node).each(function(child){
$tree.jstree("move_node", $tree.jstree("get_node", child, true), "#", "last", function(node, parent, pos){
alert(1);
});
});
$tree.jstree("delete_node", $node);
}
}
};
}
}
basically, I want the children of the group that's being deleted to be moved upwards. The function I've currently got should place the nodes at the end, but how can I place them on the deleted node's place? Also, the current code doesn't work - what am I doing wrong?
Last but not least, how can I check the node type before removing?
Thanks in advance
basically, I want the children of the group that's being deleted to be moved upwards.
If by upwards you mean get into the position of the node that got deleted, check the following example:
var data = [{
'text': 'item 1',
'children': [{
text: 'item 1-1',
children: [{
text: 'item 1-1-1',
children: [{
text: 'item 1-1-1-1'
}, {
text: 'item 1-1-1-2'
}]
}, {
text: 'item 1-1-2'
}, {
text: 'item 1-1-3'
}]
}, {
text: 'item 1-2',
children: [{
text: 'item 1-2-1'
}, {
text: 'item 1-2-2'
}]
}, {
text: 'item 1-3',
children: [{
text: 'item 1-3-1'
}, {
text: 'item 1-3-2'
}]
}, {
text: 'item 1-4',
children: [{
text: 'item 1-4-1'
}, {
text: 'item 1-4-2'
}]
}]
}, {
'text': 'item 2',
children: [{
text: 'item 2-1',
children: [{
text: 'item 2-1-1'
}, {
text: 'item 2-1-2'
}]
}, {
text: 'item 2-2',
children: [{
text: 'item 2-2-1'
}, {
text: 'item 2-2-1'
}]
}, {
text: 'item 2-3'
}]
}, {
'text': 'item 3',
children: [{
text: 'item 3-1',
children: [{
text: 'item 3-1-1'
}, {
text: 'item 3-1-2'
}]
}, {
text: 'item 3-2'
}]
}, {
'text': 'item 4 (you cannot delete this one)',
'disableDelete': true,
children: [{
text: 'item 4-1'
}, {
text: 'item 4-2'
}, {
text: 'item 4-3'
}]
}];
var $tree = $('#jstree_demo').jstree({
'plugins': ['contextmenu'],
'core': {
'animation': 0,
'check_callback': true,
'themes': {
'stripes': true
},
'data': data
},
'contextmenu': {
'items': function($node) {
return {
'Remove': {
'separator_before': false,
'separator_after': false,
'label': 'Delete group',
'action': function(obj) {
if ($node.original.disableDelete) {
document.write('deletion is forbidden for this node');
return;
}
var nodes = $node.children.slice(0); // jstree behaves erratic if we try to move using $node.children directly, so we will clone the array to prevent this issue
var $row = $(obj.reference[0].closest('li'));
$tree.jstree('move_node', nodes, $node.parent, $row.index());
$tree.jstree('delete_node', $node);
}
}
};
}
}
});
<div id="jstree_demo"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css">
Last but not least, how can I check the node type before removing?
I´ve added a small sample to show you how you can accomplish it. Check the declaration of a custom attribute disableDeletion to a node:
var data = [{'text': 'item 4 (you cannot delete this one)', 'disableDelete': true}]
And the validation in the context menu action:
if ($node.original.disableDelete) {
document.write('deletion is forbidden for this node');
return;
}

Third row as table header in pdfMAke pdf creator engine

I just went through this playground of pdfMake pdf creator engine and it nicely explains how to print a table using pdfMAke as,
table: {
headerRows: 1,
body: [
[{ text: 'Header 1', style: 'tableHeader' }, { text: 'Header 2', style: 'tableHeader'}, { text: 'Header 3', style: 'tableHeader' }],
[ 'Sample value 1', 'Sample value 2', 'Sample value 3' ],
[ 'Sample value 1', 'Sample value 2', 'Sample value 3' ],
[ 'Sample value 1', 'Sample value 2', 'Sample value 3' ],
[ 'Sample value 1', 'Sample value 2', 'Sample value 3' ],
[ 'Sample value 1', 'Sample value 2', 'Sample value 3' ],
]
},
where headerRows: 1 will consider the first row as table header. Is there any ways to consider the third row as header using this engine so that the third row will repeat as header in the next consecutive pages of pdf document.
Also is it possible to draw borders around columns which drawn below.
columns: [
{ text: 'First Column goes here.'},
{ text: 'Second column goes here.'},
{ text: 'Third column goes here.' }
]
late answer but unfortunately that's impossible, only the first row can be used as header.
As a workaround, I would suggest building tables by yourself, allowing you to repeat any line you want. It's more constraining tho, since you need to handle the overflows manually to insure the repetition of the table on each page.

Categories

Resources