I have a list with movie titles, youtube URL's (with which I can construct an embed code) and URL's to IMDB. On every page refresh, another movie title, Youtube video, and text with a URL to IMDB has to appear.
["Movie A", "URL_to_youtube_movie_A", "URL_to_IMDB_movie_A"],
["Movie B", "URL_to_youtube_movie_B", "URL_to_IMDB_movie_B"],
etc.
My website already has a refresh button: the page reloads with . How can I make the youtube video displayed randomized? I want the output to be HTML, so I can add elements afterwards, if necessary.
Shuffle the array, you can use underscore, or write custom function:
list = _.shuffle(list)
then output first n movies. This is the simplest method, that I think will be good enough for your case.
I would make an array of objects. Movie is an object, like this:
var list = [{ title: "Movie A", urlYouTube: "URL_to_youtube_movie", urlImdb: "URL_to_IMDB_movie_A"}, ...]
Also if you plan to do more operations than just show the random movies look at some javascript frameworks(backbone.js, angular, ...).
I would recommend you to use templates for the HTML output. Underscore also has simple template implementation. _.template(templateString, [data], [settings])
Something like this: DEMO && CODE
With simple javascript without any Library
You will need suffle function like below
DEMO
function arrayShuffle(oldArray) {
var newArray = oldArray.slice();
var len = newArray.length;
var i = len;
while (i--) {
var p = parseInt(Math.random()*len);
var t = newArray[i];
newArray[i] = newArray[p];
newArray[p] = t;
}
return newArray;
};
Call it like
var list = [{ title: "Movie A", urlYouTube: "URL_to_youtube_movie_A", urlImdb: "URL_to_IMDB_movie_A"},
{ title: "Movie B", urlYouTube: "URL_to_youtube_movie_B", urlImdb: "URL_to_IMDB_movie_B"},
{ title: "Movie C", urlYouTube: "URL_to_youtube_movie_C", urlImdb: "URL_to_IMDB_movie_C"}];
var Suffledlist = arrayShuffle(list);
And then show top 2 or 5 elements
Related
I have 7 cards in my html, with an image, title, description and source column. I'm trying to get the data from gnews api and then populate my cards with the data i get from the api. I'd like the data from the api to swap out my placeholder texts and image. But i'm only able to swap out the details in the first card in my HTML.
The JSON from the API look like this:
"articles": [
{
"title": "xxx xxx",
"description": "xxx xxx xxx",
"content": "xxx xxx xxx xxx... [1514 chars]",
"url": "xxx xxx",
"image": "xxx.jpg",
"publishedAt": "xxx",
"source": {
"name": "xxx",
"url": "xxx.com/"
}
}
]
I tried a forEach but it got only the first card
const title = document.querySelectorAll(".title"),
image = document.querySelector(".image"),
source = document.querySelector(".source"),
url = document.querySelector(".url");
.........
.then(function(data){
data.articles.forEach(article => {
title.innerHTML = article.title;
image.style.backgroundImage = article.image;
source.innerHTML = article.source.name;
url.setAttribute('href', article.url);
url.setAttribute('target', '_blank');
});
}
// And also i tried to target every card individually which worked but that means i would have
// to target all 7 html cards that i have which would be quite cumbersome and repetitive to write.
// Below is the code for the individual targetting..
news.title = data.articles[0].title;
news.image = data.articles[0].image;
news.source = data.articles[0].source.name;
news.url = data.articles[0].url;
news.description = data.articles[0].description;
How can i write the code to be able to get data from all the articles JSON and to fill up all the other cards with different news concurrently??
Hi and welcome to the community.
It looks like you still have a great work to go.
Well, you must first think this one through: you have to iterate through all of the cards and all of the components, which is something you are not doing.
That would mean something like:
.then(function(data){
data.articles.forEach(article => {
title.innerHTML = article.title;
image.style.backgroundImage = article.image;
source.innerHTML = article.source.name;
url.setAttribute('href', article.url);
url.setAttribute('target', '_blank');
//some code to skip to another card
});
Keep in mind that
const title = document.querySelectorAll(".title"),
image = document.querySelector(".image"),
source = document.querySelector(".source"),
url = document.querySelector(".url");
all of these are retrieving arrays of elements, since you have seven of them, right?
In your code you keep on pointing to image, title source and url, whith no indication of index. If that's the case, you are constantly updating the first.
Try to do this:
.then(function(data){
let x=0;
data.articles.forEach(article => {
title[x].innerHTML = article.title;
image[x].style.backgroundImage = article.image;
source[x].innerHTML = article.source.name;
url[x].setAttribute('href', article.url);
url[x].setAttribute('target', '_blank');
x++
});
It's not a perfect solution, though.
Take a look at this page and read it carefully. Take a few time to do it - I did it! If you still don't got it, let me know!
I am trying to have a drop down form that is populated with contacts populate a text box that contains the company information and address of that contact.
I have a small amount of knowledge in Javascript and have tried the following code:
var one = this.getField("Contact");
var two = this.getField("Company");
if (one.value == 'John Doe') {
two.value = 'Company1';
} else if (one.value == 'Jane Doe') {
two.value = 'Company2';
}
Is there anyone that can point me in the right direction? I have looked for similar questions but none I could find offered a solution for this specific issue.
Bluebeam is a relatively smart PDF viewer, and it should be possible to do some JavaScripting. You'd have to check whether it works, however; I don't have access to Bluebeam, and can not test it myself). A possible solution would look like this:
a) you create a document-level JavaScript which contains an array of the contact info (which may contain more than just the company name, but also address etc.. This array could look like this:
var contarr = new Array() ;
contarr[0] = ["Contact Person", "Company", "Address", "City", "State", "Zip"] ;
contarr[1] = ["John Doe", "Does and Donz", "Main Street", "Doetown", "TX", "99999"]
// and so on
b) In your Dropdown, you add the contact person name, and as return value, you add the index number of its entry in the contarr array. Let's assume we call the dropdown "Contact".
c) In an independent text field, you add the following Calculation script:
var sele = this.getField("Contact").value ;
this.getField("Company").value = contarr[sele][1] ;
this.getField("Address").value = contarr[sele][2] ;
this.getField("City").value = contarr[sele][3] ;
this.getField("State").value = contarr[sele][4] ;
this.getField("Zip").value = contarr[sele][5] ;
If everything is set up correctly, and you reopened the document, you should be able to select a contact, and the rest of the information would fill the according fields.
I need to make a nested JSON out of two flat structured arrays which are kind of linked together, I am able to get the first level but not able to nest it in javascript.
Below is the problem statement.
I have 2 arrays:
data = ["HSP - FS", "FS-M", "Lo Co", "GO A", "CQM","whatever"];
type = ["Epic","Sub - Epic","Sub - Epic","Epic","Sub - Epic","Story"];
the type array and data array are linked together and with type and description on the same index like
type[0] which is data[0], so it will be "Epic: HSP-FS", but this does not end here, this Epic has child elements also which are Sub - Epics and their description is placed under the same array element, so type[1] which is "Sub-Epic" has its data in data[1] which is "FS-M" and so on till next "Epic" is found in the type array.
So JSON would be like
{0:{
Epic: "HSP - FS",
Sub-Epic:"FS-M",
Sub-Epic:"Lo Co"
},
1:{
Epic: "GO A",
Sub-Epic:"CQM",
Story:"whatever"
}}
Structure of array and JSON is fixed, and even array can have any number of Epics, Sub Epics or story but the order will be maintained as in all the child of Epics will be there until next occurrence of Epic happens.
Issue is I am not able to write loop to get the output..I have till now tried something like iterating and joining these two arrays
Thank you in advance for help.
You can't have repeated named properties in a JSON object, but you can use arrays instead:
var array = [];
for(var i=0; i < data.length; ++i)
{
var t = type[i];
var d = data[i];
if (t == "Epic")
{
array.push({ "Epic": d});
}
else
{
if(typeof(array[array.length-1][t]) == "undefined")
{
array[array.length-1][t] = [];
}
array[array.length-1][t].push(d)
}
}
This is the resulting JSON:
[{
"Epic": "HSP - FS",
"Sub - Epic": ["FS-M","Lo Co"]
},
{
"Epic": "GO A",
"Sub - Epic": ["CQM"],
"Story": ["whatever"]
}]
UPDATE - Thanks for all the great answers and incredibly fast response. I've learned a great deal from the suggested solutions. I ultimately chose the answer I did because the outcome was exactly as I asked, and I was able to get it working in my application with minimal effort - including the search function. This site is an invaluable resource for developers.
Probably a simple task, but I can't seem to get this working nor find anything on Google. I am a Javascript novice and complex JSON confuses the hell out of me. What I am trying to do is make a PhoneGap Application (Phone Directory) for our company. I'll try to explain my reasoning and illustrate my attempts below.
I have JSON data of all of our employees in the following format:
[
{
"id":"1",
"firstname":"John",
"lastname":"Apple",
"jobtitle":"Engineer"
},
{
"id":"2",
"firstname":"Mark",
"lastname":"Banana",
"jobtitle":"Artist"
},
... and so on
]
The mobile framework (Framework 7) that I am using offers a "Virtual List" solution which I need to take advantage of as our directory is fairly large. The virtual list requires you to know the exact height of each list item, however, you can use a function to set a dynamic height.
What I am trying to do is create "headers" for the alphabetical listing based on their last name. The JSON data would have to be restructured as such:
[
{
"title":"A"
},
{
"id":"1",
"firstname":"John",
"lastname":"Apple",
"jobtitle":"Engineer"
},
{
"title":"B"
},
{
"id":"2",
"firstname":"Mark",
"lastname":"Banana",
"jobtitle":"Artist"
},
... and so on
]
I've been able to add key/value pairs to existing objects in the data using a for loop:
var letter, newLetter;
for(var i = 0; i < data.length; i++) {
newLetter = data[i].lastname.charAt(0);
if(letter != newLetter) {
letter = newLetter
data[i].title = letter;
}
}
This solution changes the JSON, thus outputting a title bar that is connected to the list item (the virtual list only accepts ONE <li></li> so the header bar is a div inside that bar):
{
"id":"1",
"firstname":"John",
"lastname":"Apple",
"jobtitle":"Engineer",
"title":"A"
},
{
"id":"1",
"firstname":"Mike",
"lastname":"Apricot",
"jobtitle":"Engineer",
"title":""
}
This solution worked until I tried implementing a search function to the listing. When I search, it works as expected but looks broken as the header titles ("A", "B", etc...) are connected to the list items that start the particular alphabetical section. For this reason, I need to be able to separate the titles from the existing elements and use them for the dynamic height / exclude from search results.
The question: How can I do a for loop that inserts [prepends] a NEW object (title:letter) at the start of a new letter grouping? If there is a better way, please enlighten me. As I mentioned, I am a JS novice and I'd love to become more efficient programming web applications.
var items = [
{ "lastname":"Apple" },
{ "lastname":"Banana" },
{ "lastname":"Box" },
{ "lastname":"Bump" },
{ "lastname":"Can" },
{ "lastname":"Switch" }
];
var lastC = null; //holds current title
var updated = []; //where the updated array will live
for( var i=0;i<items.length;i++) {
var val = items[i]; //get current item
var firstLetter = val.lastname.substr(0,1); //grab first letter
if (firstLetter!==lastC) { //if current title does not match first letter than add new title
updated.push({title:firstLetter}); //push title
lastC = firstLetter; //update heading
}
updated.push(val); //push current index
}
console.log(updated);
Well right now you have an array of objects - prefixing the title as its own object may be a bit confusing - a better structure may be:
[
{
title: "A",
contacts: [
{
"id":"1",
"firstname":"John",
"lastname":"Apple",
"jobtitle":"Engineer",
"title":"A"
}
]
Given your current structure, you could loop and push:
var nameIndexMap = {};
var newContactStructure = [];
for (var i = 0; i < data.length; i++) {
var letter = data[i].lastname.charAt(0);
if (nameIndexMap.hasOwnProperty(letter)) {
//push to existing
newContactStructure[nameIndexMap[letter]].contacts.push(data[i])
} else {
//Create new
nameIndexMap[letter] = newContactStructure.length;
newContactStructure.push({
title: letter,
contacts: [
data[i]
]
});
}
}
newContactStructure will now contain your sorted data.
Demo: http://jsfiddle.net/7s50k104/
Simple for loop with Array.prototype.splice will do the trick:
for (var i = 0; i < data.length; i++) {
if (i == 0 || data[i-1].lastname[0] !== data[i].lastname[0]) {
data.splice(i, 0, {title: data[i].lastname[0]});
i++;
}
}
Demo. Check the demo below.
var data = [
{"lastname":"Apple"},
{"lastname":"Banana"},
{"lastname":"Bob"},
{"lastname":"Car"},
{"lastname":"Christ"},
{"lastname":"Dart"},
{"lastname":"Dog"}
];
for (var i = 0; i < data.length; i++) {
if (i == 0 || data[i-1].lastname[0] !== data[i].lastname[0]) {
data.splice(i, 0, {title: data[i].lastname[0]});
i++;
}
}
alert(JSON.stringify( data, null, 4 ));
I wish to grab content from various sources, using different API calls, and collate them all into an object or array with the same format. I am getting stuck with javascript arrays and objects, and none of the examples I find seem to do what I want to do. This is the format I want to store. This is pseudo coded for an example of what I want to achieve
var content = new Object();
getTweets();
getSoundCloud();
display();
function getTweets() {
//first result
content.type = "tweet
content.text = "the text of the tweet"
content.image = "the image from the tweet"
return content;
}
function getSoundCloud() {
//second result
content.type = "soundcloud
content.text = "the name of the song"
content.image = "the image of the song"
return content;
}
function display() {
//for each content
{
$("#container").append(content.text);
}
}
The first result is generated by one function call, and the Second result is generated by a different function call.
I want these functions to add all of the content together into the same format object. Once the object is populated, I wish to iterate it in a different function and display on the screen.
How do I make this object? I have tried it but the data is always the same, ie, overwritten with the same values. In php this would be an associative array perhaps or something like
I want to have an object for each piece of content I have, and can loop through it
content[0].type = "tweet"
content[1].type = "coundcloud"
Any suggestions with examples would be great.
Many Thanks
When you have many of something you should immediately think
I need to store these things in an array.
When your "things" are complex and have various properties/ state, you should immediately think:
I need to create an object to store them.
... so what would be best here is an array of objects. Each function will create objects and add them to content, which we'll switch to an array:
var content = []; // Array
getTweets();
getSoundCloud();
display();
function getTweets() {
var tweet = {}; // This is an object
tweet.type = "tweet";
tweet.text = "The text of the tweet";
tweet.image = "The image of the tweet";
content.push(tweet); // add the object to the array.
}
function getSoundCloud() {
var soundcloudThing = {};
soundcloudThing.type = "soundcloud"
soundcloudThing.text = "the name of the song"
soundcloudThing.image = "the image of the song"
content.push(soundcloudThing);
}
Now when it comes to showing this content, as have an array; the obvious thing to do here is iterate over it;
function display() {
for (var i=0;i<content.length;i++)
{
$("#container").append(content[i].text);
// You can also use content[i].image and content[i].type in here
}
}
Note that [] and {} is literal notation for creating arrays and objects. It's use is favoured over new Array() and new Object().
I have done an example here: http://jsfiddle.net/pdXsA/2/
var content = [];
content.push(getTweets());
content.push(getSoundCloud());
display();
function getTweets() {
return{
type : "tweet",
text : "the text of the tweet",
image : "the image from the tweet"
};
}
function getSoundCloud() {
return{
type : "soundcloud",
text : "the name of the song",
image : "the image of the song"
};
}
function display() {
content.forEach(function(item){
$("#container").append(item.text +"<br/>");
});
}
content should be an array of objects, each function adds its object into the content array :
var content = []; // empty array
getTweets();
getSoundCloud();
display();
function getTweets() {
content.push ({ //first result
type: "tweet",
text: "the text of the tweet",
image: "the image from the tweet"
});
}
function getSoundCloud() {
content.push ({ //second result
type: "soundcloud",
text: "the name of the song",
image: "the image of the song"
});
}
function display() {
content.forEach (v) {
// code to format the object v appropriately
var vtext = v.type + ' : ' + v.text;
$("#container").append(vtext);
}
}
Actually, just sussed it out like this
var content = {
text: this.text.linkify().linkuser().linktag(),
image: this.profile_image_url,
type: 'tweet'
};
arrayContent.push(content);
I can now loop through it, and each Content and display it!