Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                
<html>
<head>
  <title>Twitch Json Api</title>
  <link rel="stylesheet" type="text/css" href="./style.css" />
  <script src="./script.js" type="text/javascript"></script>
  <meta charset="utf-8" />
  <meta lang="en-us" />
  <meta name="viewport" content="width-device-width , initial-scale=1.0" />
  <script
    src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
  <div class="main-page">
    <div class="headline">
      <img class="headlogo" src="http://mythicrejects.com/wp-content/uploads/2017/01/Combologo_474x356.png" alt="purple on white combo twitch logo"  />
    </div>
    <div class="wrapper">
      <ul class="channels-list" id="channels-list">
      <div id="show-online-button" class="show-online-button">
          <p id="show-online">online only</p>
      </div>
      <div class="filter">
          <input placeholder="filter" id="filterbar" class="searchbar" type="text">
      </div>
      </ul>
    </div>
  </div>
</body>
</html>

              
            
!

CSS

              
                body {
  background-color:#6441A4;
  height:100%;
}
.main-page {
    background-color: #6441A4;
}

.headlogo {
    position: relative;
    display: block;
    left: 50%;
    transform: translate(-50%, 0);
}

.wrapper {
    position: relative;
}

.channels-list {
    position: relative;
    left: 50%;
    transform: translate(-50%);
    list-style: none;
    max-width:920px;
    display: flex;
    justify-content:center;
    flex-flow:row wrap;
    padding: 0;
}

.show-online-button {
  height:20px;
  background-color:#fff;
  border-style:hidden;
  border-radius:3px;
  margin:5px;
  padding:10px;
  flex: 0 1 100%;
}
#show-online {
  position:relative;
  display:inline-block;
  transform: translateY(-100%);
  width:100%;
  height:20px;
  background-color:#fff;
  border-style:none;
  outline:none;
  font-family:sans-serif;
  font-size:20px;
  font-weight:bold;
  color:#6441A4;
  text-align:center;
  cursor:pointer;

  //background-color:red;

}
#show-online:hover {
  color:#ffde00;
}
#show-online:active {
  color:#ff7a00;
}
.filter {
  position:relative;
  height:20px;
  background-color:#fff;
  border-style:hidden;
  border-radius:3px;
  margin:5px;
  padding:10px;
  flex: 0 1 100%;
}
.searchbar {
  position:relative;
  width:100%;
  background-color:#fff;
  border-style: none;
  outline:none;
  font-size:20px;
  font-weight:bold;
  color:#6441a4;
  top:50%;
  transform:translateY(-50%);
  text-align:center;
}
.searchbar::placeholder {
  color:#6441a4;
}
.close-button {
  color:#db6032;
  position:relative;
  z-index:1;
  top:10px;
  left:180px;
  cursor:pointer;
  width:10px;
}
.close-button::after {
  content:'';
  width:inherit;
  height:0px;
  position:absolute;
  margin:0px;
  transform-origin:top-left;
  transform:rotate(45deg);
  border-color:currentcolor;
  border-style:solid;
  border-width: 1px 0 0 0;
}
.close-button::before {
  content:'';
  width:inherit;
  height:0px;
  position:absolute;
  margin:0px;
  transform-origin:top-right;
  transform:rotate(-45deg);
  border-color:currentcolor;
  border-style:solid;
  border-width: 1px 0 0 0;
}
li.links-card {
    background-color:#fff;
    border-radius: 3px;
    border-style: hidden;
    flex-basis:200px;
    padding: 10px;
    text-align: center;
    margin: 5px;
    outline:none;
}
li.links-card:hover {
  outline-color:#ffde00;
  outline-width:5px;
  outline-style:solid;
  outline-offset:-5px;
}

.logo {
    margin-top: 20px;
    max-width: 100px;
    max-height: 100px;
    border-radius: 50%;
    border-style: hidden;
    margin-bottom:12px;
}

li.links-card .links-info {
    font-family: sans-serif;
    margin-top: 10px;
}

.links-name {
    font-size: 22px;
    text-decoration: none;
    font-family: sans-serif;
}
.Online {
    color: #6441A4
}

.Offline {
  color: #d0bef1;
}
.invalid {
  color: #d0bef1;
}

.status {
    font-family: sans-serif;
    margin:2px;
}
.card-metrics {
    display: flex;
    overflow:hidden;
    font-family: sans-serif;
    justify-content:center;
}

.card-metrics-title {
    color: #A277F0;
    font-size: 10px;
}

.card-metrics-value {
    font-size: 11px;
    color: #6441a4;
}

.card-metrics-value a {
    text-decoration: none;
    color: #4382B1;
}

.card-followers {
    display: inline-block;
    margin: 8px;
}

.card-views {
    display: inline-block;
    margin: 8px;
}

.card-lang {
    display: inline-block;
    margin: 8px;
}

              
            
!

JS

              
                document.addEventListener("DOMContentLoaded", function() {

    // getJSON function - api call
	var getJSON = function(url, callback) {
		var xhr = new XMLHttpRequest();
		xhr.open("GET", url, true);
		xhr.responseType = "json";
		xhr.onload = function() {
			callback(xhr.response);
		};
		xhr.send();
	};
    //Channels Array
	var chan = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas", "brunofin", "comster404"];
    //variables
	var streamsReturn = [];
	var channelsReturn = [];
    //some functions
    //return status
	var status = function(currChan, currStre) {

		if (currChan.status !== 404) {
			if (currChan.status === 400 || currStre.stream === null) {
				return "Offline";
			} else {
				return "Online";
			}
		} else {
			return "invalid";
		}
	};
                //status message if online - show status, else show "offline"
                //also truncate status
	var returnStatus = function(currChan, currStre, state) {
		if (state(currChan, currStre) === "Online") {
			if (currChan.status.length >= 20) {
				return currChan.status.slice(0, 19) + "...";
			} else {
				return currChan.status;
			}
		} else if (state() === "Offline") {
			return "Offline";
		} else {
			return "404 - Invalid Account";
		}
	};
                //invalid channel name - to avoid undefined values in channel names
	var nameCheck = function(currChan, e, channels) {
		if (currChan.display_name === undefined) {
			return channels[e];
		} else {
			return currChan.display_name;
		}
	};
	var filterItems = function(query) {
		return chan.filter(function(el) {
			return el.toLowerCase().indexOf(query.toLowerCase()) <= -1;
		});
	};

	var listFirst = function(currChan, currStre, e, state, channels) {
        //LIST FIRST-----------------------------------------------------
        //create a list element inside the ul
		var newList = document.createElement("li");
        //give it classes
		newList.className = "links-card " + state(currChan, currStre);
        //give it a unique id
		newList.setAttribute("id", channels[e]);
        //append it under desired node (channels-list in this case)
		document.getElementById("channels-list").appendChild(newList);

        //Close button
		var closeButton = document.createElement("div");
        //class
		closeButton.className = "close-button";
        //uniqueid
		closeButton.setAttribute("id",channels[e]+"-close");
        //functions
		closeButton.addEventListener("click",function() {

			var element = document.getElementById(channels[e]);
			element.parentNode.removeChild(element);
            //remove from the original array too
			currChan.splice(e,1);
		});
        //append under desired node
		newList.appendChild(closeButton);

        //Hide Card metrics for invalid accounts
		if (currChan.status === 404) {
			var invalidImage = document.createElement("img");
			invalidImage.className = "logo";
			invalidImage.setAttribute("src", "https://imgur.com/aZYkju4.jpg");
			newList.appendChild(invalidImage);
		} else {
        //IMAGE & LINK ---------------------------------------------------------
        //create an anchor element insade the list element that you've created
			var imageLink = document.createElement("a");
        //set link address
			imageLink.setAttribute("href", currChan.url);
        //link opens in new tab
			imageLink.setAttribute("target", "_blank");
        //append it under newList - how? - get by classname? will using a var work?
			newList.appendChild(imageLink);

        //nest an image inside the anchor
			var imageNested = document.createElement("img");
        //give it a classname
			imageNested.className = "logo";
        //set the source attribute
			imageNested.setAttribute("src", currChan.logo);
        //append it under imageLink - via class or id
			imageLink.appendChild(imageNested);
		}
		return newList;
	};
	var infoListesi = function (e, currChan, currStre, yeniliste, state, namechecker, returnstate, channels) {
        //INFO - channel name, status , and card metrics---------------------------
        //nev div inside the list element
		var infoList = document.createElement("div");
        //give it a class
		infoList.className = "links-info";
        //append it under newList
		yeniliste.appendChild(infoList);

        //CHANNEL NAME & LINK ------------------------------------------
        //creata an anchor inside the div - name / link to profile
		var profileLink = document.createElement("a");
        //set classes of the anchor - profile link
		profileLink.className = "links-name " + state(currChan, currStre);
        //set the link address
		profileLink.setAttribute("href", currChan.url);
        //open in new tab
		profileLink.setAttribute("target", "_blank");
        //add the profile name into the anchor - with nameCheck function to prevent undefined values
		profileLink.innerHTML = namechecker(currChan, e, channels);
        //append it under infoList
		infoList.appendChild(profileLink);

        //CHANNEL STATUS ----------------------------------------------
        //add a text element to show status
		var infoListStatus = document.createElement("p");
        //add some classes
		infoListStatus.className = "status " + state(currChan, currStre);
        //add the text ---- with truncate option on longer strings returnStatus() function
		infoListStatus.innerHTML = returnstate(currChan, currStre, state);
        //append it under infoList
		infoList.appendChild(infoListStatus);
        //return the variable
		return infoList;
	};
	var cardMetrik = function(currChan, enfolist) {
        //CARD METRICS ----------------------------------------------------
        //card metrics
		var cardMetrics = document.createElement("div");
        //card metrics classes
		cardMetrics.className = "card-metrics";
        //append it under infoList
		enfolist.appendChild(cardMetrics);

        //FOLLOWERS --------------------------------------------------------
        //card metrics followers
		var cardFollowers = document.createElement("p");
        //give it classes
		cardFollowers.className = "card-followers";
        //append it under cardMetrics
		cardMetrics.appendChild(cardFollowers);

        //span title
		var followersTitle = document.createElement("span");
        //give it classes
		followersTitle.className = "card-metrics-title";
        //innerHTML of title
		followersTitle.innerHTML = "followers";
        //append it under cardFollowers
		cardFollowers.appendChild(followersTitle);

        //add a line break
		var cardFollowersBreak = document.createElement("br");
        //append under cardFollowers
		cardFollowers.appendChild(cardFollowersBreak);

        //values span
		var followersValue = document.createElement("span");
        //classes for the values span
		followersValue.className = "card-metrics-value";
        //append under cardFollowers
		cardFollowers.appendChild(followersValue);

        //add an anchor inside
		var followersValueLink = document.createElement("a");
        //give anchor some classes and attributes
		followersValueLink.setAttribute("href", currChan.url + "/followers/");
        //innerHTML of the link - followers value
		followersValueLink.innerHTML = currChan.followers;
        //append it under followersValue
		followersValue.appendChild(followersValueLink);


        //VIEWS ----------------------------------------------------------
        //create another P for the views values
		var cardViews = document.createElement("p");
        //give it classes
		cardViews.className = "card-views";
        //append under cardMetrics
		cardMetrics.appendChild(cardViews);

        //add a span inside for title
		var cardViewsTitle = document.createElement("span");
        //give it a class
		cardViewsTitle.className = "card-metrics-title";
        //innerHTML
		cardViewsTitle.innerHTML = "views";
        //append under cardViews
		cardViews.appendChild(cardViewsTitle);

        //add a linebreak
		var cardViewsBreak = document.createElement("br");
        //append it under cardViews
		cardViews.appendChild(cardViewsBreak);

        //add a span for value
		var cardViewsValue = document.createElement("span");
        //give it classes
		cardViewsValue.className = "card-metrics-value";
        //innerHTML probably
		cardViewsValue.innerHTML = currChan.views;
        //append under cardViews
		cardViews.appendChild(cardViewsValue);


        //LANGUAGE --------------------------------------------------------
        //finally the language info
		var cardLang = document.createElement("p");
        // give it classes
		cardLang.className = "card-lang";
        //append under cardMetrics
		cardMetrics.appendChild(cardLang);

        //create a span inside for language title
		var cardLangTitle = document.createElement("span");
        //give it classes
		cardLangTitle.className = "card-metrics-title";
        //innerHTML
		cardLangTitle.innerHTML = "language";
        //append under cardLang
		cardLang.appendChild(cardLangTitle);

        //add a line break
		var cardLangBreak = document.createElement("br");
        //append it under cardLang
		cardLang.appendChild(cardLangBreak);


        //add a span for values
		var cardLangValue = document.createElement("span");
        //give it classes
		cardLangValue.className = "card-metrics-value";
        //innerHTML
		cardLangValue.innerHTML = currChan.language;
        //append under cardLang
		cardLang.appendChild(cardLangValue);
	};


    //DO IT BETTER -----create your cards dynamically------------ to be updated----

    //GET channels ->
	var getAllValues = function (e, channels, state, namechecker, returnstate) {
        //get streams
		getJSON("https://api.twitch.tv/kraken/streams/" + channels[e], function(data) {
            //Store json to access data from other sources
			var currentStream = data;
			streamsReturn.push(data);
            //get channels
			getJSON("https://api.twitch.tv/kraken/channels/" + channels[e], function(data) {
                //Store json to access data from other sources
				channelsReturn.push(data);
				var currentChannel = data;
                //function for links online - offline classes
				var newList = listFirst(currentChannel, currentStream, e , state, channels);
				var infoList = infoListesi(e, currentChannel, currentStream, newList, state, namechecker, returnstate, channels);
				if (currentChannel.status === 404) {
					return;
				} else {
					cardMetrik (currentChannel, infoList);
				}
				return currentChannel;
			});
			return currentStream;
		});
	};


	for (let i = 0; i < chan.length; i++) {
		setTimeout(getAllValues.bind(null, i, chan, status, nameCheck, returnStatus), i * 400);
	}
    //button functions
	document.getElementById("show-online-button").addEventListener("click", function() {

		var hideOffline = document.getElementsByClassName("Offline");
		for (let i = 0; i < hideOffline.length; i++) {
			if (hideOffline[i].style.visibility != "hidden") {
				hideOffline[i].style.visibility = "hidden";
			} else {
				hideOffline[i].style.visibility = "visible";
			}
		}
		var hideInvalid = document.getElementsByClassName("invalid");
		for (var g = 0; g < hideInvalid.length; g++) {
			if (hideInvalid[g].style.visibility != "hidden") {
				hideInvalid[g].style.visibility = "hidden";
			} else {
				hideInvalid[g].style.visibility = "visible";
			}
		}
		if (document.getElementById("show-online").innerHTML == "online only") {
			document.getElementById("show-online").innerHTML = "show all";
		} else {
			document.getElementById("show-online").innerHTML = "online only";
		}
	});
    //close-button

    //search - filter
	document.getElementById("filterbar").addEventListener("keyup", function() {

            //display all first
		for (let i = 0; i < chan.length; i++) {
			document.getElementById(chan[i]).style.display = "block";
		}
            //filter with keypress - without enter
            //filter function

            //searchquery
		var searchQuery = document.getElementById("filterbar").value;
            //declare a var for array of items to be filtered
		var filtered = filterItems(searchQuery);

            //if searchbar is blank and there is a keypress after it
            //shows all elements according to the original chan array
            //else disables elements according to filtered array

		for (let i = 0; i < filtered.length; i++) {
			document.getElementById(filtered[i]).style.display = "none";
		}
		filtered = chan;
	});
});
// or to query / not sure; if query -> add X'es to delete from the array (or the page) and use search to add ? maybe...

              
            
!
999px

Console