A.G.Progm.Enthusiast A.G.Progm.Enthusiast - 8 months ago 69
HTML Question

How to sort a dropdown-menu created on a navbar-collapse using JavaScript/JQuery

I have a bootstrap navigation bar as below on which I have dropdown menu.

<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<div class="collapse navbar-collapse" >
<ul id="my-navbar-ul" class="nav navbar-nav">

</ul>
</div>
</div>


I am appending elements to the dropdown menu at a later point of time and want them to be displayed in sorted manner. Below is my code :

$mynavbarul = $('#my-navbar-ul');

$mynavbarul.append('<li class= "dropdown">
<a rel="nofollow" href="#" class = "dropdown-toggle" data-toggle= "dropdown" role="button" id = "namelist">Select a Name<span class ="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a rel="nofollow" href="#" id="mark">Mark</a><li>
<li><a rel="nofollow" href="#" id="allan">Allan</a><li>
<li><a rel="nofollow" href="#" id="derek">Derek</a><li>
<li><a rel="nofollow" href="#" id="brian">BRIAN</a><li>
</ul>
</li>' );


The names in the list could be in lower or upper case both. I have tried the following sorting function and calling it explicitly from the .js file where above code is written. However, the sorting mechanism seems to be not working and getting stuck somewhere in between the function. I have put debug statement to print the selectedValue and it is coming as blank. I must be doing something wrong. Below is my function :

function sortDropDownListByText() {
// Loop for each select element on the page.
$("#namelist").each(function() {

// Keep track of the selected option.
var selectedValue = $(this).val();
console.log("selected value = "+selectedValue); //coming as blank

// Sort all the options by text. I could easily sort these by val.
$(this).html($("option", $(this)).sort(function(a, b) {
return a.text == b.text ? 0 : a.text < b.text ? -1 : 1
}));

// Select one option.
$(this).val(selectedValue);
});
}


Any help to get it work would be much appreciated. Thanks.

Answer Source

If this is only about sorting the items then maybe this is a possibility.

(I assume the list items should have a closing tag)

<li><a rel="nofollow" href="#" id="mark">Mark</a></li> 

instead of

<li><a rel="nofollow" href="#" id="mark">Mark</a><li>

What you could do is get the ul id="my-navbar-ul" instead of id of the a id = "namelist".

Then you can find the list items in the <ul> and store them. Remove the list items from the <ul> and sort the ones that you have stored. Loop the stored ones and append them back to the <ul>.

Example:

$mynavbarul = $('#my-navbar-ul');

            var html = '<li class= "dropdown">';
            html += '<a rel="nofollow" href="#" class = "dropdown-toggle" data-toggle= "dropdown" role="button"  id = "namelist">Select a Name<span class ="caret"></span></a>';
            html += '<ul class="dropdown-menu" role="menu">';
            html += '<li><a rel="nofollow" href="#" id="mark">Mark</a></li>';
            html += '<li><a rel="nofollow" href="#" id="allan">Allan</a></li>';
            html += '<li><a rel="nofollow" href="#" id="derek">Derek</a></li>';
            html += '<li><a rel="nofollow" href="#" id="brian">BRIAN</a></li>';
            html += '</ul>';
            html += '</li>';
            $mynavbarul.append(html);

            function sortDropDownListByText() {
                var ul = $("#my-navbar-ul ul.dropdown-menu");
                var listItems = ul.find("li");
                ul.empty();
                listItems.sort(function (a, b) {
                    return $(a).children('a').first().html() < $(b).children('a').first().html() ? -1 : 1;
                }).each(function (index, value) {
                    ul.append(value);
                });
            }

            sortDropDownListByText();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navbar navbar-inverse">
    <div class="container-fluid">
        <div class="navbar-header">
            <a class="navbar-brand" href="#">WebSiteName</a>
        </div>
        <div class="collapse navbar-collapse">
            <ul id="my-navbar-ul" class="nav navbar-nav">

            </ul>
        </div>
    </div>
</nav>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download