Search code examples
htmljquerydatetextprepend

How to prepend subheadlines to div based on contained time attribute?


I have a given HTML structure (see below). I want to achieve that this is separated by date headlines for each new month. For example all dates in March should have one subheadline, than other dates following with their own subheadline.

Is there a solution with jQuery without the need of special libraries?

<div class="events">
   <div class="event layout_upcoming current even first cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-03-18" class="date" itemprop="startDate">18.03.2021 – 26.03.2022</time>
      <p>Item 1</p>
   </div>
   <div class="event layout_upcoming current odd cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-04-23" class="date" itemprop="startDate">23.04.2021 – 08.05.2022</time>
      <p>Item 2</p>
   </div>
   <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-05-20" class="date" itemprop="startDate">20.05.2021 – 21.05.2021</time>
      <p>Item 3</p>
   </div>
   <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-05-27" class="date" itemprop="startDate">27.05.2021</time>
      <p>Item 4</p>
   </div>
   <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-06-10" class="date" itemprop="startDate">10.06.2021</time>
      <p>Item 5</p>
   </div>
   <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-07-08" class="date" itemprop="startDate">08.07.2021</time>
      <p>Item 6</p>
   </div>
   <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-11-10" class="date" itemprop="startDate">10.11.2021</time>
      <p>Item 7</p> 
   </div>
   <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
      <time datetime="2021-11-11" class="date" itemprop="startDate">11.11.2021</time>
      <p>Item 8</p> 
   </div>
</div>

I would like the output to be the following:

<div class="events">
    <div class="event layout_upcoming current even first cal_47" itemscope="" itemtype="http://schema.org/Event">
        <h3>March (03 or März)</h3>
        <time datetime="2021-03-18" class="date" itemprop="startDate">18.03.2021 – 26.03.2022</time>
        <p>Item 1</p>
    </div>
    <div class="event layout_upcoming current odd cal_47" itemscope="" itemtype="http://schema.org/Event">
        <h3>April (04)</h3>
        <time datetime="2021-04-23" class="date" itemprop="startDate">23.04.2021 – 08.05.2022</time>
        <p>Item 2</p>
    </div>
    <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
        <h3>May (05 or Mai)</h3>
        <time datetime="2021-05-20" class="date" itemprop="startDate">20.05.2021 – 21.05.2021</time>
        <p>Item 3</p>
    </div>
    <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
        <time datetime="2021-05-27" class="date" itemprop="startDate">27.05.2021</time>
        <p>Item 4</p>
    </div>
    <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
        <h3>June (06 or Juni)</h3>
        <time datetime="2021-06-10" class="date" itemprop="startDate">10.06.2021</time>
        <p>Item 5</p>
    </div>
    <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
        <h3>July (07 or Juli)</h3>
        <time datetime="2021-07-08" class="date" itemprop="startDate">08.07.2021</time>
        <p>Item 6</p>
    </div>
    <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
        <h3>Novembre (11 or November)</h3>
        <time datetime="2021-11-10" class="date" itemprop="startDate">10.11.2021</time>
        <p>Item 7</p>
    </div>
    <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
        <time datetime="2021-11-11" class="date" itemprop="startDate">11.11.2021</time>
        <p>Item 8</p>
    </div>
</div>

My jQuery so far:

$( ".event time" ).each(function() {
  var datetime = $(this).attr("datetime");
  const date = new Date(datetime);  
  const month = date.toLocaleString('default', { month: 'long' });
  const year = date.toLocaleString('default', { year: 'numeric' });  
  $(this).prepend("<h3>"+month+" "+year+"</h3>")
});

Solution

  • (function($){
        $('document').ready(function(){
            check_month = [];
            $( ".event time" ).each(function() {
              var datetime = $(this).attr("datetime");
              const date = new Date(datetime);
                const month = date.toLocaleString('default', { month: 'long' });
              const year = date.toLocaleString('default', { year: 'numeric' });
              if (check_month.indexOf(month+year) == -1)
              {
                check_month.push(month+year);
                $("<h3>"+month+" "+year+"</h3>").insertBefore($(this));
              }
            });
        });//ready
    })(jQuery)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="events">
       <div class="event layout_upcoming current even first cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-03-18" class="date" itemprop="startDate">18.03.2021 – 26.03.2022</time>
          <p>Item 1</p>
       </div>
       <div class="event layout_upcoming current odd cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-04-23" class="date" itemprop="startDate">23.04.2021 – 08.05.2022</time>
          <p>Item 2</p>
       </div>
       <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-05-20" class="date" itemprop="startDate">20.05.2021 – 21.05.2021</time>
          <p>Item 3</p>
       </div>
       <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-05-27" class="date" itemprop="startDate">27.05.2021</time>
          <p>Item 4</p>
       </div>
       <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-06-10" class="date" itemprop="startDate">10.06.2021</time>
          <p>Item 5</p>
       </div>
       <div class="event layout_upcoming upcoming odd cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-07-08" class="date" itemprop="startDate">08.07.2021</time>
          <p>Item 6</p>
       </div>
       <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-11-10" class="date" itemprop="startDate">10.11.2021</time>
          <p>Item 7</p> 
       </div>
       <div class="event layout_upcoming upcoming even cal_47" itemscope="" itemtype="http://schema.org/Event">
          <time datetime="2021-11-11" class="date" itemprop="startDate">11.11.2021</time>
          <p>Item 8</p> 
       </div>
    </div>

    Would you suggest this can be used as the solution? Or would you improve my code?

    check_month = [];
    $( ".event time" ).each(function() {
      var datetime = $(this).attr("datetime");
      const date = new Date(datetime);
        const month = date.toLocaleString('default', { month: 'long' });
      const year = date.toLocaleString('default', { year: 'numeric' });
      if (check_month.indexOf(month+year) == -1)
      {
        check_month.push(month+year);
        $(this).prepend("<h3>"+month+" "+year+"</h3>");
      }
    });