Search code examples
javascriptjquerycheckboxalphabetical

Dynamic results from checkbox combinations in alphabetical order


I promise searched a lot, but didn't find anything that really answers.

I'd like to show a list of alphabetically ordered countries according to my combination of checked regions. So far I've been able to achieve this for individual regions, but not for combinations. See https://jsfiddle.net/ro5yjg1c/ What I want is if, for example, I click the 'Europe' and 'Asia' checkboxes, I'd like to see the following checkboxes in a continuous alphabetically-ordered list: "Austria China Germany Japan Spain Thailand". Any other combination needs to work too. Is this possible?

Any help much appreciated

<label>
<input type="checkbox" name="colorCheckbox" id="Europe" />Europe</label>
<label>
<input type="checkbox" name="colorCheckbox" id="Africa" />Africa</label>
<label>
<input type="checkbox" name="colorCheckbox" id="Asia" />Asia</label>


<div class="mywrapper">

<div id="myEurope">
<label>
  <input type="checkbox" value="Spain" />Spain</label>
<label>
  <input type="checkbox" value="Germany" />Germany</label>
<label>
  <input type="checkbox" value="Austria" />Austria</label>
</div>

<div id="myAfrica">
<label>
  <input type="checkbox" value="Nigeria" />Nigeria</label>
<label>
  <input type="checkbox" value="Egypt" />Egypt</label>
<label>
  <input type="checkbox" value="Kenya" />Kenya</label>
</div>

<div id="myAsia">
<label>
  <input type="checkbox" value="Thailand" />Thailand</label>
<label>
  <input type="checkbox" value="China" />China</label>
<label>
  <input type="checkbox" value="Japan" />Japan</label>
</div>

</div>



$(function() {
$('input[type="checkbox"]').click(function() {

var sortByText = function(a, b) {
return $.trim($(a).text()) > $.trim($(b).text()); 
}

// --------------
if ($(this).attr("id") == "Europe") {
var sorted = $('#myEurope label').sort(sortByText);
$('#myEurope').append(sorted);
$("#myEurope").slideToggle(200)
}
// --------------
if ($(this).attr("id") == "Africa") {
var sorted = $('#myAfrica label').sort(sortByText);
$('#myAfrica').append(sorted);
$("#myAfrica").slideToggle(200)
}
// --------------
if ($(this).attr("id") == "Asia") {
var sorted = $('#myAsia label').sort(sortByText);
$('#myAsia').append(sorted);
$("#myAsia").slideToggle(200)
}
// --------------

});
});



.mywrapper {
border: 1px solid blue;
height: 200px;
width: 300px;
border: 1px solid blue;
}

#myEurope {
display: none;
}

#myAfrica {
display: none;
}

#myAsia {
display: none;
}

Solution

  • You need to ungroup elements from the regional div's (e.g. remove ), so that they appear on the same level of array for sorting. You can still use css class for relevant country to select elements, just change css selector from element to class:

    .myEurope {
      display: none;
    }
    

    Apply classes to relevant labels:

    <label class="myEurope">
        <input type="checkbox" value="Spain" />Spain</label>
    <label class="myEurope">
        <input type="checkbox" value="Germany" />Germany</label>
    

    After that JS code can be significantly simplified (see fiddle):

    function sortByText(a, b) {
      return $.trim($(a).text()) > $.trim($(b).text());
    }
    
    // Pre-sort all the countries under mywrapper div (still keeping them hidden)
    var li = $(".mywrapper").children("label").detach().sort(sortByText)
    $(".mywrapper").append(li)
    
    // On-click handler will just toggle display, countries already sorted
    $('input[type="checkbox"]').click(function() {
     $('.my' + $(this).attr("id")).slideToggle(200)
    })