Daniel Ellison Daniel Ellison - 6 months ago 37
Javascript Question

Making a simple timeline with Jquery map and moment js

I got a timeline working except for one small issue that I cant figure out. Its grouping my items by their dates but skipping the dates when there are no entries. I would like those dates to show but put a message saying "No entries to display".

For example:
If I select the date range from

2016-05-02
to
2016-05-04


I would like to get:

Monday 2 May 2016
1 Test1
2 Test2
Tuesday 3 May 2016
No items to display...
Wednesday 4 May 2016
3 Test3
4 Test4


Heres a rough example of my code:
https://jsfiddle.net/vLdn68ko/15/

var items_by_date = {}; // declare an object that will have date indexes
$.ajax({url:"/SomeUrlBeginninWithSlash/daterange/?$filter=(start_date ge '2016-05-02') and (end_date lt '2016-05-04')",
dataType: 'json',
cache: false,
success: function (data) {

data.d.results.map(function(item){
var item_date = moment(item.Date).format('dddd D MMMM YYYY');
// if the date index does not exist we need to declare it
if(!items_by_date[item_date]) items_by_date[item_date] = [item];
// else we can just push the item on that array
else items_by_date[item_date].push(item);
})

console.log(items_by_date);
// now you can render how ever you need to
drawTable(items_by_date);
}
});

function drawTable(data){
$('#dataTable').html('');
for(var d in data){ // d will be the date index
$('#dataTable').append('<tr><td colspan="2" style="font-weight: bold;">'+d+'</td></tr>');

data[d].map(function(item){
$('#dataTable').append('<tr><td>'+item.ID+'</td><td>'+item.Description+'</td></tr>');
})
}
}


I would really appreciate any help with this.

Answer

So you basically need to get the minimum date from your range, get the maximum and then fill your data with the days that have no entries. Its a bit ugly because you keep the date strings instead of dates, so have to convert but it works fine:

  var items_by_date  = {}; // declare an object that will have date indexes
  $.ajax({url:"/SomeUrlBeginninWithSlash",
      dataType: 'json',
      cache: false,
      success: function (data) {
        data.d.results.map(function(item){
          var item_date = moment(item.Date).format('dddd D MMMM YYYY');
          // if the date index does not exist we need to declare it
          if(!items_by_date[item_date]) items_by_date[item_date] = [item];
          // else we can just push the item on that array
          else items_by_date[item_date].push(item);
        })

        fillEmpty(items_by_date);
        // now you can render how ever you need to
        drawTable(items_by_date);
      }
  });

  function fillEmpty(items_by_date){
    var dates = Object.keys(items_by_date).map(function(d){return new Date(d)})
    var minDate = new Date(Math.min.apply(null,dates))
    var maxDate = new Date(Math.max.apply(null,dates))
    while(minDate < maxDate){
      minDate.setDate(minDate.getDate()+1)
      var key = moment(minDate).format('dddd D MMMM YYYY');
      items_by_date[key] = items_by_date[key] || [{ID:"",Description: "No items to display..."}]
    }
  }

  function drawTable(data){
    $('#dataTable').html('');
    Object.keys(data).sort(function(a,b){return new Date(a)-new Date(b)}).forEach(function(d){ // you actually need to show them sorted by day
        $('#dataTable').append('<tr><td colspan="2" style="font-weight: bold;">'+d+'</td></tr>');
        data[d].map(function(item){
            $('#dataTable').append('<tr><td>'+item.ID+'</td><td>'+item.Description+'</td></tr>');
        })
      })
  }

Full Fiddle: https://jsfiddle.net/vLdn68ko/18/

Comments