The default display is grouped by language:

<ul>
  <li class="lang">English
    <ul>
    <li class="option">Option A
    <li class="option">Option B
    <li class="option">Option C
    </ul>
  <li class="lang">Spanish
    <ul>
    <li class="option">Option A
    <li class="option">Option B
    </ul>
  <li class="lang">Hebrew
    <ul>
    <li class="option">Option A
    <li class="option">Option C
    </ul>
  </ul>
<a href="option_first.html">Option First</a>

A hard coded link to a hard coded page will display the same data grouped by option rather than language:

<ul>
  <li class="option">Option A
    <ul>
    <li class="lang">English
    <li class="lang">Spanish
    <li class="lang">Hebrew
    </ul>
  <li class="option">Option B
    <ul>
    <li class="lang">English
    <li class="lang">Spanish
    </ul>
  <li class="option">Option C
    <ul>
    <li class="lang">English
    <li class="lang">Hebrew
    </ul>
  </ul>
<a href="lang_first.html">Language First</a>

As an example of its capabilities, how would jQuery handle this? Is there a plugin to invert a hierarchy?

2 answers

0
points

I would do it this way (I'm sure there is a more elegant way of doing it).

  1. each() through the .option class and collect all the unique (inArray()) options / contents into an array named allOptions.
  2. For each option in allOptions, output li .option parent, each() through .lang class checking if child element matches current option. If it does, output option li children li element (lang).

I haven't tested this so it could very well not work. Also, this post might help you.

Answered over 6 years ago by Cy Klassen
Mottie 1134
0
points

I went a different route with this, instead of changing around the HTML, I built the HTML from an array. I think this makes the code a little easier to read and follow, I posted a demo here.

This is the HTML needed:

<a href="#" class="switch-order lang">Option First</a>

<div id="list"></div>

and quite a bit of scripting

 var options = {"root" : [{
  "lang" : "English",
  "options" : [ "Option A", "Option B", "Option C" ]
 }, {
  "lang" : "Spanish",
  "options" : [ "Option A", "Option B" ]
 }, {
  "lang" : "Hebrew",
  "options" : [ "Option A", "Option C" ]
 }] };

$(document).ready(function(){
 // start with list sorted by language
 sortLang();

 // switch
 $('.switch-order').click(function(){
  if ($(this).hasClass('lang')) {
   $(this).removeClass('lang').addClass('opt');
   $('.switch-order').html('Options First');
   sortOptions();
   return false;
  } else {
   $(this).removeClass('opt').addClass('lang');
   $('.switch-order').html('Language First');
   sortLang();
   return false;
  }
 });
});

 // make list ordered by language
 function sortLang(){
  var i, j, l = '<ul>', list = options.root;
  for (i=0; i < list.length; i++ ){
   l += '<li class="lang">' + list[i].lang + '</li>';
   l += '<ul>';
   for (j=0; j < list[i].options.length; j++) {
    l += '<li class="option">' + list[i].options[j] + '</li>';
   }
   l += '</ul>';
  }
  l += '</ul>';
  $('#list').html(l);
 }

 // make list ordered by options
 function sortOptions(){
  var i, j, l = "<ul>", list = options.root, array = [];
  for (i=0; i < list.length; i++ ){
   for (j=0; j < list[i].options.length; j++){
    array.push(list[i].options[j]);
   }
  }
  array = array.getUnique();
  for (i=0; i < array.length; i++){
   l += '<li class="option">' + array[i] + '</li>';
   l += '<ul>';
   for (j=0; j < list.length; j++){
    if ($.inArray( array[i], list[j].options ) >= 0){
     l += '<li class="lang">' + list[j].lang + '</li>';
    }
   }
   l += '</ul>';
  }
  l += '</ul>';
  $('#list').html(l);
 }

 // Return a unique array.
 Array.prototype.getUnique = function(){
  var o = {}, a = [], i, e;
  for (i = 0; e = this[i]; i++) {o[e] = 1;}
  for (e in o) {a.push(e);}
  return a.sort();
 };
Answered over 6 years ago by Mottie