Sort divs (added dynamically) by classname - javascript

I have been struggling to find a way in which I could sort Divs after being displayed .So far, I have used prepend() and append() and I have managed to show at first the players that are streaming, but the next divs are random. I want to be able to show who's online, who's not and who has closed the account in order.
I have already tried deferred method: $.when(makeDivs()).then(sortDivs());
but it's not working properly, any idea how I can fix this?
My codepen: http://codepen.io/diegomdzr/pen/vKWGbd

I don't have the reputation to comment yet. But from my understanding, you want to make the classNames of divs in alphabetical order after they have been applied to the document?
function reOrder() {
var div = document.getElementsByTagName('div');
var cn = []; //ClassNames of each div.
for (var i = 0; i < div.length; i++) {
cn.push(div[i].className);
}
cn = cn.sort(); //sort the array in alphabetical order.
var oDiv = [];
for (var i = 0; i < cn.length; i++) {
//for each array item in cn, find where it's element is, remove the element, continue.
for (var ii = 0; ii < div.length; ii++) {
if (div[ii].className == cn[i]) {
oDiv.push(div[ii]);
var newDiv = [];
for (var iii = 0; iii < div.length; iii++) {
//Remove the element from the array.
if (div[iii] != div[ii]) {
newDiv.push(div[iii]);
}
}
div = newDiv;
}
}
}
return oDiv;
};
reOrder();
This will return an array of the elements, but sorted. You can then replace all of the elements of the document with these sorted elements.

Sorting is expensive, should be avoided if possible, and isn't a particularly good solution here.
It's way simpler to create a container (div) for each of your streamer categories, (online|offlie|nonExistent) then simply append HTML, as it is generated, to the appropriate container.
$(document).ready(function() {
var streamers = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas", "comster404", "brunofin", "HorussTV"];
var link = "https://twitch.com/";
// Create/append containers here (or hard-code them in HTML) ... in correct order of presentation within #streamers.
var $onlineStreamers = $("<div/>").appendTo($('#streamers'));
var $offlineStreamers = $("<div/>").appendTo($('#streamers'));
var $nonExistantStreamers = $("<div/>").appendTo($('#streamers'));
streamers.forEach(function getStatus(element) {
$.getJSON("https://api.twitch.tv/kraken/channels/" + element + "?callback=?", function(json) {
var img = json.logo || "http://res.cloudinary.com/djnwhbm1z/image/upload/v1468187598/unknown_i7m43p.png";
$.getJSON("https://api.twitch.tv/kraken/streams/" + element + "?callback=?", function(json) {
// Append HTML to the appropriate container
if(json.stream) {
$onlineStreamers.append('<div class="online"><h4>' + element + '</h4><img src="' + img + '" class="profPic"><div class="content text-center"><span><b>Game:</b></br>' + json.stream.game + ' </br><b>Status: </b>' + json.stream.channel.status + '</span></div></div>');
} else if(json.status == 422) {
$nonExistantStreamers.append('<div class="nonExistant"><h4>' + element + '</h4><img src="' + img + '" class="profPic"><div class="content text-center"><span>Account Closed</span></div></div>');
} else {
$offlineStreamers.append('<div class="offline"><h4>' + element + '</h4><img src="' + img + '" class="profPic"><div class="content text-center"><span>Offline</span></div></div>');
}
});
});
});
});
Notes:
No sorting required unless the entries need to be sorted within each category.
You can probably purge class="online" etc from the appended HTML, unless those classes are used elsewhere.

Related

How to find visible child in hidden parent

I want to show a div which has the error message span visible in it. I tried the following codes but it works only when the container is visible otherwise it is unable to find in it.
Can someone share the reason and solution to it?
Code 1:
Using .length
$(".has-warning:visible").each(function() {
var id = this.id;
var divs = ["wReq_div", "mcatIsq_div", "glDetail_div"];
for (var i = 0; i < divs.length; i++) {
if ($("#" + divs[i] + " #" + id).length) {
console.log("found in " + divs[i]);
return false;
}
}
});
This gives true for the container if it's visible otherwise not.
Code 2:
Using $.contains
$(".has-warning:visible").each(function(){
var id = this.id;
var divs = ["wReq_div","mcatIsq_div","glDetail_div"];
for(var i=0;i<divs.length;i++){
if($.contains($("#"+divs[i])[0],$("#"+id)[0])){
console.log("found in " + divs[i]);
return false;
}
}
});
It's also working only if the container is visible.
So my main problem is:
Parent is hidden and child has display not none, how to find that shown child in the hidden parent
To find that which parent div(hidden) has an error div with given id so that I can show that parent div.
Here is the CodePen
I don't want to use the method of changing class from a hidden one to visible one to display my errorMsg as I'll have to do a lot of changes in multiple files.
From the docs
jQuery( ":visible" )
Elements are considered visible if they consume space in the document. Visible elements have a width or height that is greater than zero.
If a parent is hidden, all it's children will also be hidden. So, $(".has-warning:visible") will not return the child elements, even if they're not hidden.
you need to rely on the display property of the child elements, rather than the :visible attribute and try something like this,
function checkMsg1(){
$(".has-warning").each(function() {
var id = this.id;
var i=0;
var divs = ["wReq_div", "mcatIsq_div", "glDetail_div"];
for (i = 0; i < divs.length; i++) {
if ($("#" + divs[i] +" #"+id).css("display") !== 'none') {
$("#" + divs[i]).show();
}
}
});
}
I used following code to overcome this problem, Please suggest if you have better one:
var divs = ["wReq_div","mcatIsq_div","glDetail_div"];
$(".has-warning").each(function(){
if($(this).css("display") != "none"){
var id = this.id;
for(var i=0;i<divs.length;i++){
if($.contains($("#"+divs[i])[0],$("#"+id)[0])){
console.log("found in " + divs[i]);
break;
}
}
}
});
But it first selects all the divs and may increase time.
you will not find .has-warning:visible as its parent is not visible. But you can check for parent div if it is hidden or not.
$(".has-warning").each(function() {
if($(this).css("display") != "none"){
var id = this.id;
var i=0;
var divs = ["wReq_div:hidden", "mcatIsq_div:hidden", "glDetail_div:hidden"];
for (i = 0; i < divs.length; i++) {
if ($("#" + divs[i] + " #" + id).length) {
alert("found in " + divs[i] + " " + id);
// Add code to display that div
}
else {
alert("not found in " + divs[i]+ " " + id);
}
}
}
});

My jquery is not adding div to correct node

var out = [];
out.push('<div class="newData">');
for (var i = 0; i < 5; i++) {
out.push('<img src="' + data.data[i].images.low_resolution.url + '"/>');
count++;
// if (data.pagination.next_url = "") flag++;
if (count > 4) {
myurl = data.pagination.next_url;
count = 0;
}
out.push('</div>');
$('#wrap').append(out);
I have this simple code but in inspect elements it shows.
<div id="wrap">
<div class="newdata"></div>
<img scr='"asd"/>
<img scr='"asd"/>
<img scr='"asd"/>
</div>
Why is is immediately closing the newdata div and why not putting photos in it?
Try using a string ,don't forget to close the for loop
var out = '';
out+='<div class="newData">';
for (var i = 0; i < 5; i++) {
out+='<img src="' + data.data[i].images.low_resolution.url + '"/>';
count++;
// if (data.pagination.next_url = "") flag++;
if (count > 4) {
myurl = data.pagination.next_url;
count = 0;
}
}
out+='</div>';
$('#wrap').append(out);
You have the div '<div class="newData">' start outside the for loop and you close it inside the for loop. Then you add it inside the loop. Make sure you add valid html when you append it to #wrap, then it will work.
Edit: Additionally as others have pointed out: use strings to add the strings to each other and then append.
The issue is because you can only append whole elements to the DOM. When you append the opening div tag, the browser will automatically close it for you. This means your img elements are then created as siblings.
You could instead change your logic to create the div container, then build the HTML string in a loop and append that together. Try this:
var $div = $('<div class="newData"></div>').appendTo('#wrap');
var html = '';
for (var i = 0; i < 5; i++) {
html += '<img src="' + data.data[i].images.low_resolution.url + '"/>');
}
$div.append(html);
You are not closing the loop, that causing you the problem
out+='</div>';
$('#wrap').append(out);
add this in last of your loop

Cloning a div using a For-Loop isn't giving the right amount of clones

I am trying to make a script that will clone a div, cards in bootstrap 4, and change text in the div. I want this to happen a certain number of times., depending on the variable. However, when I use the script below I'm getting 8 cards (7 clones), instead of the 3 clones that it is supposed to be making. Does anyone know what is happening here?
$(document).ready(function(){
var cards = 3;
var id = "";
var newClass = "";
var i;
for(i = 0; i < cards; i++) {
id = id + "1";
newClass = newClass + "1"
$(".listings").clone().addClass(newClass).appendTo("body");
$("."+newClass).attr("id",id);
$("#" + id + " " + "h1").text("$5000");
}
});
change
.addClass(newClass)
to
.prop("class",newClass)

Get index element which has a specific initial in listview

I have a problem with listview.
I'm filling the list with an array, this list is completely custom, and I want that if an element of this array begins with "-R", then that cell must be different from the others (color, font, etc.).
the problem is that I can not take the index of the cell that begins with "-R".
this is the code:
arrayEserCardio = "try;find;-Reply;Again;"
var indexEserSplit = arrayEserCardio.toString().split(";");
for (var i =0; i<indexEserSplit.length;i++) {
var eserSingle = indexEserSplit[i];
var link_markup ='<li id="listCardio2"><a onclick="rowSelectedEserCardio()" href="#" class="ui-link-inherit"><div class="textScheda"><p style="white-space: normal" class="titleEs">'+eserSingle+'</p></div></a></li>';
if(eserSingle.substring(0,2)=='-R') {
var initial = eserSingle.substring(0,2);
var index = arrayEserCardio.indexOf(initial);
//but index return wrong
}
}
I hope I was clear, I do not know javascript very well.. thanks to all
I would write it like this:
var
arrayEserCardio = "try;find;-Reply;Again;",
var indexEserSplit = arrayEserCardio.split(";"),
eserSingle,
link_markup,
i;
for (var i = 0; i < indexEserSplit.length; i++) {
eserSingle = indexEserSplit[i];
cls = "titleEs";
if (eserSingle.substring(0,2) == '-R') {
cls += " with_min_r";
}
link_markup ='<li id="listCardio2"><a onclick="rowSelectedEserCardio()" href="#" class="ui-link-inherit"><div class="textScheda"><p style="white-space: normal" class="' + cls + '">' + eserSingle + '</p></div></a></li>';
}
It should have been
if (eserSingle.substring(0, 2).equals("-R")) {
}
The == operator compares the object references, not the value of the Strings.

Using values from Array to execute function in jQuery

I have a page that contains several divs. The divs have the same postfixes but different prefixes. What I want to do is loop through them and if one of them contain a 0 hide the description div.
The divs look like this:
<div id="first_desc">First</div><div id="first_note1">0</div>
<div id="second_desc">Second</div><div id="second_note1"></div>
<div id="third_desc">Third</div><div id="third_note1"></div>
My script is this:
$(document).ready(function() {
// Variables
var firstdiv = 'first';
var seconddiv = 'second';
var thirddiv = 'third';
// Array
var myArray = new Array(firstdiv, seconddiv, thirddiv);
for(var x = 0; x < myArray.length; x++) {
if('$("#' + myArray[x] + '_note1").text() === $.trim("0")') {
'$("#' + myArray[x] + '_desc").hide()';
}
}
});
So far this code is not working. Can anyone help me? Thanks.
You have some extra ' in there.
if($("#" + myArray[x] + "_note1").text() === $.trim("0")) {
$("#" + myArray[x] + "_desc").hide();

Categories

Resources