I'm trying to sort divs by ID in Javascript. So far, I've got an array of divs split into "leftSlide" and "rightSlide". I'm doing it like so:
var leftSlides = [];
var rightSlides = [];
$(".ms-left").find("div").each(function(){ leftSlides.push(this.id); });
$(".ms-right").find("div").each(function(){ rightSlides.push(this.id); });
And my console output is:
// Left Divs
["slide0", "slide1", "slide2", "slide3", "slide4", "slide5", "slide6", "slide7", "slide8", "slide9", "slide10"]
// Right Divs
["slide-right0", "", "slide-right1", "", "slide-right2", "", "slide-right3", "", "slide-right4", "", "slide-right5", "", "slide-right6", "", "slide-right7", "", "slide-right8", "", "slide-right9", "", "slide-right10", ""]
Now I want to re-order my divs so they go something like this:
<div id="slide0"></div>
<div id="slide-right0"></div>
<div id="slide1"></div>
<div id="slide-right1"></div>
<div id="slide2"></div>
<div id="slide-right2"></div>
...and so on.
I notice that there's an errant empty div in the "slide-right" divs, but it's probably ok for them to be ignored, and if not, I'll try to find some logic to not add them to the array if they're empty. For now just trying to sort properly.
Any tips?
Assuming your slides will always have the same length on the left side and the right side and are ordered correctly you can use this code.
Please specify if you could have any other case!
var leftSlides = [];
var rightSlides = [];
$(".ms-left").find("div[id]").each(function(){ leftSlides.push(this); });
$(".ms-right").find("div[id]").each(function(){ rightSlides.push(this); });
$all = $(".all");
for (var i=0; i<leftSlides.length; i++) {
$all.append(leftSlides[i]);
$all.append(rightSlides[i]);
}
This code selects only divswith an id and then iterates trough the leftSlides array and pushes the elements from both arrays into one, first left then right.
jsBin demo
if you remove "-right" from "slide-right0" you'll get the matching pair "slide0":
$(".ms-right").find("div").prop("id", function(i, id){
$("#"+ id.replace("-right","")).after( this );
}).end().remove(); // After all is moved remove the .ms-right element.
div{
padding:5px; margin:5px;
background:rgba(255,0,0,0.2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ms-left">
<div id="slide0">0</div>
<div id="slide1">1</div>
<div id="slide2">2</div>
<div id="slide3">3</div>
<div id="slide4">4</div>
<div id="slide13">13</div>
</div>
<div class="ms-right">
<div id="slide-right0">r0</div>
<div>no ID</div>
<div id="slide-right1">r1</div>
<div>no ID</div>
<div id="slide-right2">r2</div>
<div>no ID</div>
<div id="slide-right3">r3</div>
<div>no ID</div>
<div id="slide-right4">r4</div>
<div>no ID</div>
<div id="slide-right13">r13</div>
</div>
I have't try this code, just give you a tip.
var leftSlides = [];
var rightSlides = [];
$(".ms-left").find("div").each(function(){ leftSlides.push(this.id); });
$(".ms-right").find("div").each(function(){ rightSlides.push(this.id); });
$('#yourNewWrapper').html(function(){
var allLeft = $('.ms-left').find('div');
var allRight = $('.ms-right').find('div');
var longLength = allLeft.length > allRight.length ? allLeft.length : allRight.length;
var divHtmlCache = [];
for(var i = 0; i < longLength; i++){
var eachLeft = allLeft.eq(i).length ? allLeft.eq(i) : null;
var eachRight = allRight.eq(i).length ? allRight(i) : null;
divHtmlCache.push(eachLeft ? eachLeft.html() : '' );
divHtmlCache.push(eachRight ? eachRight.html() : '');
}
return divHtmlCache.join('');
});
You may try. I did not use any special function except for $.insertBefore for moving the elements as needed.
for(var x=0; x < $('div').length; x++)
{
for(var i=0; i < $('div').length; i++)
{
if((i+1) < $('div').length)
CompareDivs( $('div')[i], $('div')[i+1]);
}
}
function CompareDivs(curr,next)
{
var curr_idNum = $(curr).attr("id").substring($(curr).attr("id").length - 1,$(curr).attr("id").length);
var next_idNum = $(next).attr("id").substring($(next).attr("id").length - 1,$(next).attr("id").length);
if(curr_idNum > next_idNum)
{
$(next).insertBefore($(curr));
}
}
Working example : https://jsfiddle.net/DinoMyte/3h78pjkh/1/
You could try something like this:
var leftSlides = [];
var rightSlides = [];
$(".ms-left").find("div").each(function(){ leftSlides.push(this); });
$(".ms-right").find("div").each(function(){ rightSlides.push(this); });
$all = $(".all");
for (var i=0; i<leftSlides.length; i++) {
$all.append(leftSlides[i]);
$all.append(rightSlides[i*2]);
}
https://jsfiddle.net/edoLtp1h/
Related
I use this code for get data-isAirTour attribute but always is undefined.
var tours = $('#WrapTours').find('div.tour');
var toursTmp;
var length = tours.length;
for (var i = 0; i < length; i++) {
if (tours.eq(i).value.data('isForeignTour') == isForeignTour) {
toursTmp.push(tours[i]);
}
}
html:
<div class="col-sms-6 col-sm-6 col-md-3 tour" data-isAirTour="#item.IsAirTour" data-isForeignTour="#item.IsForeignTour" data-TourType="#item.TourType">
</div>
How to solve this?
tours[i] will return DOM element. To get jQuery object use .eq(index), to get the object at index then you can use jQuery methods like .attr()
tours.eq(i).attr('data-isAirTour')
Apart from the other proposed solutions, you can also use the vanilla JS getAttribute() method, like so:
var tours = $('#WrapTours').find('div.tour');
for (var i = 0; i < tours.length; i++) {
var attr01 = tours[i].getAttribute("data-isAirTour");
console.log(attr01);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="WrapTours">
<div class="tour" data-isAirTour="yes"></div>
</div>
Alternatively, you can use dataset.isairtour (remember to keep it all in lowercase) to achieve the same result:
var tours = $('#WrapTours').find('div.tour');
for (var i = 0; i < tours.length; i++) {
var attr01 = tours[i].dataset.isairtour;
console.log(attr01);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="WrapTours">
<div class="tour" data-isAirTour="yes"></div>
</div>
I want to find div element that contain custom attribute mod than append that div to list item. But first I have to remove divs that contain duplicate mod value. Here's what I have done
<div class="list"></div>
<div class="container">
<div mod="dog"></div>
<div mod="man"></div>
<div mod="woman"></div>
<div mod="dog"></div>
<div mod="bird"></div>
<div mod="insects"></div>
<div mod="dog"></div>
</div>
this is my script
modArr($('.container').find('[mod]'))
function modArr(el){
var filterArray = [] // store mod
, modNames = [] // store mod value
, arrIndex = [] // store non duplicate index
, li = [] // store
modArray = el
// store mod value
for(var i=0; i < modArray.length; i++){
modNames.push($(modArray[i]).attr('mod')) // get mod value from div
}
// search for non duplicate mod value and get the index of none duplicate mod
for(var i=0; i < modArray.length; i++){
if(filterArray.indexOf(modNames[i]) === -1){
filterArray.push(modNames[i])
arrIndex.push(i) // push non duplicate index value
}
}
filterArray = [] // reset filterArray
// push module from modArray to filterArray using index in arrIndex
for(var i=0; i < arrIndex.length; i++){
filterArray.push(modArray[arrIndex[i]])
}
// push to li array
$.each(filterArray,function(i,el){
li[i] = '<li>'+ el.outerHTML +'</li>'
})
$('<ul></ul>')
.append(li.join(''))
.appendTo('.list')
}
What you can see is that I've used to many loops, is there any simple way to do this. Thanks!
We can use an object as a map for checking duplicates, see comments (I've added text to the mod divs so we can see them):
modArr($('.container').find('[mod]'));
function modArr(elements) {
// A place to remember the mods we've seen
var knownMods = Object.create(null);
// Create the list
var ul = $("<ul></ul>");
// Loop the divs
elements.each(function() {
// Get this mod value
var mod = this.getAttribute("mod");
// Already have one?
if (!knownMods[mod]) {
// No, add it
knownMods[mod] = true;
ul.append($("<li></li>").append(this.cloneNode(true)));
}
});
// Put the list in the .list element
ul.appendTo(".list");
}
<div class="list"></div>
<div class="container">
<div mod="dog">dog</div>
<div mod="man">man</div>
<div mod="woman">woman</div>
<div mod="dog">dog</div>
<div mod="bird">bird</div>
<div mod="insects">insects</div>
<div mod="dog">dog</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
We can also just use the DOM to check for duplicates, but it's a bit slower (not that it matters for the number of elements here):
modArr($('.container').find('[mod]'));
function modArr(elements) {
// Create the list
var ul = $("<ul></ul>");
// Loop the divs
elements.each(function() {
// Get this mod value
var mod = this.getAttribute("mod");
// Already have one?
if (ul.find('div[mod="' + mod + '"]').length == 0) {
// No, add it
ul.append($("<li></li>").append(this.cloneNode(true)));
}
});
// Put the list in the .list element
ul.appendTo(".list");
}
<div class="list"></div>
<div class="container">
<div mod="dog">dog</div>
<div mod="man">man</div>
<div mod="woman">woman</div>
<div mod="dog">dog</div>
<div mod="bird">bird</div>
<div mod="insects">insects</div>
<div mod="dog">dog</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note: I used this.cloneNode(true) rather than outerHTML because there's no need to take a roundtrip through markup. If you want more jQuery there, it's $(this).clone(); ;-) Similarly, if you don't like this.getAttribute("mod"), there's $(this).attr("mod").
I'd be remiss if I didn't point out that mod is an invalid attribute name for div elements. You can use any name you want starting with data-, though, so perhaps use <div data-mod="dog"> instead.
Try this, only adds if an element with mod is not already in list:
$('.list').append('<ul>');
$('.container [mod]').each(function(index, el) {
if($('.list [mod=' + $(el).attr('mod') + ']').length === 0) {
$('.list ul').append($('<li>' + el.outerHTML + '</li>'));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="list"></div>
<div class="container">
<div mod="dog">Dog1</div>
<div mod="man">Man1</div>
<div mod="woman">Woman1</div>
<div mod="dog">Dog2</div>
<div mod="bird">Bird1</div>
<div mod="insects">Insect1</div>
<div mod="dog">Dog3</div>
</div>
http://jsfiddle.net/rfnslyr/CRqXm/1/
I have the following fiddle which extracts CSS classes and ID's, and posts them to console. I want to type a name into the top box, paste some code, and have it generate a separate set of unique css ID's and classes into a new instance of the #classes instance (which has uin0CE + a bunch of classes in it).
I have that posting to console done, I just don't know how to "spawn" a new instance of the the #classes section on submit every time I add a new name to #codeName and code to #codeInput.
index.html
<div id="container">
<input id="codeName" class="boxsizingBorder"></input><br>
<textarea id="codeInput" class="boxsizingBorder"></textarea><br>
<button id="submitCode">submit</button>
<div id="classes">
<div class="pageTitle">uin0CE</div>
<div class="cssClassesIDs">
ui-icon-nodisc,redDotClass,translate,test,ui-hide-label,ui-grid-a,ui-block-a,ui-block-b,alignRight,ui-grid-solo,ui-disabled,companyFieldset,longbutton,icon-map-marker,locationIcon,icon-phone,contactIcon,legalBlock,legal,legalDivider,signInInfoIcon,icon-info-sign,ui-icon-alt
</div>
</div>
</div>
<script src="functions.js"></script>
functions.js
$(function() {
$('#submitCode').click(function() {
var CSS_CLASSES = [];
var CSS_IDS = [];
var el = document.createElement( 'div' );
var text = $("#codeInput").val();
el.innerHTML = text;
var nodes = el.getElementsByTagName('*');
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.id.length > 0) {
CSS_IDS.push.apply(CSS_IDS, node.id.split(" "));
}
if (node.className.length > 0) {
CSS_CLASSES.push.apply(CSS_CLASSES, node.className.split(" "));
}
}
var uniqueNames = [];
$.each (CSS_CLASSES, function(i, el){
if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});
console.log(uniqueNames + " --- " + uniqueNames.length);
});
});
Edit: I added this to your fiddle:
//Added this section here
var name = $('#codeName').val();
var code = uniqueNames;
$('#classes').empty();
$('#classes').append('<div class="pageTitle">'+name+'</div>');
$('#classes').append('<div class="cssClassesIDs">'+code+'</div>');
Here's the updated fiddle: http://jsfiddle.net/CRqXm/4/
I'm hoping I'm following your question correctly, but this seems to be what you're looking for.
Here I am going to make a tag cloud manually.Everything is going well but I face a little problem. Below is my code :
HTML:
<ul id="tagCloud">
<li id="tagcloud_li">Item1</li>
<li id="tagcloud_li">Item2</li>
</ul>
<div id="vis">
<div class="set_texts">
</div>
</div>
JavaScript :
$(function() {
var liArray = document.getElementsByTagName('li');
var list_item = [];
for(var i=0; i < liArray.length ;i++){
list_item.push($(liArray[i]).text());
var get_item_value = ($(liArray[i]).text());
var create_text = $('#vis').find('.set_texts').append($('<a href="" id="tagcloud_list" class="tagcloud_li'+i+'">'));
$('#vis').find(".tagcloud_li"+i).text($(liArray[i]).text());
}
var count_li = $('#vis').find('#tagcloud_list').length+1;
for(var i=0; i < liArray.length ;i++){
for(var j = 0; j < count_li; j++){
if(i == j){
var get_item_value = ($(liArray[i]).text());
var get_class = $('#vis').find('a').text(get_item_value).append(get_class);
}
}
}
});
Output of this code is :
Item2
Item2
In this output both contain value 'Item2'.
But I want to get value 'item1' in first tag 'a' and value 'item2' in second tag 'a' .Like :
Item1
Item2
How I can get this?
HTML:
<ul id="tagCloud">
<li id="tagcloud_li">Item1</li>
<li id="tagcloud_li">Item2</li>
</ul>
<div id="vis">
<div class="set_texts"></div>
</div>
CSS:
.set_text {
height:500px;
width:500px;
background-color:#FFFFFF;
font-family:Arial;
border: 1px solid #FFFFFF;
text-align:left;
}
.tagcloud {
font-size:12px;
text-decoration:none;
color: #FF7600;
}
JS:
$(function () {
var container = $("#vis").find(".set_texts");
$("#tagCloud").find('li').each(function (i) {
$('<a href="" id="tagcloud_list" class="tagcloud tagcloud_li' + i + '"/>').text($(this).text()).appendTo(container);
});
});
Sample: (Fiddle)
Created tag cloud is simple but it's what your code does.
Your code is very complex and thus you won't see the point for sure. I.e.,
var liArray = document.getElementsByTagName('li');
var list_item = [];
for(var i=0; i < liArray.length ;i++){
list_item.push($(liArray[i]).text());
var get_item_value = ($(liArray[i]).text());
var create_text = $('#vis').find('.set_texts').append($('<a href="" id="tagcloud_list" class="tagcloud_li'+i+'" style="font-size:12px;text-decoration:none; color: #FF7600;">'));
$('#vis').find(".tagcloud_li"+i).text($(liArray[i]).text());
}
might be reduced to this:
$("li").each(function() {
var item = $(this);
var text = item.text();
$('<a href="" class="tagcloud_list" id="tagcloud_li'+i+'" style="font-size:12px;text-decoration:none; color: #FF7600;">')
.text( text )
.appendTo( $('#vis').find('.set_texts') );
});
Your example of this loop is fetching same information from DOM several times and drops it in one of those cases. That's expensive by means of performance. Next you might reverse way of adding the <a> so you won't need to add it to the target container first just to get query that one to give it back afterwards.
The resulting <a> are all using same ID which is bad, too. So try swapping class and ID.
According to your issue this code seems to be crucial:
var get_class = $('#vis').find('a').text(get_item_value).append(get_class);
It is finding all <a> in your target assigning single text to all of them.
Change your Javascript to this.. And I used Jquery..
$(document).ready(function(){
var liArray = $("li");
var i;
for(i=0;i < liArray.length;i++){
$("div.set_texts").append('' + liArray[i].innerHTML + '');
}
});
I want to create a list of clickable divs from arrays using Javascript, where the list structure has to be something like this:-
<div id="outerContainer">
<div id="listContainer">
<div id="listElement">
<div id="itemId"> </div>
<div id="itemTitle"> </div>
<div id="itemStatus"> </div>
</div>
<div id="listElement">
<div id="itemId"> </div>
<div id="itemTitle"> </div>
<div id="itemStatus"> </div>
</div>
</div>
</div>
I want to extract the values of itemId, itemTitle and itemStatus from three arrays itemIdData[ ], itemTitleData[ ] and itemStatusData[ ] respectively, to create the whole list.
Also, when I click on any of the listElements, I want an alert showing the itemId. Can anyone help me with this problem.
If you're using jQuery, then try something like this:
$("#listContainer").on("click", "div", function () {
console.log("jQuery Event Delegation");
alert($(this).find(">:first-child").attr("id"));
});
It's possible to write the same thing without jQuery, but will take further lines of code - I'm conveying the idea of delegation here (there are extensive existing docs and examples on the JQuery site, and here on this site).
NB: the code you're submitted in the question can't(shouldn't) have multiple DOM elements with same IDs (that's what classes are for - for semantically similar elements). Also, trying to emulate a list using divs instead of li elements is perhaps not best practice.
After a bit of experimentation, understood what I was doing wrong and how to get it done.
Here's the code:-
var listContainer = document.createElement("div");
document.getElementById("outerContainer").appendChild(listContainer);
for (var i = 0; i < json.length; i++) {
//create the element container and attach it to listContainer.
var listElement = document.createElement("div");
listElement.id = i;
listElement.className = "listItemContainer";
listElement.addEventListener("click", function(e){
var itemId = e.target.children[1].innerHTML;
alert(itemId);
});
listContainer.appendChild(listElement);
//create and attach the subchilds for listElement.
var itemTitle = document.createElement("span");
itemTitle.innerHTML = postTitleData[i];
itemTitle.id = 'title'+i;
itemTitle.className = "itemTitle";
listElement.appendChild(itemTitle);
var itemId = document.createElement("div");
itemId.innerHTML = postIdData[i];
itemId.id = 'id'+i;
itemId.className = "itemId";
listElement.appendChild(itemId);
var itemStatus = document.createElement("span");
itemStatus.innerHTML = postStatusData[i];
itemStatus.id = 'status'+i;
itemStatus.className = "itemStatus";
listElement.appendChild(itemStatus);
}
Tried something like this which isn't quite working!
var listContainer = document.createElement("div");
document.getElementById("outerContainer").appendChild(listContainer);
var listElement = document.createElement("div");
listContainer.appendChild(listElement);
listElement.className = "listItemContainer";
for (var i = 0; i < json.length; i++) {
var itemId = document.createElement("div");
itemId.innerHTML = idData[i];
listElement.appendChild(itemId);
itemId.className = "itemId";
var itemTitle = document.createElement("div");
itemTitle.innerHTML = titleData[i];
listElement.appendChild(itemTitle);
itemTitle.className = "itemTitle";
var itemStatus = document.createElement("div");
itemStatus.innerHTML = statusData[i];
listElement.appendChild(itemStatus);
itemStatus.className = "itemStatus";
listElement.appendChild(document.createElement("hr"));
var elementId = 'ListElement'+i;
listElement.id = elementId;
listElement.addEventListener("click", function(){
alert(document.getElementById(elementId).innerHTML);
});
}