Very strange javascript sorting values behaviour - javascript

I have been messing around with this for hours and the only thing I can narrow it down to is that if there is 14 elements to sort, it doesn't work properly, but if there is thirteen, it works fine.
I am trying to do a basic sort of DIV elements by the price values they hold inside.
Here is the simple html -
<div class="wrap">
<button id="numBnt">Numerical</button>
<div id="container">
<div class="box">
<h2>£10.35</h2>
</div>
<div class="box">
<h2>£21.35</h2>
</div>
<div class="box">
<h2>£21.35</h2>
</div>
<div class="box">
<h2>£102.35</h2>
</div>
<div class="box">
<h2>£10.35</h2>
</div>
<div class="box">
<h2>£10.35</h2>
</div>
<div class="box">
<h2>£10.95</h2>
</div>
<div class="box">
<h2>£100.35</h2>
</div>
<div class="box">
<h2>£100.05</h2>
</div>
<div class="box">
<h2>£200.00</h2>
</div>
<div class="box">
<h2>£5510.25</h2>
</div>
<div class="box">
<h2>£19.80</h2>
</div>
<div class="box">
<h2>£5510.25</h2>
</div>
<div class="box">
<h2>£510.25</h2>
</div>
</div>
</div>
And the javascript
var $divs = $("div.box");
$('#numBnt').on('click', function () {
var numericallyOrderedDivs = $divs.sort(function (a, b) {
return parseFloat($(a).find("h2").text().replace(/£/g, '')) > parseFloat($(b).find("h2").text().replace(/£/g, ''));
});
$("#container").html(numericallyOrderedDivs);
});
With 13 div elements, the divs are sorted perfectly.
here is an example - http://jsfiddle.net/C2heg/380/
Then if I add another and make it 14 divs, the sort doesn't work correctly.
here is an example - http://jsfiddle.net/C2heg/378/
I am litrally banging my head of the table! Hopefully someone can shed some light on this.

Use a - b instead of a > b
$('#numBnt').on('click', function () {
var numericallyOrderedDivs = $divs.sort(function (a, b) {
return parseFloat($(a).find("h2").text().replace(/£/g, '')) - parseFloat($(b).find("h2").text().replace(/£/g, ''));
});
$("#container").html(numericallyOrderedDivs);
});
Demo: http://jsfiddle.net/C2heg/381/

Neither of your fiddles are working, and it has nothing to do with the number of elements.
This works though:
var $divs = $("div.box");
$('#numBnt').on('click', function () {
var numericallyOrderedDivs = $divs.sort(function (a, b) {
var a = parseFloat($(a).find("h2").text().replace(/£/g, ''));
var b = parseFloat($(b).find("h2").text().replace(/£/g, ''));
return a - b;
});
$("#container").html(numericallyOrderedDivs);
});
The sort function on comparing two items should return 0 if they are equal, a positive number if first is greater than second, a negative number otherwise.
Here's the updated fiddle.

Related

remove any child element after certain div index by javascript or jquery

i have this html collection, i want if i click on any div class ".sday"
any other div that are present after that be remove .
for example if we click on sday 2 we should keep sday1 and sday 2, and 3 and 4 must delete
my script removing count is ok but it delete wrong div.
any idea?
<div id="parent" class="parent">
<div class="room-sheet">
<div class="sday">1</div>
</div>
<div class="room-sheet">
<div class="sday">2</div>
</div>
<div class="room-sheet">
<div class="sday">3</div>
</div>
<div class="room-sheet">
<div class="sday">4</div>
</div>
</div>
script(using jquery)
<script>
$(".sday").click(function(){
console.log("hello");
var parentElement = $(this).parent().parent().find('.room-sheet');
var parentChildernCount = $(this).parent().parent().find('.room-sheet').length;
var elementIndex = $(this).closest('.room-sheet').index();
var dd = parentChildernCount - elementIndex;
for(let i=elementIndex; i < dd; i++){
//note: make sure any element after our index in deleted!!!
$("#parent").find('.room-sheet').children().eq(i).remove();
}
})
</script>
Listen for clicks on a .sday on the parent, navigate to the parent of the clicked .sday (a .room-sheet), call nextAll to get all subsequent siblings, and .remove() them:
$('#parent').on('click', '.sday', function() {
$(this).parent().nextAll().remove();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent" class="parent">
<div class="room-sheet">
<div class="sday">1</div>
</div>
<div class="room-sheet">
<div class="sday">2</div>
</div>
<div class="room-sheet">
<div class="sday">3</div>
</div>
<div class="room-sheet">
<div class="sday">4</div>
</div>
</div>
Also, there's no need to require a big library like jQuery for something this simple, you may implement this with native DOM methods, if you like:
document.querySelector('#parent').addEventListener('click', ({ target }) => {
if (!target.matches('.sday')) {
return;
}
const sheet = target.parentElement;
while (sheet.nextSibling) {
sheet.nextSibling.remove();
}
});
<div id="parent" class="parent">
<div class="room-sheet">
<div class="sday">1</div>
</div>
<div class="room-sheet">
<div class="sday">2</div>
</div>
<div class="room-sheet">
<div class="sday">3</div>
</div>
<div class="room-sheet">
<div class="sday">4</div>
</div>
</div>
Save the current number and the maximum number in variables then just iterate through them, making sure not to delete the clicked one:
$(".sday").on("click", function() {
let start = parseInt($(this).text());
let finish = parseInt($(".sday").last().text());
for (let i = start + 1; i <= finish; i++) {
$(`.sday:conatins(${i})`).remove();
}
});

Sort nested divs alphabetically

I have the following div layout:
<div class="container">
<div class="entry">
<div class="title">World</div>
<div class="description">text1</div>
</div>
<div class="entry">
<div class="title">hello</div>
<div class="description">text2</div>
</div>
<div class="entry">
<div class="title">Lorem</div>
<div class="description">text3</div>
</div>
</div>
I want to sort the entry divs alphabetically by the content of the child title div.
What I've tried so far
This will sort it alphabetically:
var alphabeticallyOrderedDivs = $('.title').sort(function(a, b) {
return String.prototype.localeCompare.call($(a).text().toLowerCase(), $(b).text().toLowerCase());
});
var container = $(".container");
container.detach().empty().append(alphabeticallyOrderedDivs);
$('body').append(container);
But it will strip the description divs. Try jsFiddle demo.
How can I sort the divs alphabetically without stripping anything?
Your logic is correct, but the issue is you're sorting the .title elements. Instead you need to sort the .entry elements, and then find the .title within the current .entry and perform the comparison on their text values. Try this:
var alphabeticallyOrderedDivs = $('.entry').sort(function(a, b) {
var $aTitle = $(a).find('.title'), $bTitle = $(b).find('.title');
return String.prototype.localeCompare.call($aTitle.text().toLowerCase(), $bTitle.text().toLowerCase());
});
var container = $(".container");
container.detach().empty().append(alphabeticallyOrderedDivs);
$('body').append(container);
.entry {
border: 1px solid #CCC;
padding: 5px;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<div class="container">
<div class="entry">
<div class="title">World</div>
<div class="description">text1</div>
</div>
<div class="entry">
<div class="title">hello</div>
<div class="description">text2</div>
</div>
<div class="entry">
<div class="title">Lorem</div>
<div class="description">text3</div>
</div>
</div>
How can I sort the divs alphabetically without stripping anything?
By sorting the right elements?
Why are you sorting .title, if as you stated the .entry elements are what you actually want to sort?
var alphabeticallyOrderedDivs = $('.entry').sort(function(a, b) {
return String.prototype.localeCompare.call(
$(a).find('.title').text().toLowerCase(),
$(b).find('.title').text().toLowerCase());
});
http://jsfiddle.net/yapu9a6m/1/
You just have to take the parent element with you when you sort. Then you go searching the child element after which you want to sort:
var alphabeticallyOrderedDivs = $('.entry').sort(function(a, b) {
return String.prototype.localeCompare.call($(a).find("div.title").text().toLowerCase(), $(b).find("div.title").text().toLowerCase());
});
You're sorting the titles, you should be sorting the entries.
So 1 tiny change:
var alphabeticallyOrderedDivs = $('.entry').sort(function(a, b) {
return String.prototype.localeCompare.call($(a).text().toLowerCase(), $(b).text().toLowerCase());
});
See updated fiddle

How to loop child divs parent by parent with respect to the horizontal level in jquery?

<div class="row">
<div class="parent">
<div class="child">child1</div>
<div class="child">child2</div>
<div class="child">child3</div>
</div>
<div class="parent">
<div class="child">child4</div>
<div class="child">child5</div>
<div class="child">child6</div>
</div>
<div class="parent">
<div class="child">child7</div>
<div class="child">child8</div>
<div class="child">child9</div>
</div>
<div class="parent">
<div class="child">child10</div>
<div class="child">child11</div>
<div class="child">child12</div>
</div>
<div class="parent">
<div class="child">child13</div>
<div class="child">child14</div>
<div class="child">child15</div>
</div>
<div class="parent">
<div class="child">child16</div>
<div class="child">child17</div>
<div class="child">child18</div>
</div>
</div>
I have sortable divs and i want to save the order of divs. But if i use jquery each function it loops parent divs and passing another parent after taking all childs of it vertically.What i am trying to do is getting child1,child4,child7,child10.. and so on. If we think this as a table i want to take values of cell row by row but jquery each doing this column by column.
The output that i want is 1,4,7,10,13,16,2,5,8,11,14,17,3,6,9,12,15,18
here is code in fiddle
Please check demo
var arr=[];
var count = $(".parent")[0].children.length;
for (var i = 0 ; i < count ; i++){
$(".parent").each(function(){
arr.push($(this.children[i]).text())
});
}
console.log(arr)
Please check this code made for you and let me know, If it's working for you or not.
var cnt = 0;
$(".parent:first-child .child").each(function () { cnt++; });
for (var i = 1; i <= cnt; i++) {
$(".parent").each(function () {
console.log($(this).children('.child:nth-child(' + i + ')').html());
});
}

I need to sort Bootstrap grid rows by title

I have a table that I have created in bootstrap 3 using the grid and NOT tables.
The website is for booking busses.
The table HTML structure looks something like this:
<div class="row">
<div class="col-lg-3"><h3>Bus Company</h3></div>
<div class="col-lg-3"><h3>Bus Features</h3></div>
<div class="col-lg-3"><h3>Departure Time</h3></div>
<div class="col-lg-3"><h3>Book Now</h3></div>
</div>
And then there's a loop that gets all the relevant search results...one of the iterations looks like this:
<div class="row busses">
<div class="col-lg-3"><p>Bus Company One</p></div>
<div class="col-lg-3"><p>Water, Toilet</p></div>
<div class="col-lg-3"><p>6:45 pm</p></div>
<div class="col-lg-3"><p>Book Now</p></div>
</div>
And that will repeat for every bus that matches the search criteria.
I would like to be able to click on any of the titles in the first row and then that sorts the results accordingly...or maybe just departure time and bus company (column 1 and column 3).
I have searched far and wide and ideally would just like a javascript plugin that I can use but everything I find seems to need to use an actual html <table> and I do not want to use that.
If anyone does know of a plugin it also needs to be able to sort by time as in...see that 2pm is later than 11am if you get what I mean.
Thanks in advance!
Matt
This could be achieved with something like this:
function sortBusses(byDatum, reverse) {
var busses = $('.busses').detach().toArray();
busses = busses.sort(function(a,b) {
var aVal = $(a).find('[data-target-attr='+byDatum+']').text();
var bVal = $(b).find('[data-target-attr='+byDatum+']').text();
// looks reversed because we use append later, not prepend
var returnVal = bVal < aVal ? 1 : -1;
if (reverse) returnVal = -returnVal;
return returnVal;
});
$(busses).appendTo('.busses-container');
}
$(document).ready(function() {
$('.busses-heading div').click(function() {
if ($(this).attr('data-target-attr')) {
var isReversed = $(this).attr('data-reversed');
reverse = (isReversed && isReversed==='false') ? true : false;
sortBusses($(this).attr('data-target-attr'), reverse);
$(this).attr('data-reversed', reverse);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="busses-container">
<div class="row busses-heading">
<div class="col-lg-3" data-target-attr="company"><h3>Bus Company</h3></div>
<div class="col-lg-3" data-target-attr="features"><h3>Bus Features</h3></div>
<div class="col-lg-3" data-target-attr="time"><h3>Departure Time</h3></div>
<div class="col-lg-3"><h3>Book Now</h3></div>
</div>
<div class="row busses">
<div class="col-lg-3"><p data-target-attr="company">Bus Company One</p></div>
<div class="col-lg-3"><p data-target-attr="time">6:45 pm</p></div>
<div class="col-lg-3"><p data-target-attr="features">Seats</p></div>
<div class="col-lg-3"><p>Book Now</p></div>
</div>
<div class="row busses">
<div class="col-lg-3"><p data-target-attr="company">Bus Company Two</p></div>
<div class="col-lg-3"><p data-target-attr="time">7:45 pm</p></div>
<div class="col-lg-3"><p data-target-attr="features">Water, Toilet</p></div>
<div class="col-lg-3"><p>Book Now</p></div>
</div>
<div class="row busses">
<div class="col-lg-3"><p data-target-attr="company">Bus Company Three</p></div>
<div class="col-lg-3"><p data-target-attr="time">8:45 pm</p></div>
<div class="col-lg-3"><p data-target-attr="features">Toilet</p></div>
<div class="col-lg-3"><p>Book Now</p></div>
</div>
</div>
However, since your data is tabular in nature, it would be advisable to go ahead and use a table
Thanks for that answer...that code looks pretty good but I actually ended up finding this little script which ended up doing everything for me quite nicely...and its jQuery independant too!
http://tinysort.sjeiti.com/

Sorting DIVs inside other DIVs [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to sort divs according to their id using jQuery?
Well I'm having a really hard time trying to solve this and I actually had no sucess until now, I'm trying to sort DIVs inside Other DIVs by ID.
So here's how my DIVs are distribuited in my page
<div id="products" >
<div class="line">
<div id="Album2">[there are images and even other divs here in each Album]</div>
<div id="Album1"></div>
<div id="Album10"></div>
<div id="Album16"></div>
</div>
<div class="line">
<div id="Album9"></div>
<div id="Album3"></div>
<div id="Album4"></div>
<div id="Album7"></div>
</div>
<div class="line">
<div id="Album5"></div>
<div id="Album11"></div>
<div id="Album6"></div>
<div id="Album13"></div>
</div>
<div class="line">
<div id="Album8"></div>
<div id="Album14"></div>
<div id="Album12"></div>
<div id="Album15"></div>
</div>
</div>
and this should be my output:
<div id="products" >
<div class="line">
<div id="Album1"></div>
<div id="Album2"></div>
<div id="Album3"></div>
<div id="Album4"></div>
</div>
<div class="line">
<div id="Album5"></div>
<div id="Album6"></div>
<div id="Album7"></div>
<div id="Album8"></div>
</div>
<div class="line">
<div id="Album9"></div>
<div id="Album10"></div>
<div id="Album11"></div>
<div id="Album12"></div>
</div>
<div class="line">
<div id="Album13"></div>
<div id="Album14"></div>
<div id="Album15"></div>
<div id="Album16"></div>
</div>
</div>
But I have one more problem, all my products are listed and there are more than one page, I was actually able to track them and made a sorted Array of Strings but I didn't had the same luck doing it with the DIVs.
This is my page:
http://biscoitofino.jumpseller.com/catalogo
Any suggestions?
Thanks in advance.
Something like this should do it, at least within the context of a single page:
var lines = $("#products .line");
var elems = $("#products .line div");
for (var index = 1; index <= elems.length; index++) {
var elemId = "Album" + index;
var containerIndex = parseInt((index - 1) / 4);
var container = lines[containerIndex];
var elem = document.getElementById(elemId);
elem.parentNode.removeChild(elem);
container.appendChild(elem);
}
Here's an example: http://jsfiddle.net/dpHyn/
Although I think the real answer is, since presumably you've got a server that's providing the list of albums dynamically already, why not just have the server sort the elements properly when it loads them from the database (or whatever other datasource you are using)? That would save you all this trouble, and work properly with pagination as well.
​
var lines = $("#products > .line"),
albums = lines.children().toArray(),
line = -1;
albums.sort(function(a, b) {
return a.id.replace("Album", "") - b.id.replace("Album", "");
});
$.each(albums, function(i, el) {
if (!(i % lines.length))
line += 1;
lines.eq(line).append(el);
});
or without jquery
var lines = document.querySelectorAll("#products > .line"),
line = -1;
[].slice.call(document.querySelectorAll("#products > .line > div"))
.sort(function(a,b) {
return a.id.replace("Album", "") - b.id.replace("Album", "");
})
.forEach(function(el, i) {
if (!(i % lines.length))
line += 1;
lines[line].appendChild(el);
});

Categories