0

I'm looking to create an isotope filter to a div list and as such want to add a class of the year to a parent container/div by extracting the 'Year' from a displayed date and then adding that as the class to the parent div (.publication)

Right now I am using a very basic method to do this by looking to see if a div contains a specific year and then individually assigning a year:

HTML

<div>
  <div class="publication addyearclasshere">
  <div class="publication-date">15/3/2017</div>
</div>

<div class="publication addyearclasshere">
  <div class="publication-date">15/3/2016</div>
</div>

Code

jQuery('div[class*="publication-date"]:contains("2020")').closest('.publication').addClass('2020');
jQuery('div[class*="publication-date"]:contains("2019")').closest('.publication').addClass('2019');
jQuery('div[class*="publication-date"]:contains("2018")').closest('.publication').addClass('2018');
jQuery('div[class*="publication-date"]:contains("2017")').closest('.publication').addClass('2017');
jQuery('div[class*="publication-date"]:contains("2016")').closest('.publication').addClass('2016');
jQuery('div[class*="publication-date"]:contains("2015")').closest('.publication').addClass('2015');

The problem with this approach is that if we go below 2015 or above 2020 no class is assigned. If we can explode the date and extract the year for the class then this would keep going year on year?

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
glennyboy
  • 153
  • 2
  • 15

2 Answers2

2

Loop through each .publication-date and extract the year from its text. Add the year as a class to its parent. Like this:

jQuery(".publication-date").each(function(i) {
    var yr = $(this).text().trim().split('/')[2];
    jQuery(this).closest('.publication').addClass(yr);
});

Working Fiddle

EDIT: To answer the OPs question in the comments:

Use replace to replace all the spaces by '-' and add the result to .publication's class.

jQuery(".publication-name").each(function(i) {
    var name = $(this).text().trim().replace(' ', '-');
    jQuery(this).closest('.publication').addClass(name);
});
mridula
  • 3,203
  • 3
  • 32
  • 55
  • @glennyboy From your example, I was under the impression that `.publication` was an immediate parent of `.publication-date`. But since it isn't, use `closest()` instead of `parent()`. I have updated the answer. – mridula May 31 '17 at 04:57
  • Can you perhaps also explain the relevance of the (i) in the function? – glennyboy Jun 01 '17 at 11:51
  • `i` is the index in the loop. Same as `i` in `for(var i = 0; i < n; i++)`. In your case, its not necessary and you can remove it. – mridula Jun 01 '17 at 12:05
  • How do I use the same logic to take the first word in div '.publication-name' and also add that as a class to .publication. So if the name is 'random publication' it would simply take the word 'random' and add that as a class? Even better it takes the full publication name and adds a hyphen between each word so you get class '.random-publication' ? – glennyboy Jun 01 '17 at 16:02
  • Thank you again for your help. On the second implementation if they are move than 2 words it seems not to work. For example 'Economist & Jurist' is being written as class 'Economist-& Jurist' . – glennyboy Jun 02 '17 at 13:20
  • Use `regex` to match all spaces in the string: `name.replace(/ /g,'-')` instead of `name.replace(' ','-')`. – mridula Jun 02 '17 at 13:24
  • Although, I don't think special characters like '&' are valid in class names. https://stackoverflow.com/questions/448981/which-characters-are-valid-in-css-class-names-selectors – mridula Jun 02 '17 at 13:34
  • this seems to work by stripping out the special characters:- var name = $(this).text().trim().replace(/[^a-z0-9\s]/gi, '-').replace(/[_\s]/g, ''); – glennyboy Jun 02 '17 at 14:03
  • scrub that - the above only works if there is a special character.. otherwise joins the words in the class – glennyboy Jun 02 '17 at 14:09
  • 1
    Works .replace(/[_\s]/g, '-') – glennyboy Jun 02 '17 at 14:15
  • Hi @mridula can you please enlighten me how I can combine both the above snippits for name and date to add them as multiple data filter attributes separated with a comma. For example 'publicationname, publicationyear). I have jQuery(this).closest('.publication').attr("data-filter",yr + name); ??????? – glennyboy Jun 14 '17 at 19:52
  • this is what I'm trying to achieve on https://stackoverflow.com/questions/44567166/combine-2-functions-to-write-to-an-attribute-array-in-jquery-or-javascript – glennyboy Jun 15 '17 at 12:13
2

You can loop through each of the elements and split the text.

And you don't need to use .closest() but just use .parent()

Updated. Since your code in the example in the one on your website. you would have to use closest to match the website code. Updated html to match your website html.

jQuery('div[class*="publication-date"]').each(function() {
  var year = $(this).text().split("/");
  $(this).closest(".publication").addClass(year[year.length - 1]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <div class="publication w-col w-col-6 w-dyn-item">
    <div class="publication-row w-row">
      <div class="w-col w-col-10">
        <div>
          <h1>Cosmética</h1>
        </div>
        <div class="publication-meta-row w-row">
          <div class="w-col w-col-9">
            <div class="publication-meta-row w-row">
              <div class="w-col w-col-3">
                <div class="avatar" style="background-image: url('https://daks2k3a4ib2z.cloudfront.net/58cbe3b491c05a4f18aa9e82/58dd000bd8b55b726fac170e_NSS_L1600745.png');">
                  <div class="avatar-title w-embed">
                    <div title="Nielson Sánchez Stewart " style="display: block; width; 100%; height: 100%; position: relative; top: 0; right; 0;"></div>
                  </div>
                </div>
              </div>
              <div class="w-col w-col-9">
                <div class="publication-name">Sur</div>
              </div>
            </div>
          </div>
          <div class="w-col w-col-3">
            <div class="publication-date">15/3/2017</div>
          </div>
        </div>
      </div>
      <div class="w-col w-col-2">
        <div class="download-wrapper">
          <div class="pdf w-embed"><a href="https://www.dropbox.com/s/vsh8wc5bktgmps7/Art%C3%ADculo%202017.03.15%20-%20Cosm%C3%A9tica.pdf?dl=0" target="_blank" title="Download/Preview in Dropbox"><i class="fa fa-file-pdf-o" aria-hidden="true"></i></a></div>
        </div>
      </div>
    </div>
  </div>

</div>
Carsten Løvbo Andersen
  • 26,637
  • 10
  • 47
  • 77
  • @glennyboy In your example, the parent of `publication-date` is `publication` but on your website, the parent doesn't have that class. I've updated the snippet to make it work. – Carsten Løvbo Andersen May 31 '17 at 05:56
  • Thank you that also worked. Seems you can't put more than one right answer, but I would have otherwise. – glennyboy Jun 01 '17 at 11:50