Merge multiple unordered list items and convert them to a select dropdown

Viewed 159

I have a BS 4 carousel and each slide contains a list of links. The links are loading some content when clicked. For better UX on mobile, I would like to merge all of these links (in carousel-items) into a single select option dropdown. It is also important the links stay functional so the appropriate content can be loaded when the items in the select dropdown are clicked.

I would like to do this with jQuery.

I have got it semi-working. I am missing the merging part though.

This is my HTML before conversion:

<div class="carousel-inner">
  <div class="carousel-item active">
    <ul class="majors">
      <li><a href="javascript:switchContent('1')">1</a></li>
      <li><a href="javascript:switchContent('2')">2</a></li>
      <li><a href="javascript:switchContent('3')">3</a></li>
    </ul>
  </div>
  <div class="carousel-item">
    <ul class="majors">
      <li><a href="javascript:switchContent('4')">4</a></li>
      <li><a href="javascript:switchContent('5')">5</a></li>
      <li><a href="javascript:switchContent('6')">6</a></li>
    </ul>
  </div>
  <div class="carousel-item">
    <ul class="majors">
      <li><a href="javascript:switchContent('7')">7</a></li>
      <li><a href="javascript:switchContent('8')">8</a></li>
      <li><a href="javascript:switchContent('9')">9</a></li>
    </ul>
    </ul>
  </div>
  <div class="carousel-item">
    <ul class="majors">
      <li><a href="javascript:switchContent('10')">10</a></li>
      <li><a href="javascript:switchContent('11')">11</a></li>
      <li><a href="javascript:switchContent('12')">12</a></li>
    </ul>
  </div>
</div>

with this code:

$(function() {
  $('ul.majors').each(function() {
    var $select = $('<select />');

    $(this).find('a').each(function() {
      var $option = $('<option />');
      $option.attr('value', $(this).attr('href')).html($(this).html());
      $select.append($option);
    });

    $(this).replaceWith($select);
  });
});

And this is how the code looks like after conversion:

<div class="carousel-inner">
  <div class="carousel-item active">
    <select>
      <option value="javascript:switchContent('1')">1</option>
      <option value="javascript:switchContent('2')">2</option>
      <option value="javascript:switchContent('3')">3</option>
    </select>
  </div>
  <div class="carousel-item">
    <select>
      <option value="javascript:switchContent('4')">4</option>
      <option value="javascript:switchContent('5')">5</option>
      <option value="javascript:switchContent('6')">6</option>
    </select>
  </div>
  <div class="carousel-item">
    <select>
      <option value="javascript:switchContent('7')">7</option>
      <option value="javascript:switchContent('8')">8</option>
      <option value="javascript:switchContent('9')">9</option>
    </select>        
  </div>
  <div class="carousel-item">
    <select>
      <option value="javascript:switchContent('10')">10</option>
      <option value="javascript:switchContent('11')">11</option>
      <option value="javascript:switchContent('12')">12</option>
    </select>
  </div>
</div>

But how do I make it look like this:

<select>
  <option value="javascript:switchContent('1')">1</option>
  <option value="javascript:switchContent('2')">2</option>
  <option value="javascript:switchContent('3')">3</option>
  <option value="javascript:switchContent('4')">4</option>
  <option value="javascript:switchContent('5')">5</option>
  <option value="javascript:switchContent('6')">6</option>
  <option value="javascript:switchContent('7')">7</option>
  <option value="javascript:switchContent('8')">8</option>
  <option value="javascript:switchContent('9')">9</option>
  <option value="javascript:switchContent('10')">10</option>
  <option value="javascript:switchContent('11')">11</option>
  <option value="javascript:switchContent('12')">12</option>
</select>

And do these values work/act like links when each option is selected?

Here's a Pen of what I have gotten so far.

1 Answers

Build a single <select> first, then replace each <ul> with it.

$(function() {
  var $select = $('<select />'); // Start building a <select>
  $('ul.majors a').each(function() { // Grab each hyperlink in each ul.majors
    var $option = $('<option />'); // Build 
    var $option = $('<option />').attr('value', $(this).attr('href')).html($(this).html()); // Update the value from the a's href
    $select.append($option); // Append the option to the <select>
  });

//      // Replace each ul.majors with the select:
//      $('ul.majors').each(function(){
//        $(this).replaceWith($select.clone()); // Need to clone it!
//      })

  // Or, to replace the entire carousel with the dropdown:
  $('.carousel-inner').replaceWith($select);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="carousel-inner">
  <div class="carousel-item active">
    <ul class="majors">
      <li><a href="javascript:switchContent('1')">1</a></li>
      <li><a href="javascript:switchContent('2')">2</a></li>
      <li><a href="javascript:switchContent('3')">3</a></li>
    </ul>
  </div>
  <div class="carousel-item">
    <ul class="majors">
      <li><a href="javascript:switchContent('4')">4</a></li>
      <li><a href="javascript:switchContent('5')">5</a></li>
      <li><a href="javascript:switchContent('6')">6</a></li>
    </ul>
  </div>
  <div class="carousel-item">
    <ul class="majors">
      <li><a href="javascript:switchContent('7')">7</a></li>
      <li><a href="javascript:switchContent('8')">8</a></li>
      <li><a href="javascript:switchContent('9')">9</a></li>
    </ul>
    </ul>
  </div>
  <div class="carousel-item">
    <ul class="majors">
      <li><a href="javascript:switchContent('10')">10</a></li>
      <li><a href="javascript:switchContent('11')">11</a></li>
      <li><a href="javascript:switchContent('12')">12</a></li>
    </ul>
  </div>
</div>

Related