Alright. So the following code fetches only the first channel from the list, I want it to be fetching all the streams from the JSON. ( Bonus question: How can I format all the fetched streams into a nice row-per-row grid which features three streams in each row )
<script>
var twitchApi = "https://api.twitch.tv/kraken/streams";
$.getJSON(twitchApi, function (json) {
var streamGame = json.streams[0].game;
var streamThumb = json.streams[0].preview;
var streamVideo = json.streams[0].name;
$('#twitch').append('<li><iframe src="http://player.twitch.tv/?channel=' + streamVideo + '"></iframe></li>');
}
);
</script>
And the second thing I need help with is how to create a script which fetches the top 10 games from this JSON : https://api.twitch.tv/kraken/games/top .. Should be quite similar to the one above but my brain is frozen and I need to finish this.
You can get what you need to get done with a combination of loops and inline-block elements. Here, I used jQuery to create rows of three cells each.
var twitchApi = "https://api.twitch.tv/kraken/streams";
$.getJSON(twitchApi, function (json) {
var streamRow = $("<div class='stream-row'></div>").appendTo("#twitch"); // Create first row.
var streamCell;
var streamVideo;
for (var i = 0; i < json.streams.length; i++)
{
if (i % 3 == 0 && i > 0)
{
// Create a new row every multiple of 3.
streamRow = $("<div class='stream-row'></div>");
$("#twitch").append(streamRow);
}
// Create a cell with a video and add it to the row.
streamVideo = json.streams[i].channel.name;
streamCell = $("<div>", {
css: {
"class": "stream-cell",
"display": "inline-block"
}
});
streamCell.append('<iframe src="http://player.twitch.tv/?channel=' + streamVideo + '"></iframe>');
streamRow.append(streamCell);
}
});
You use another loop for the top ten thing. The API already returns 10 games, so I used the length instead of hard-coding 10.
var twitchApi = "https://api.twitch.tv/kraken/games/top";
$.getJSON(twitchApi, function (json) {
for (var i = 0; i < json.top.length; i++)
{
// Do whatever you need here with the info from the JSON.
console.log(json.top[i].game.name)
}
});
For fetching more than one stream at same time with the same data you can use a for loop.
Fixed your streamVideo variable, ".channel" was missing before ".name"(I recommed using a JSON viewer to get a clear vision of the structure, like Online JSON Viewer
And made the script so 10 iframes are displayed(also grabbed the embed code from twitch, your embed was so small).
The styling I let it to your own, I know nothing about styling iframes, you can try setting 30% width for each, so there are 3 per row, and the others go in the bottom row.
var twitchApi = "https://api.twitch.tv/kraken/streams";
$.getJSON(twitchApi, function(json) {
for (i = 0; i < 10; i++) {
var streamGame = json.streams[i].game;
var streamThumb = json.streams[i].preview;
var streamVideo = json.streams[i].channel.name;
$('#twitch').append('<li><iframe src="https://player.twitch.tv/?channel=' + streamVideo + '" frameborder="0" scrolling="no" height="378" width="620"></iframe><li>');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Related
So I'm doing a freeCodeCamp project that shows information regarding specific streamers. I have bumped into multiple problems, regarding if statements inside a for loop (I think).
First, the Status is always "Offline" for every streamer, second, the borders around the logos don't change except for the first one. If it worked, I'm still not sure whether the border colors would be correct though (red for offline streams, green for online).
If you watch closely, what I did was I provided a specific id for each iteration of streamer info, 1 for the corresponding image, and 1 for status, so I can target them with the i variable inside an if statement.
Here is the JS code, it is better visible via Codepen using the link I provided, mainly because you see the whole work and I don't know how to format code properly so that you don't have to use horizontal scrollbar to see long lines. :/
Thanks in advance!
$(document).ready(function() {
var channels = ["freecodecamp", "wudijo", "ThijsHS", "HSdogdog", "Sjow"];
for (var i = 0; i < channels.length; i++) {
var channelURL = "https://wind-bow.gomix.me/twitch-api/channels/"+ channels[i] +"?callback=?";
var streamURL = "https://wind-bow.gomix.me/twitch-api/streams/"+ channels[i] +"?callback=?";
$.getJSON(channelURL, function(data1) {
var logo = data1.logo;
var name = data1.display_name;
var twitchLink = data1.url;
var status;
$.getJSON(streamURL, function(data2) {
if (data2.stream === null) {
status = "Offline";
}
else {
status = data2.stream.channel.status;
}
$("#followerInfo").append("<div class = 'row'><div class = 'col-md-4'><a href = '"+ twitchLink +"' target = 'blank'><img id = 'img"+ i +"' src = '"+ logo +"'></a></div><div class = 'col-md-4'><p>" + name + "</p></div><div class = 'col-md-4'><p id = 'status"+ i +"'>" + status + "</p></div></div>");
if (data2.stream === null) {
$("#img"+ i +"").addClass('img-offline');
}
else {
$("#img"+ i +"").addClass('img-online');
}
});
});
}
});
If you console.log(channelURL) you can see that only "Sjow" his data is being called. This happens because your loop finishes before any requests are made, therefore only the last value in the array (Sjow) is used.
You can fix this by following this answer.
I had a question about the way I could execute a callback on multiple elements in my div.
So here it is. I have a div that contains two columns (col1 and col2, both taking 50% of the parent div and on float:left) many projects displayed as images. A big project is twice bigger (height) than a small one.
The configuration created makes it possible to display properly the projects to fill the div and not leave blank parts. So, basically, if we have 3 projects, we get a big project in col1 and 2 small in col2.
With 4 projects, we get a small + big in col1 and a big + small in col2.
And so on.
Problem is, when i'm filtering the different projects (in this example, by, for example, displaying the projects made in JS only, I use show() and hide() which works properly.
If animated, the projects just disappear because the hide() seems to be called while the show() isn't completed yet.
I was then told about the call back function but it seems to work only on one element, not multiples. Which is not optimal since my filtering always displays multiple projects.
I would like to know how to execute the function properly, so it works on all the projects because it seems to apply to only one.
Thanks in advance.
<script>
function update_projects(projects_ids){
console.log("Update projects : " + projects_ids);
var projects_top = $('.projects').offset().top;
if ($(window).scrollTop() > projects_top) {
$(window).scrollTop(projects_top);
}
var projects_config = generate_configuration(projects_ids.length);
var project_index = 0;
//$('.project').show();
$('.project').slideUp(2000, function(){
var odd = false;
for (var i = 0; i < projects_config.col1.length; ++i) {
var block_type = projects_config.col1[i];
var project_id = projects_ids[project_index++];
var odd_selector = '';
if (block_type == 'small') {
if (odd == false) {
odd_selector = '.left';
} else {
odd_selector = '.right';
}
odd = !odd;
}
$('.col1 .project_' + project_id + '.' + block_type + odd_selector).show();
}
odd = false;
for (var i = 0; i < projects_config.col2.length; ++i) {
var block_type = projects_config.col2[i];
var project_id = projects_ids[project_index++];
var odd_selector = '';
if (block_type == 'small') {
if (odd == false) {
odd_selector = '.left';
} else {
odd_selector = '.right';
}
odd = !odd;
}
$('.col2 .project_' + project_id + '.' + block_type + odd_selector).show();
}
});
resize();
}
As you've discovered, the completion callback on an animation is called once per element, not once per set.
To have a callback that is invoked when all of the animations have finished, use the .promise() method on the collection:
$('.myClass').slideUp(2000).promise().then(function() {
// not called until all animations have finished
...
});
I have to JSON files, I load them both into two tables like this:
$(window).load(function(){
$.getJSON('http://1xxxxxx/xxxxx_1_18.json', function(data) {
var output="<div class='outer'>";
for (var i in data.lbclassic118) {
output+="<div style='visibility:hidden;' class='lbclassic118'id="+"age" + data.lbclassic118[i].ageinweeks+">"+ '<table class="table table-responsive"><tr class="cabecera"><th colspan="3"><center><strong>Age (weeks)'+ data.lbclassic118[i].ageinweeks+'</strong></center></th></tr><tr><td rowspan="3">Body Weight (g)</td><td>average</td><td><strong>'+ data.lbclassic118[i].average+'</strong></td></tr><tr><td>range min</td><td><strong>'+ data.lbclassic118[i].rangemin+'</strong></td></tr><tr><td>range mmax</td><td><strong>'+ data.lbclassic118[i].rangemmax+'</strong></td></tr><tr><td rowspan="3">feed sonsumption</td><td>kj bird day</td><td><strong>'+ data.lbclassic118[i].kjbirdday+'</strong></td></tr><tr><td>g bird day</td><td><strong>'+ data.lbclassic118[i].gbirdday+'</strong></td></tr><tr><td>cumulative</td><td><strong>'+ data.lbclassic118[i].cumulative+'</strong></td></tr></table>' +"</div>";
}
output+="</div>";
document.getElementById("placeholder1").innerHTML=output;
});
});
$(window).load(function(){
$.getJSON('http://xxxxxx/xxxxxx.json', function(data) {
var output="<div class='outer'>";
for (var i in data.lbclassic1990) {
output+="<div style='visibility:hidden;' class='lbclassic1990'id="+"age" + data.lbclassic1990[i].ageinweeks+">"+ '<table class="table table-responsive"><tr class="cabecera"><th colspan="3"><center><strong>Age (weeks) '+ data.lbclassic1990[i].ageinweeks+'</strong></center></th></tr><tr><td>Egg No. per H.H.</td><td>cumul.</td><td><strong>'+data.lbclassic1990[i].cumul+'</strong></td></tr><tr><td rowspan="2">Rate of Lay %</td><td>per H.H.</td><td><strong>'+data.lbclassic1990[i].perhh+'</strong></td></tr><tr><td>per H.D.</td><td><strong>'+data.lbclassic1990[i].perhd+'</strong></td></tr><tr><td rowspan="2"> Egg Weight (g)</td><td>egg weight in week</td><td><strong>'+data.lbclassic1990[i].eggweightinweek+'</strong></td></tr><tr><td>egg mass cumul.</td><td><strong>'+data.lbclassic1990[i].eggmasscumul+'</strong></td></tr><tr><td rowspan="2">Egg Mass -- g/H.D. -- kg/H.H.</td><td>egg mass in week</td><td><strong>'+data.lbclassic1990[i].eggmassinweek+'</strong></td></tr><tr><td>egg mass cumul.</td><td><strong>'+data.lbclassic1990[i].eggmasscumul2+'</strong></td></tr></table>' +"</div>";
}
output+="</div>";
document.getElementById("placeholder2").innerHTML=output;
});
});
The information comes up as it should, I have no problems with that.
However, what I'm trying to do is just show ONE table at a time, not all the tables at the same time (don't want a table for each element in the JSONs) to be seen, but only one a time.
For that I'm implemeting a function that with a slider control will show or hide the tables.
Here's an images of the HTML output data structure:
Now, what I want to to is hide or show different DIVs (tables) with this script:
<script>
function leslider(valor) {
var elementos_lbclassic118 = document.getElementsByClassName("lbclassic118");
var elementos_lbclassic1990 = document.getElementsByClassName("lbclassic1990");
var total_elementos = elementos_lbclassic118.length + elementos_lbclassic1990.length;
var i;
for (i = 1; i < total_elementos.length+1; i++) {
document.getElementById("age"+i).style.visibility = "hidden";
}
document.getElementById("age"+valor).style.visibility = "visible";
}
However it won't work, the 1st JSON will show all the elements but never hide it, and the second one will place them all on top of each other, not sure where I'm failing.
I guess you are wrong "leslider" function.
How to use this "leslider" function, let's me see this code.
I found the culprit, I was getting length from a numeric, value. Here's the updated function.
<script>
function leslider(valor) {
var elementos_lbclassic118 = document.getElementsByClassName("lbclassic118");
var elementos_lbclassic1990 = document.getElementsByClassName("lbclassic1990");
var total_elementos = elementos_lbclassic118.length + elementos_lbclassic1990.length;
var i;
for (i = 1; i < total_elementos+1; i++) {
document.getElementById("age"+i).style.display = "none";
}
document.getElementById("age"+valor).style.display = "block";
}
This is my first time working with pagination. The issue I am having is that I am getting multiple responses from the Instagram API after a certain amount of clicks to the pagination button. I think I have narrowed down the issue to the fact that the function is probably firing multiple times. Take a look at my functions.
Receives the data and sorts it to the other functions:
function sortAndStore(data) {
var images = data.data,
pagLink = data.pagination.next_url;
var newImages = [];
for (i = 0; i < images.length; i++) {
var link = images[i].link,
standardRes = images[i].images.standard_resolution.url,
thumb = images[i].images.thumbnail.url;
var tempImages = new Object();
tempImages.link = link;
tempImages.standard_res = standardRes;
tempImages.thumbnail = thumb;
newImages.push(tempImages);
}
createLayout(newImages);
loadMore(pagLink);
}
Creates the desired layout (sloppy right now but working):
function createLayout(data) {
var images = data;
if ($('#authorizeInsta').css('display') === 'inline') {
$('#authorizeInsta').hide();
// Adds additonal structure
$('<div id="instagramFeed" class="row-fluid" data-count="0"></div>').insertAfter('.direct_upload_description_container');
}
if (!$('#feedPrev').length > 0) {
$('<ul id="feedNav" class="pagination"><li><a id="feedPrev" href="#">Prev</a></li><li><a id="feedNext" href="#">Next</a></li></div>').insertAfter('#instagramFeed');
}
var count = $('#instagramFeed').data('count'),
countParse = parseInt(count);
newCount = countParse + 1;
$('<div id="row' + newCount + '" class="span3">').appendTo('#instagramFeed');
$('#instagramFeed').data('count', newCount);
for (i = 0; i < images.length; i++) {
var link = images[i].link,
standardRes = images[i].standard_res,
thumb = images[i].thumbnail,
newImage = '<img data-image="' + standardRes + '" src="' + thumb + '" class="feedImage" id="feedImage' + i + '"/>';
$(newImage).appendTo('#row' + newCount + '');
}
imageSelect();
}
Pagination function:
function loadMore(link) {
var pagLink = link;
console.log(pagLink);
$('#feedPrev').unbind('click').click(function(event) {
$.ajax({
url: link,
type: 'GET',
dataType: 'jsonp',
})
.done(function(data) {
sortAndStore(data);
})
.fail(function(data, response) {
console.log(data);
console.log(response);
});
return false;
});
}
I understand that the issue is probably here in the sortAndStore function
createLayout(newImages);
loadMore(pagLink);
And here is what the pagination link console logs out to. The issue being that I clicked the button three times and I got four responses. The first two times were fine. I got one pagination link, but the third time I received two response.
If you can see a different issue or suggest a different way to structure my functions it would be greatly appreciated. The data parameter in the sortAndStore function is the data from the original Instagram API call.
Thanks,
Figured it out! The issue was that every time the pagination button was clicked the browser was storing a new value for pagLink. Therefore, after clicking the button twice, there were two stored variables which made two pagination API calls.
The fix is to redefine the variable every time a new pagination link goes through the function, not to define an additional pagLink variable.
So this:
function sortAndStore(data) {
var images = data.data;
pagLink = data.pagination.next_url;
Instead of this:
function sortAndStore(data) {
var images = data.data,
pagLink = data.pagination.next_url;
So the solution was to redefine the variable, not to add an additional one, like I was doing by accident.
I am trying to create a cfgrid (Coldfusion 9) with locked columns.
I looked at the code at http://dev.sencha.com/deploy/ext-4.0.0/examples/grid/locking-grid.html and can see that the property I need to set is 'locked' = true...
here is the javascript code:
<cfsavecontent variable="headContent">
<script type="text/javascript">
function init()
{
var myGrid = ColdFusion.Grid.getGridObject('gridData');
//turn on the grid panel's lockable option - not sure if this is needed or not
myGrid.lockable = true;
//get the column model
cm = myGrid.getColumnModel();
//lock the first two columns in the grid
for(var i=0; i < 2; i++) {
var thisid = cm.getColumnId(i);
var thiscol = cm.getColumnById(thisid);
thiscol.locked = true;
//for (prop in thiscol){ document.write("object." + prop + " = " + thiscol[prop] + "<br>");}
}
//refresh the grid
ColdFusion.Grid.refresh('gridData',false);
}
</script>
</cfsavecontent>
I don't get any errors..but don't get my locked columns either.
I know I can affect the properties of the grid using this particular javascript code - I tried setting thiscol.sortable = false and that did indeed grey out the ability to sort the column.
any ideas??
I solved my problem by downloading extjs 4 and creating the js code needed..