ARTLoe
ARTLoe

Reputation: 1799

Dynamic filter - Coding JQuery effectively

Each time a user creates a new category field a new id for the field is created

category_advert

#userj_requiredskills_attributes_0_category_advert_id
#userj_requiredskills_attributes_1_category_advert_id
#userj_requiredskills_attributes_2_category_advert_id

category_advertskill

#userj_requiredskills_attributes_0_category_advertskill_id
#userj_requiredskills_attributes_1_category_advertskill_id
#userj_requiredskills_attributes_2_category_advertskill_id

could one kindly advise me how to code my JQuery effectively, so no matter what the id is the code works - many thanks

html.erb

<%= f.collection_select :category_advert_id, CategoryAdvert.order(:name), :id, :name, {},  {class: 'category_advert'}  %>
  <%= f.grouped_collection_select :category_advertskill_id, CategoryAdvert.order(:name), :category_advertskills, :name, :id, :name, {prompt: "Select a category"}, {class: "category_advertskill"} %>

Jquery

$(document).ready(function () {
  var category_advertskills;
  category_advertskills = $('#userj_requiredskills_attributes_0_category_advertskill_id').html();
  return $('#userj_requiredskills_attributes_0_category_advert_id').change(function() {
    var category_advert, escaped_category_advert, options;
    category_advert = $('#userj_requiredskills_attributes_0_category_advert_id :selected').text();
    escaped_category_advert = category_advert.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
    options = $(category_advertskills).filter("optgroup[label='" + escaped_category_advert + "']").html();
    if (options) {
      $('#userj_requiredskills_attributes_0_category_advertskill_id').html(options);
      return $('#userj_requiredskills_attributes_0_category_advertskill_id').parent().show();
    } else {
      $('#userj_requiredskills_attributes_0_category_advertskill_id').empty();
      return $('#userj_requiredskills_attributes_0_category_advertskill_id').parent().hide();
    }
  });
});


$(document).ready(function () {
  var category_advertskills;
  category_advertskills = $('#userj_requiredskills_attributes_1_category_advertskill_id').html();
  return $('#userj_requiredskills_attributes_01category_advert_id').change(function() {
    var category_advert, escaped_category_advert, options;
    category_advert = $('#userj_requiredskills_attributes_1_category_advert_id :selected').text();
    escaped_category_advert = category_advert.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
    options = $(category_advertskills).filter("optgroup[label='" + escaped_category_advert + "']").html();
    if (options) {
      $('#userj_requiredskills_attributes_1_category_advertskill_id').html(options);
      return $('#userj_requiredskills_attributes_1_category_advertskill_id').parent().show();
    } else {
      $('#userj_requiredskills_attributes_1_category_advertskill_id').empty();
      return $('#userj_requiredskills_attributes_1_category_advertskill_id').parent().hide();
    }
  });
});

Upvotes: 0

Views: 24

Answers (2)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

Start by using variables to hold those duplicate mile-long selectors instead of doing the same selector over and over. $(this) inside the change event will also be the same element you keep referencing. You can then just use a starts-with selector for the matches.

e.g. something like:

$(document).ready(function () {
  var category_advertskills = $('[id^="userj_requiredskills_attributes_"]');
  category_advertskills.change(function() {
    var $this = $(this);
    var category_advert = $this.find(':selected').text();
    var escaped_category_advert = category_advert.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1');
    var options = category_advertskills.filter("optgroup[label='" + escaped_category_advert + "']").html();
    if (options) {
      $this.html(options);
      $this.parent().show();
    } else {
      $this.empty();
      $this.parent().hide();
    }
  });
});

You also seem to have some unwanted returns that will not be used in a DOM ready handler.

Upvotes: 1

PhonicUK
PhonicUK

Reputation: 13854

Use a class for all of the categories and use data attributes for the type and ID

 <div class="requiredskill" data-user="userj" data-type="advertskill">blah</div>

And then from jquery, lookup elements with that class and check the data attribute.

$(".requiredskill")[0].data("user"); //userj

You can match specific data values in a selector like so:

$(".requiredskill[data-user=userj][data-type=advertskill]")

Upvotes: 0

Related Questions