mardi 6 novembre 2018

How to retain checkbox functionality with a select dropdown instead?

I had this code below that would filter which divs would show based on checkbox selections. Every time a checkbox was checked/uncheck, the code would check to see if a data attribute existed for each checked box and if so, show the div. If not, hide the div.

<style>
.Row {
  background: gray;
  border-bottom: 1px white solid;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    <div class="Row sel" id="reseller_allegiant" data-region="Americas" data-country="Brazil" data-tier="Elite Reseller">
      <div class="Heading">Allegiant Technology</div>
      <div class="Copy">Brazil</div>
      <div class="Copy">Elite Reseller</div>
    </div>

    <div class="Row sel" id="reseller_folco" data-region="APAC" data-country="Mexico" data-tier="Preferred Reseller">
      <div class="Heading">Folco Communications</div>
      <div class="Copy">Mexico</div>
      <div class="Copy">Preferred Reseller</div>
    </div>

    <div class="Row sel" id="reseller_latin_telecom" data-region="EMEA" data-country="Argentina, Mexico, Brazil" data-tier="Authorized Reseller">
      <div class="Heading">Latin Telecom</div>
      <div class="Copy">Argentina; Mexico; Brazil</div>
      <div class="Copy">Authorized Reseller</div>
    </div>

    <div id="controls">
      <span class="title">Region:</span><br>
      <input class="css-checkbox" type="checkbox" id="APAC" data-type="region" data-value="APAC" checked>
      <label for="APAC" class="css-label">APAC</label>
      <input class="css-checkbox" type="checkbox" id="EMEA" data-type="region" data-value="EMEA" checked>
      <label for="EMEA" class="css-label">EMEA</label>
      <input class="css-checkbox" type="checkbox" id="Americas" data-type="region" data-value="Americas" checked>
      <label for="Americas" class="css-label">Americas</label>
      <br>
      <br>
      <span class="title">Partner Type:</span><br>
      <input class="css-checkbox" type="checkbox" id="Preferred" data-type='tier' data-value='Preferred Reseller' checked>
      <label for="Preferred" class="css-label">Preferred</label>
      <input class="css-checkbox" type="checkbox" id="Elite" data-type='tier' data-value='Elite Reseller' checked>
      <label for="Elite" class="css-label">Elite</label>
      <input class="css-checkbox" type="checkbox" id="Authorized" data-type='tier' data-value='Authorized Reseller' checked>
      <label for="Authorized" class="css-label">Authorized</label>
      <br>
      <br>
      <span class="title">Country:</span><br>
      <input class="css-checkbox" type="checkbox" id="Argentina" data-type='country' data-value='Argentina' checked>
      <label for="Argentina" class="css-label">Argentina</label>
      <input class="css-checkbox" type="checkbox" id="Brazil" data-type='country' data-value='Brazil' checked>
      <label for="Brazil" class="css-label">Brazil</label>
      <input class="css-checkbox" type="checkbox" id="Mexico" data-type='country' data-value='Mexico' checked>
      <label for="Mexico" class="css-label">Mexico</label>
    </div>
    <br><br><br>
    <select name="country" id="country">
    <option value="all">Select a Country</option>
    <option value="Argentina">Argentina</option>
    <option value="Brazil">Brazil</option>
    <option value="Mexico">Mexico</option>
    </select>

I added the HTML Select code at the bottom today because we want to change the Country checkboxes to just be a dropdown, because there will be a TON of them. So again, this is the new HTML for that:

 <select name="country" id="country">
    <option value="all">Select a Country</option>
    <option value="Argentina">Argentina</option>
    <option value="Brazil">Brazil</option>
    <option value="Mexico">Mexico</option>
    </select>

Here is the original JS/JQuery that worked fine:

Array.prototype.indexOfAny = function(array) {
  return this.findIndex(function(v) {
    return array.indexOf(v) != -1;
  });
}

Array.prototype.containsAny = function(array) {
  return this.indexOfAny(array) != -1;
}



function getAllChecked() {

  // build a multidimensional array of checked values, organized by type

  var values = [];
  var $checked = $checkboxes.filter(':checked');

  $checked.each(function() {

    var $check = $(this);
    var type = $check.data('type');
    var value = $check.data('value');

    if (typeof values[type] !== "object") {
      values[type] = [];
    }

    values[type].push(value);

  });

  return values;

}

function evaluateReseller($reseller, checkedValues) {

  // Evaluate a selected reseller against checked values.
  // Determine whether at least one of the reseller's attributes for
  // each type is found in the checked values.

  var data = $reseller.data();
  var found = false;

  $.each(data, function(prop, values) {

    values = values.split(',').map(function(value) {
      return value.trim();
    });

    found = prop in checkedValues && values.containsAny(checkedValues[prop]);

    if (!found) {
      return false;
    }

  });

  return found;

}


var $checkboxes = $('[type="checkbox"]');
var $resellers = $('.Row.sel');

$checkboxes.on('change', function() {

  // get all checked values.
  var checkedValues = getAllChecked();

  // compare each resellers attributes to the checked values.
  $resellers.each(function(k, reseller) {

    var $reseller = $(reseller);
    var found = evaluateReseller($reseller, checkedValues);

    // if at least one value of each type is checked, show this reseller.
    // otherwise, hide it.

    if (found) {
      $reseller.show();
    } else {
      $reseller.hide();
    }

  });

});

I copied the checkboxes "change" function as a template and added this code below to handle getting the selected country and checking it against the data attributes, but it doesn't seem to do anything, so clearly I'm doing something wrong.

var $countryselect = $( "#country" );
$countryselect.on('change', function() {
    var thecountry =  $( "#country" ).val();

    $resellers.each(function(k, reseller) {

    var $reseller = $(reseller);
    var found = evaluateReseller($reseller, thecountry);

    // if the resellers country is selected, show this reseller.
    // otherwise, hide it.

    if (found) {
      $reseller.show();
    } else {
      $reseller.hide();
    }

  });
})

Any ideas/suggestions? Here is the Fiddle NOTE: I don't have my new Jquery bit in the Fiddle (since it doesn't work), so you can see how it worked originally.

In a nutshell, I want the new Country select dropdown to do the same thing as the Country checkboxes above it, and then I'd delete the Country checkboxes. So if the div's data-country attribute includes the selected country, show the div, otherwise hide it. And I also want to the other existing checkbox filtering (for Region and Partner Type) to still work, along with the new HTML Select option.




Aucun commentaire:

Enregistrer un commentaire