I have this fiddle that sorts items on my webpage. I can see it works by checking the console.log results. I just don't know how to make the results appear on the actual webpage -- the items sorted in order.
http://jsfiddle.net/AQFFq/21/
function myFunction() {
var elements = [].slice.call(document.getElementsByClassName("price"));
elements.sort(function(a, b) {
return parseFloat(b.innerHTML.substring(1)) - parseFloat(a.innerHTML.substring(1));
});
for (var i = 0; i < elements.length; i++)
elements[i].parentNode.appendChild(elements[i]);
console.log(elements);
}
Thanks.
as i mentioned in my comments you have a couple of problems with your sorting. 1 there isnt {} around your for loop so it is only running once. 2 your are appending the price to its own parent node and since the parent nodes are still in their original order the function does nothing. what you need to do is select the parent node that is the entire element you want to sort and append that to the first parent node your sortable items have in common. here is a jsfiddle for what i mean functioning fiddle ps i switched a and b in your sort function so that the result is actually different then the original page.
Related
I have this piece of code:
for (var i = 0, row; row = document.getElementById("myTbl").rows[i]; i++) {
row.cells[headCatg.cellIndex].classList.remove("red");
row.deleteCell(headCatg.cellIndex);
}
I need to remove the class "red" from each cell of the table column and then delete that column. The reason I need to remove class first, because it has been added to DOM by another cript and if I remove the column the class just appears in the next column.
When I run each of these commands (remove() and deleteCell()) individually in the loop, everything seem to work fine, but when I put them together, the column is removed but the class shifts to another column.
What am I missing?
You have to convert the HTMLcollection to an array
The reason why your code wasn't working properly it's because HTMLcollection returns a live NodeList which means when you use remove on each element in the collection the other elements gets rearranged and the length of the list get's smaller causing you to skip some of them so you should convert your html collection to an array using Array.from
row = document.getElementByClassName("myTbl")
rowarr=Array.from(row)
for (var i = 0, rowarr.length; i++) {
row[i].cells[headCatg.cellIndex].classList.remove("red");
row[i].deleteCell(headCatg.cellIndex);
}
As the title says, I need to sort my data depending on my first column which contains som rank names. I do not wan't it sorted alphabetically but rather in a order I define myself.
Example:
Admin_contact
Commissioner
Battalion Chief
Paramedic
I want them listed in that order using google scripts so it automatically sorts when data gets edited.
Hope someone can help me achieve this
Absolutely, you can create a google script function onEdit() in the spreadsheet which will fire each time you edit something.
There are a few ways to do it. One of the most obvious ones (probably not the best as it loops through the data a lot):
Using getLastColumn() and getLastRow() grab all the data. You then use 2 arrays. 1 is current and 1 is sorted.
Loop through the current array and if data[i][0] matches the rank, output it to the sorted array
After you finish one loop, change to the rank you expect next (keep them in an array and you can use a for loop with rank[n])
Loop the array until you run out of the ranks.lenght
So it would be something along the lines of
function onEdit()
//Get the data
rank = [rank1, rank2, rank3]
for (n=0 ; n < rank.lenght; n++) {
for (i = 0; i < data.lenght; i++)
if (data[i][0] === rank[n]) {
sorted[x] = data[i];
x++;
}
}
}
Though I would recommend to make it so you can manually run it instead of an onEdit. Or you can set it so only if the last row is edited, then to fire it (make a return at the start of the script if the edited row is less than getLastRow()+1
Try this code:
function customSort(array, arrayOrder, numColumn) {
var order = [];
// transpose vertical 2d array into 1d array
for (var i = 0; i < arrayOrder.length; i++) {
order.push(arrayOrder[i][0]);
}
// sort
return array.sort(function (a, b) {
return order.indexOf(a[numColumn-1]) - order.indexOf(b[numColumn-1]);
});
}
Here's the use like custom function:
Same example for column 2:
I have multiple 'li' elements:
$(".my_lis")
with on the page I want to shuffle them around with JavaScript (I'm using JQuery). How to do that?
It's not too hard actually. The general idea is:
Grab all the dom nodes
Shuffle them
Empty the <ul> and insert the shuffled nodes
--
var items = $('.my_list li').get();
//edit (per comments): avoid confusion
items = shuffle(items);
$('.my_list').empty().append(items);
Where shuffle() can be anything that shuffles the array, I prefer underscore.js but here is a vanilla JavaScript way of doing a shuffle on an Array:
Just an example on shuffling ANY array
function shuffle(items) {
for(var index = 0, ln = items.length; index < ln; index++) {
var item = items[index],
swapIndex = ~~(Math.random() * ln),
swapItem = items[swapIndex];
//Swap places
items.splice(swapIndex, 1, item);
items.splice(index, 1, swapItem);
}
return items;
}
A reliable option is to insert a temporary dummy element after each element in the jQuery collection, then shuffle the current collection, and replace the elements in the dummy collection with elements from the shuffled list.
When appending a DOM element to another place, the element is automatically removed from the previous place.
Working demo: http://jsfiddle.net/ryEHm/2/
Code:
var $collection = $(".my_list li");
var shuffled = [];
$collection.each(function() {
shuffled.push(this); //Push DOM element
}).after('<span class="dummy"/>');
$('span.dummy').each(function(index) {
$(this).replaceWith(shuffled.splice(Math.random()*shuffled.length),1);
});
Maybe this plugin from James Padolsey helps you: http://css-tricks.com/snippets/jquery/shuffle-dom-elements/
Simply use it like this:
$('.my_lis').shuffle();
Here's a demo: http://jsfiddle.net/y4kyw/ – Press run to shuffle the list again
You can check out the jQuery Sortable plugin which has great examples and code walkthroughs/samples here:
http://jqueryui.com/demos/sortable/
jsfiddle demo
using
jQuery plugin to randomly reorder child elements with callback — Gist
to use: $(".my_lis").reorder();
I have the following piece of code that finds all elements in the document with classname foo and then removes them all
function(doc) {
var items = doc.getElementsByClassName('foo');
alert(items.length);
if(items.length>0) {
for(var i=0;i<items.length;i++) {
alert(i);
doc.body.removeChild(items[i]);
}
}
Forexample, the items.length is 3 and the function exits after running one loop and when the length is 8 it exits at 3. Any help would be greatly appreciated. Also, when I run the function again and again it does eventually remove all elements.
Your problem is that the NodeList returned by getElementsByClassName() is live. Either convert it into an array first as Felix suggests or iterate backwards:
var items = doc.getElementsByClassName('foo');
var i = items.length;
while (i--) {
items[i].parentNode.removeChild(items[i]);
}
This works because the item removed from the list each iteration is the last item in the list, therefore not affecting earlier items.
I also changed doc.body to items[i].parentNode for greater generality, in case you need to deal with elements that are not direct children of the <body> element.
The problem is that items is a live NodeList, i.e. whenever you access a property of the list (items.length), the list is reevaluated (elements are searched again).
Since you delete elements in the meantime, the list becomes shorter, but you keep the index.
You could convert the NodeList to an array first:
var items = [].slice.call(doc.getElementsByClassName('foo'));
The array size won't change when you delete the DOM elements.
I was trying to delete elements with a particular class name, but it doesnt work. Any idea why?
function delete_elems(){
var my_elems = document.getElementsByClassName("my_elem");
for(k=0; k<my_elems.length; k++){
my_elems[k].parentElement.removeChild(my_elems[k]);
}
}
I also tried:
function delete_elems(parentElem){
var my_elems = document.getElementsByClassName("my_elem");
for(k=0; k<my_elems.length; k++){
parentElem.removeChild(my_elems[k]);
}
}
Begin at the end:
for(k=my_elems.length-1;k>=0; --k)
http://jsfiddle.net/doktormolle/fDNqq/
The getElementsByClassName method returns a live node list, so iterating over it using an index and at the same time modifying the list (by removing nodes from the document) means that as elements are removed, the list is modified so what started as a list with 10 members will only have 9 once one is removed. If you remove item 0, then all items are re-indexed so what was item 1 is now 0, 2 is 1 and so on up to 8 (since there are only 9 left).
As noted by Dr. Molle, you may be able to avoid this issue by iterating over the list from the end.
You can avoid a counter altogether:
var el;
while ((el = my_elems[0])) {
el.parentNode.removeChild(el);
}
Note that when using a NodeList, each time an element is removed, the list must be re-generated by the browser (regardless of which of the above methods is used) so this method will likely be slow where the nodeList is large.
You can avoid that by converting the list to an array first (simply iterate over it) in which case you can use either an incrementing or decrementing counter and not worry about missing members in the list (since it isn't modified when elements are removed from the document).