Search code examples
javascriptjqueryhtmlhrefonchange

JS: Issue getting values from drop-down menu to replace parts of HREF strings


I'm trying to use jQuery to grab the value of a selected item in a drop-down menu, and use that value to replace a particular section of all anchor links containing that string in their href value. I've set up a CodePen here, and I'm also including the relevant markup and JS below.

Basically, if the value of the selected <option> in the drop-down menu is "handle1", for instance, I'd like to iterate through all links with parent elements of a certain class, and replace the "SelectedHandle" placeholder text with that value.

$(document).ready(function() {
  // define vars
  var dropDown = $("#choices"),
    grid = $('.row-grid');

  // get value (handle) of selected item
  dropDown.on('change', function() {

    var handle = $(this).val();
    var links = $('.animate-this a');

    links.each(function() {
      this.href = this.href.replace('SelectedHandle', handle);
    });

    // show divs upon making a selection
    if (handle !== 0) {
      grid.removeClass('hide-by-default');
    }

  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- EXAMPLE SELECT OPTIONS BELOW -->
<select id="choices">
  <option value="0" selected disabled hidden>Choose Below</option>
  <option value="handle1">Person 1</option>
  <option value="handle2">Person 2</option>
  <option value="handle3">Person 3</option>
</select>

<!-- EXAMPLE DIVS BELOW -->
<div class="row row-grid hide-by-default">
  <div class="col-6 col-sm-4 col-md-3">
    <div data-animate-hover="2">
      <div class="animate-this">
        <a href="https://twitter.com/home?status=Hey %40SelectedHandle Message 1" target="_blank"><img src="https://via.placeholder.com/160x80" class="img-fluid rounded shadow">
        </a>
      </div>
    </div>
  </div>

  <div class="col-6 col-sm-4 col-md-3">
    <div data-animate-hover="2">
      <div class="animate-this">
        <a href="https://twitter.com/home?status=Hey %40SelectedHandle Message 2" target="_blank"><img src="https://via.placeholder.com/160x80" class="img-fluid rounded shadow">
        </a>
      </div>
    </div>
  </div>
</div>

My problem is that the change function is only replacing text in the links from the first option selected; clicking on others afterwards will not update the hrefs. Thus, if you initially select "Person 2", you'll see the links update to reflect that option value, but then choosing "Person 1" or "Person 3" won't have any impact on the hrefs. I'm wondering if this is a scope issue related to the use of this? Thanks for any assistance here!


Solution

  • When you change the handle in select dropdown for the first time, the "SelectedHandle" string in the href will be replaced by strings like "handle1" or "handle2".

    So, when you change the handle in select dropdown for the second or third time, there will be no "SelectedHandle" string in the href to be replaced. Hence the href wont change.

    I would recommend to encode the spaces inside URLs(href tags), as some browsers will convert spaces in URLs into "%20" & other browsers will convert them into "+". Hence replace the spaces inside href tags with "%20";

    I have made 2 changes in your code.

    1. In HTML code, converted spaces inside href tags with "%20"
    2. In JS code, Refer "Replacing handle inside href" block;

    Try (Run) the below code snippet. I believe it works as you expected.

    $(document).ready(function() {
      // define vars
      var dropDown = $("#choices"),
        grid = $('.row-grid');
    
      // get value (handle) of selected item
      dropDown.on('change', function() {
    
        var handle = $(this).val();
        var links = $('.animate-this a');
    
        //Replacing handle inside href
        links.each(function() {
          $trim_beginning = (this.href).substr(
            (this.href).indexOf("%40") + 3
          );
    
          $trim_ending = $trim_beginning.substr(
            0, $trim_beginning.indexOf("%20")
          );
    
          $replace_string = $trim_ending;
          this.href = this.href.replace($replace_string, handle);
        });
    
        // show divs upon making a selection
        if (handle !== 0) {
          grid.removeClass('hide-by-default');
        }
    
      });
    });
    div,
    img {
      display: block;
      padding: 0;
      margin: 0;
    }
    
    select {
      margin-bottom: 25px;
    }
    
    .hide-by-default {
      display: none;
    }
    
    .col-6 {
      margin-bottom: 25px;
    }
    <!--JQUERY CDN-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <!-- EXAMPLE SELECT OPTIONS BELOW -->
    <select id="choices">
      <option value="0" selected disabled hidden>Choose Below</option>
      <option value="handle1">Person 1</option>
      <option value="handle2">Person 2</option>
      <option value="handle3">Person 3</option>
    </select>
    
    <!-- EXAMPLE DIVS BELOW -->
    <div class="row row-grid hide-by-default">
      <div class="col-6 col-sm-4 col-md-3">
        <div data-animate-hover="2">
          <div class="animate-this">
            <a href="https://twitter.com/home?status=Hey%20%40SelectedHandle Message%201" target="_blank"><img src="https://via.placeholder.com/160x80" class="img-fluid rounded shadow">
            </a>
          </div>
        </div>
      </div>
    
      <div class="col-6 col-sm-4 col-md-3">
        <div data-animate-hover="2">
          <div class="animate-this">
            <a href="https://twitter.com/home?status=Hey%20%40SelectedHandle%20Message%202" target="_blank"><img src="https://via.placeholder.com/160x80" class="img-fluid rounded shadow">
            </a>
          </div>
        </div>
      </div>
    </div>