skip to Main Content

I am trying to do multiple things at the same time…

  1. Replace a select dropdown
  2. Have the select dropdown trigger the visibility of a div (it’s a child of the div after #1).

I have this HTML:

let $displays = $('.view-id-dashboard');
$displays.eq(1).toggle();
let $selects = $('.dashboard-select');
$('select[data-drupal-selector="edit-sort-order"]').each(function(index) {
  $("label[for='" + this.id + "']").text('Edited/Created by me');
  this.replaceWith($selects.get(index));
});
$selects.on('change', function() {
  $selects.val(this.value);
  $displays.toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="view view-dashboard view-id-dashboard view-display-id-embed_1">
  <p>
    First div, contains lots of things, I only kept the select dropdown to be replaced.
  </p>
  <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select">
    <option value="ASC">Asc</option>
    <option value="DESC" selected="selected">Desc</option>
  </select>
</div>

<div class="view view-dashboard view-id-dashboard view-display-id-embed_2">
  <p>
    Second div, contains lots of things, again only kept the relevant select below.
  </p>

  <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select">
    <option value="ASC">Asc</option>
    <option value="DESC" selected="selected">Desc</option>
  </select>
</div>

<p>
  I added this verbatim and this is the problem.
</p>
<select class="dashboard-select form-select form-element form-element--type-select">
  <option value="edited_by_me">Edited by me</option>
  <option value="created_by_me">Created by me</option>
</select>
<select class="dashboard-select form-select form-element form-element--type-select">
  <option value="edited_by_me">Edited by me</option>
  <option value="created_by_me">Created by me</option>
</select>

This works as intended but I am very unhappy I needed to add the same <select class="dashboard-select twice. I tried various ways of .clone(), .add() and such to no avail.

2

Answers


  1. Create a div to hold the moved selects, and use append() to move the selects there.

    let $displays = $('.view-id-dashboard');
    $displays.eq(1).toggle();
    let $selects = $('select[data-drupal-selector="edit-sort-order"]');
    let $container = $('#select-container');
    $selects.each(function(index) {
      $("label[for='" + this.id + "']").text('Edited/Created by me');
      $container.append(this);
    });
    
    $selects.on('change', function() {
      $selects.val(this.value);
      $displays.toggle();
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="view view-dashboard view-id-dashboard view-display-id-embed_1">
      <p>
        First div, contains lots of things, I only kept the select dropdown to be replaced.
      </p>
      <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select">
        <option value="ASC">Asc</option>
        <option value="DESC" selected="selected">Desc</option>
      </select>
    </div>
    
    <div class="view view-dashboard view-id-dashboard view-display-id-embed_2">
      <p>
        Second div, contains lots of things, again only kept the relevant select below.
      </p>
    
      <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select">
        <option value="ASC">Asc</option>
        <option value="DESC" selected="selected">Desc</option>
      </select>
    </div>
    
    <div id="select-container">
    </div>
    Login or Signup to reply.
  2. Here is an adapted version that only has one select at the end of your document.

    The idea is to hide it (serving as a template), and to clone it in the initialisation code.

    let $displays = $('.view-id-dashboard');
    $displays.eq(1).toggle();
    let $selects = $('.dashboard-select').hide(); // There's only one now
    $('select[data-drupal-selector="edit-sort-order"]').each(function(index) {
      $("label[for='" + this.id + "']").text('Edited/Created by me');
      this.replaceWith($selects.clone(true).show().get(0)); // Clone
    });
    // Refresh the collection: now there are three (including the template)
    $selects = $('.dashboard-select');
    $selects.on('change', function() {
      $selects.val(this.value);
      $displays.toggle();
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="view view-dashboard view-id-dashboard view-display-id-embed_1">
      <p>
        First div, contains lots of things, I only kept the select dropdown to be replaced.
      </p>
      <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select">
        <option value="ASC">Asc</option>
        <option value="DESC" selected="selected">Desc</option>
      </select>
    </div>
    
    <div class="view view-dashboard view-id-dashboard view-display-id-embed_2">
      <p>
        Second div, contains lots of things, again only kept the relevant select below.
      </p>
    
      <select data-drupal-selector="edit-sort-order" id="edit-sort-order" name="sort_order" class="form-select form-element form-element--type-select">
        <option value="ASC">Asc</option>
        <option value="DESC" selected="selected">Desc</option>
      </select>
    </div>
    
    <p>
      I added this verbatim and this is the problem.
    </p>
    <select class="dashboard-select form-select form-element form-element--type-select">
      <option value="edited_by_me">Edited by me</option>
      <option value="created_by_me">Created by me</option>
    </select>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search