Sort an unordered list alphabetically - javascript

I want to sort an unordered list alphabetically. I've tried many different javascript solutions, not one of them worked (tested in Safari and Chrome). This is the code I would like to use:
var activeLanguage = "de"
function sortUL(selector) {
var $ul = $(selector);
$ul.find('li').sort(function(a, b) {
var upA = $(a).text().toUpperCase();
var upB = $(b).text().toUpperCase();
return (upA < upB) ? -1 : (upA > upB) ? 1 : 0;
}).appendTo(selector);
};
$(document).ready(function() {
sortUL("#WoodList");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul id="WoodList">
<li>Banana</li>
<li>Catv</li>
<li>Apple</li>
<li>Orange</li>
<li>Car</li>
<li>Pear</li>
<li>Banana</li>
<li>Cat2</li>
<li>Apple4</li>
<li>Banana1</li>
<li>Cat</li>
<li>Apples</li>
<li>Banana</li>
<li>Cat</li>
</ul>
The list remains unsorted in the browser. Why is it not working ?

Here's a working example on JSFiddle: https://jsfiddle.net/vzbgzexc/
Make sure that you're loading jQuery. It doesn't look like anywhere in your code that you're loading jQuery, yet you're using $. You're likely receiving an error in your browser's console similar to this:
ReferenceError: $ is not defined
Insert:
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
Hope that helps!

Related

Is there a way to get the active categories from jQuery Filterizr?

I want to hide a single item unless a category is selected. I'm using the filteringStart callback to do this. How do I get the active categories array from the filterizr object?
It doesn't look like there's a public method to get active filters in the Filterizr library. It isn't too difficult to write the JavaScript required to figure it out though.
Using one of their examples, the html would look as follows:
<ul class="nav nav-gallery filters-filteringModeSingle" id="filteringModeSingle">
<li class="filtr-button filtr" data-fltr="all">All</li>
<li class="filtr-button filtr" data-fltr="green">Green</li>
<li class="filtr-button filtr filtr-active" data-fltr="orange">Orange</li>
<li class="filtr-button filtr" data-fltr="purple">Purple</li>
<li class="filtr-button filtr" data-fltr="mix">Mix</li>
</ul>
You could get an array of selected values as follows:
var selected = $.map($(".filtr-active").toArray(), function(el, i) {
return $(el).data("fltr");
});
To do something based on a specific value being selected, you could do the following:
if (selected.indexOf("green") !== -1) {
console.log("You selected green!");
}
I hope that makes sense!
Edit:
You could get the unselected filters by tweaking the selector.
var notSelected = $.map($(".filtr:not(.filtr-active)").toArray(), function (el, i) {
return $(el).data("fltr");
});
try this code
$(function () {
console.log($(this)[0].getAttribute("data-filter"));
});

target a <li> so that you can click

I am currently developing a program. It includes a 3 option navigation bar. It uses <li> and does not have id's, when i try to add id's to them it messes up the order, and doesent even work with a click! Im starting to loose faith with it.. can anyone help me on this one,
my GOAL is to have it alert different things on different clicks, so than I could link different html pages,
fiddle used HERE.
<ul class="ui-module menu-selector" id="menu-selector">
<li>Home</li>
<li class="js-is-active">Notif's</li>
<li>Profile</li>
</ul>
Since you don't have ids, I suppose that childNodes property will help a lot.
For example, you can use:
var lis = document.getElementById('menu-selector').childNodes;
// or you can select lis directly...
// var lis = document.querySelectorAll('#menu-selector li');
Array.prototype.slice.call(lis)
.forEach(function(li) {
// do something... like
li.onclick = function () {
console.log(this);
}
});
Note: childNodes (or querySelectorAll return) is NodeList type, and I use Array.prototype.slice.call() in order to use forEach() method on it.
See childNodes for more details.
if you don't want to have ids on your li elements for some reason you can use the following logic to select active li:
$("#menu-selector li.active").on("click", function(){
alert($(this).text())
});
I added id's for you, not sure what you meant by it messing up the order.
HTML
<div class="ui-items">
<header class="ui-module app-header">VoiceBox <i class="entypo-user-add"></i>
<i class="entypo-pencil"></i>
</header>
<div id="outer">
<ul class="ui-module menu-selector" id="menu-selector">
<li id="home_li">Home</li>
<li id="notif_li" class="js-is-active">Notif's</li>
<li id="profile_li">Profile</li>
</ul>
</div>
</div>
Javascript
var listItem = $('#menu-selector > li');
$(listItem).click(function() {
$(listItem).removeClass('js-is-active');
$(this).toggleClass('js-is-active');
});
$('#home_li').click(function(){
alert('home clicked')
})
$('#notif_li').click(function(){
alert('notifs clicked')
})
$('#profile_li').click(function(){
alert('profile clicked')
})
Fiddle http://jsfiddle.net/1swep9oq/2/

Optimize javascript/jQuery for better performance

I make Chrome extension for removing li elements from specific UL.
for example i have
<ul>
<li id="1"><div class="l1"><p>test1</p></div></li>
<li id="2"><div class="l1"><p>test2</p></div></li>
<li id="3"><div class="l1"><p>test3</p></div></li>
.... and so on
</ul>
I have array of 3500 items(like database) which on every page reload checks this ul for matches and removes them.
my jQuery code is like this:
var remove = function remove(items){
$.each(items, function(index,value){
if( $("div.l1 p").filter(function() { return $(this).text() == value; }).length ) // if there is match {
$("div.l1 p").filter(function(){ return $(this).text() == value; }).parent().parent().remove(); // delete li element
}
}
}
and i call it like:
var initi = function initi() // called when page is loaded
{
remove(Array("test1","test2","test3",...,"testonemilion"));
}
my problem which happens is sometimes chrome randomly runs out of memory and requires reloading the page. I think this will happen more often when "database" becomes bigger.
so i wanted to ask are there possible ways to optimize my jQuery function, to lower that memory stress?
i use latest chrome 40.0.2214.115 m and have 8GB RAM on my computer(which never gets to 100%)
Thanks!
EDIT: Also are there debugging tools which will display how different versions of function will perform(for example function1() executes for 1 sec, function2() executes for 0.8sec and so on)
You could use filter() to see if text is in an array and therefore only loop through the elements once instead of many times as you are doing
var remove = function remove(items){
$("div.l1 p").filter(function(){
return $.inArray( $(this).text(), items) !==-1;
}).parent().parent().remove();
}
DEMO
You are running 2 filters and then accessing the parent's twice of each filter.
Is it possible that you could do:
<ul>
<li id="1" class="test1"><div class="l1"><p>test1</p></div></li>
<li id="2" class="test2"><div class="l1"><p>test2</p></div></li>
<li id="3" class="test3"><div class="l1"><p>test3</p></div></li>
.... and so on
</ul>
OR
<ul>
<li id="1" data-text="test1"><div class="l1"><p>test1</p></div></li>
<li id="2" data-text="test2"><div class="l1"><p>test2</p></div></li>
<li id="3" data-text="test3"><div class="l1"><p>test3</p></div></li>
.... and so on
</ul>
This way you could use simple selectors on the LIs that you actually want to remove?
var remove = function remove(items){
$.each(items, function(index,value){
$('.'+value).remove();
});
}
Your code can be made more efficient. Since filter() will return an object with the matching elements, there is no need for your if statement.
You should also keep your jQuery object by in a variable, to save having to select all your paragraphs for every iteration of your .each() method.
var remove = function remove(items){
var $p = $("div.l1 p");
$.each(items, function(index,value){
$p.filter(function(){
return $(this).text() == value;
}).parent().parent().remove();
}
}
}
Having said that, this won't make things much quicker for you; 3500+ elements is a lot of elements to loop through by any measure. Paginate your results.

Strange behaviour for jQuery find

I got this piece of javascript that works perfectly to one of my websites but give troubles with other.
$(document).ready(function(){
if ($.find(Thesaurus.options.containers).length > 0) {
thes = new Thesaurus(Thesaurus.options);
}
});
These are results when I try to debug by using the old fashioned alerts:
alert(Thesaurus.options.containers); - this returns the string div.content
alert($.find(Thesaurus.options.containers)); - this one returns empty, therefore the length is zero
alert($.find('div.content')); - this one returns [object HTMLdivElement] as I expect
I seem to be unable to understand what is happening.
There is no method $.find() in jQuery it's .find()
$(document).ready(function(){
if ($(document).find(Thesaurus.options.containers).length > 0) {
thes = new Thesaurus(Thesaurus.options);
}
});
or
$(document).ready(function(){
if ($(Thesaurus.options.containers).length > 0) {
thes = new Thesaurus(Thesaurus.options);
}
});
If you visit web page of jQUery you can visualize that you are using wrong $.find... here an example the way to use.
<ul class="level-1">
<li class="item-i">I</li>
<li class="item-ii">II
<ul class="level-2">
<li class="item-a">A</li>
<li class="item-b">B
<ul class="level-3">
<li class="item-1">1</li>
<li class="item-2">2</li>
<li class="item-3">3</li>
</ul>
</li>
<li class="item-c">C</li>
</ul>
</li>
<li class="item-iii">III</li>
</ul>
If we begin at item II, we can find list items within it:
1
$( "li.item-ii" ).find( "li" ).css( "background-color", "red" );
you need to change your code something like this:
if ($(document).find(Thesaurus.options.containers).length > 0) {
thes = new Thesaurus(Thesaurus.options);
}
Hope this works.
Regards

Is it possible to append a unique CSS class to multiple <li> elements, or re-sort them using Jquery?

Currently working on the Squarespace.com platform and I'd like to re-sort a dynamic Blog Category index that defaults to alphabetical sorting. This is how Squarespace generates the code:
<div id="moduleContentWrapper11663355" class="widget-wrapper widget-type-journalarchive">
<div id="moduleContent11663355">
<ul class="archive-item-list-pt">
<li>
Category One
<span class="entry-count">(1)</span>
</li>
<li>
Category Two
<span class="entry-count">(1)</span>
</li>
<li>
Category Three
<span class="entry-count">(1)</span>
</li>
</ul>
</div>
</div>
Is it possible to re-sort the entries using Jquery, or worse case, can I append a unique CSS class to each <li> so I can manipulate each one using CSS?
Thanks!
the dom is really nothing but a complicated collection... you can use jquery to sort the li like an array.
var mylist = $('#moduleContent11663355 > ul');
var listitems = mylist.children('li').get();
listitems.sort(function(a, b) {
var compA = $(a).text().toUpperCase();
var compB = $(b).text().toUpperCase();
return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
})
$.each(listitems, function(idx, itm) { mylist.append(itm); });
thanks to http://www.onemoretake.com/2009/02/25/sorting-elements-with-jquery/
var i = 1;
$('.archive-item-list-pt li').each(function(item) {
$(item).addClass('myClass'+i);
});
$('.archive-item-list-pt li').each(function(i,j) {
$(this).addClass('yourClass'+i);
});
here is the fiddle http://jsfiddle.net/h2gfT/7/
update
$('.archive-item-list-pt li').each(function(i,j) {
var cls=$(this).children("a").text().toLowerCase();
var idx = cls.replace(' ','-');
$(this).addClass(idx);
});
here is the fiddle http://jsfiddle.net/h2gfT/9/
one with jquery chaining hotness
$('.archive-item-list-pt li').each(function(i,j) {
var cls=$(this).children("a").text().toLowerCase().replace(' ','-');
$(this).addClass(cls);
});
http://jsfiddle.net/h2gfT/11/
Sort items in place based in the arbitrary key function
http://blog.mirotin.net/125/jquery-sortitems
Sorting the entries with jQuery can be done in a couple diffrent ways, but if you just want to append CSS to each of them you could do that in two different ways.
$('li').each(function(l) { $(this).attr('class', '<insertnameofcssclasshere>') })
or
$('li').each(function(l) { $(this).css(<insertcssstuff here>) })
Of course, these would apply it to all li elements on your page. You would want to use more specific or contained selectors if you want to affect just some of them.

Categories