how to make a div sortable? - javascript

I have a div table like for a page, is it possible to make it sortable like html table with javascript?
I moved from normal table because it was not possible for me to continue using it due to this How to add td rowspans to a table? and thus used the div table.
so I used this div table and the only thing im missing is how to make it sortable so I can sort it by item or price.. like datatables, tablesorter e.t.c
<div class="Header">
<div class="item">Item
</div>
<div class="desc">Description
</div>
<div class="price">Price
</div>
<div class="status">Status
</div>
</div>
<div class="Info">
<div class="itemName">
<div class="item">Item 1</div>
</div>
<div class="itemInfo">
<div class="List">
<div class="Desc">Description 1</div>
<div class="Box">
<div class="price">$79</div>
<div class="status">16 in stock</div>
</div>
</div>
</div>
</div>
full code here http://codepen.io/anon/pen/empqyN?editors=110 and here http://jsfiddle.net/a4fcxzra/

Here is a sorting handler: (the header classes need to be the same as where the info is, so changed in the header desc to Desc)
var sorting=1;
$(".Header div").each(function(){
$(this).click(function(){
var cl=$(this).attr("class") // get header class, this is where I get info from
sorting = sorting == 1 ? -1 : 1 ; // sorting asc or desc
$(".Info").detach().sort(function(a,b){
var str1=$(a).find('.'+cl).text(); // get text
var str2=$(b).find('.'+cl).text();
var n1 = str1.match(/\d+/)[0] //get digits in text
var n2 = str2.match(/\d+/)[0]
if(n1 != '' ){ // if its a number
return n1*sorting > n2*sorting; // sort by number
}else{ // sort by string
return sorting == 1 ? str1 > str2 : str1 < str2
}
}).appendTo($(".Header").parent());
})
})
Working Fiddle: http://jsfiddle.net/juvian/a4fcxzra/1/

You can sort an Array using JavaScript and then creating tags dynamically to place them within the column headers (which you should create in the html for better performance)

Related

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/

JQuery loop through div and build multi-line string based on data attribute

I have two questions:
1.) As you can see I have multiple divs and I have onclick things going on when the callout panel notes div is clicked. It accesses the data-category attribute. I'm using
$(this).parent().parent().siblings().first().data("category");
To access it, which works, but it seems messy. I tried parents().last().data(...) but that never worked. I feel like there's a more efficient way. So any opinions would be appreciated.
2.) My next question I can't figure out. Some of the divs have the selected class (after I click on the div). Later I'm going to hit a button to grab the selected stuff, and send it through some ajax stuff. There are 5 other "categories" so I need the .selected content to be associated with the data-category="a", ie, I need to make sure it only loops withing the that category. Can anyone help me loop through the data-category="a" and build a multi-line string with the data-response-text of the .selected classes?
The html is below:
<div class="row responses panel">
<div class="small-12 column" data-category="a">
<h3>Responses</h3>
</div>
<div class="small-12 column">
<div class="callout panel notes" data-response-text="Info 1">
Info 1
</div>
</div>
<div class="small-12 column">
<div class="callout panel notes selected" data-response-text="Info 2">
Info 2
</div>
</div>
<div class="small-12 column">
<div class="callout panel notes selected" data-response-text="Info 3">
Info 3
</div>
</div>
<div class="small-12 column">
<div class="callout panel notes selected" data-response-text="Info 4">
<div class="remove-response"></div>
Info 4
</div>
</div>
<div class="small-12 column">
<div class="add-new-box">
<div class="add-new">
Add Response
</div>
<div class="add-new-text">
<input class="text-response" type="text" placeholder="Response">
</div>
</div>
</div>
</div>
<div><span class="button">Submit</span></div>
For the first part you can do:
$(this).closest('.row.responses').children(':first').data('category');
If either .row or .responses are unique to that level elements, you can use that solely then.
For the second part, I assume "content to be associated with the data-category a" means elements insides .row.responses which firs element has data-category="a". If so then you can do:
var str = "";
var sls = $('[data-category="a"]').parent().find('.selected');
sls.each(function() {
str += $(this).data('response-text') + "\n";
});
First question: I would select the panel like so:
$(this).find('[data-category]').data();
I would then create a function that's called on each of the panels and then returns an array of the data you require from .selected
function getData(panel) {
var $selected = $(panel).find('.selected');
var dataArr = [];
for (var i = 0; i < $selected.length; i++) {
dataArr.push($selected.eq(i).data().responseText);
}
return dataArr;
}
var panelData = getData($('the-panel-in-question'));

wrap more than one nodes with div

How can i wrap exactly half of the div's with another div using jquery or javascript
I have this
<div class="post">1</div>
<div class="post">2</div>
<div class="post">3</div>
<div class="post">4</div>
<div class="post">5</div>
<div class="post">6</div>
I want this
<div class="wrap">
<div class="post">1</div>
<div class="post">2</div>
<div class="post">3</div>
</div>
<div class="wrap">
<div class="post">4</div>
<div class="post">5</div>
<div class="post">6</div>
</div>
Try using this:
var posts = $('.post'),
postCount = posts.length,
postHalf = Math.round(postCount/2),
wrapHTML = '<div class="wrap"></div>';
posts.slice(0, postHalf).wrapAll(wrapHTML); // .slice(0, 3)
posts.slice(postHalf, postCount).wrapAll(wrapHTML); // .slice(3, 6)
This selects all .post, gets the number of elements found then halves that value to get the splitting point. It then uses .slice() to select a specific range of elements and .wrapAll() to wrap each selection in <div class="wrap"></div>.
Here it is working: http://jsfiddle.net/ekzrb/

JQuery order div by value and skip if value is zero

I've done my ordering in my code but instead of reloading the whole json result, I want a client side reorder for my divs.
My C# code for ordering is:
.OrderBy(p=> p.order == 0? int.MaxValue : p.order);
This give me result like
1
2
3
4
0
0
0
My Html schema is like
<div class="item" data-sort="0" id="5051fb7c746eed1bf05309db">
<span>Some values</span>
<span>Some values</span>
<div class="subgroups">
<div class="item" data-sort="null" id="5060de4a746eed1b44cc6e90"></div>
</div> <!-- closing subgroups -->
</div> <!-- closing main div which need to be sorted -->
<div class="item" data-sort="2" id="5051fb7c746eed1bf05309db">
<span>Some values</span>
<span>Some values</span>
<div class="subgroups">
<div class="item" data-sort="null" id="5060de4a746eed1b44cc6e90"></div>
</div> <!-- closing subgroups -->
</div> <!-- closing main div which need to be sorted -->
<div class="item" data-sort="0" id="5051fb7c746eed1bf05309db">
<span>Some values</span>
<span>Some values</span>
<div class="subgroups">
<div class="item" data-sort="null" id="5060de4a746eed1b44cc6e90"></div>
</div> <!-- closing subgroups -->
</div> <!-- closing main div which need to be sorted -->
How can I reorder these divs so that the 2nd one become first and those with 0 data will be last upon reordering.
Take a look at the jQuery plugin TinySort if you're using jQuery. Here is an example of its use:
$(".item").tsort({ attr: 'data-sort',order:'desc'});
I think if you can output 0 or -1 instead of null to the data-sort attribute it should put those items at the end.
You can also do like this:
Put all your divs inside a parent div
<div id="parentDiv">
..
</div>
Then you can sort like this
$(function(){
function sort_comp(a, b){
var k1 = parseInt($(a).attr("data-sort"),10);
if(k1 === 0) k1 = Number.MAX_VALUE;
var k2 = parseInt($(b).attr("data-sort"),10);
if(k2 === 0) k2 = Number.MAX_VALUE;
return (k1-k2);
}
var arr = $.makeArray($("#parentDiv > .item"));
arr.sort(sort_comp);
$("#parentDiv > .item").remove();
$(arr).each(function(){
$("#parentDiv").append($(this));
});
});

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