niedziela, 9 kwietnia 2017

Vue.js filters - formatowanie daty

Filtry w Vue.js są jak helper'y czy utils'y w C#. Takie pomocnicze metody, które przydają się w wielu miejscach w aplikacji i pozwalają uniknąć duplikowania kodu. Podstawowe informacje na ich temat można przeczytać tutaj lub w formie tutoriala na youtube.
Pierwszy filtr, który zaimplementowałem w aplikacji Dogevents wiązał się z wyświetlaniem daty wydarzenia. Każde wydarzenie składa się z dwóch pól typu data/czas określających jego początek oraz koniec:

{
  "start_time": "2017-05-06T14:30:00+0200",
  "end_time": "2017-05-06T19:30:00+0200",
}

Przedstawiony format choć jest jak najbardziej prawidłowy w kontekście wymiany, przechowywania danych o tyle jego czytelność jest niska - nie jest "user friendly" :)

Prócz bardziej przyjaznego wyświetlania tych informacji chciałem uzyskać jeszcze kilka dodatkowych efektów:
  • Jeśli wydarzenie odbywa się w jednym dniu wyświetlić tylko raz datę i godzinę rozpoczęcia + godzinę zakończenia, np. 2017-02-04 10:00 - 14:00
  • Jeśli wydarzenie trwa więcej niż jeden dzień i nie jest na przełomie miesiąca wyświetlić jego datę jako 5 - 8 Maj 2017
Wyświetlanie daty wydarzenia z użyciem filtra 

Działający przykład udostępniłem na JSFiddle

Na początek wywołanie filtra toEventDate z poziomu szablonu:

<div id="app">
    <p>{{ { start_time: start_time, end_time: end_time } | toEventDate}}</p>
</div>

Wykonuję tu jedną dodatkową rzecz - opakowanie w obiekt dwóch właściwości start_time, end_time tak aby móc przekazać je jako jeden parametr do funkcji filtra. Następnie rejestracja globalnego filtra:


Vue.filter('toEventDate', function(eventDate){
 //some logic here ...
}

I ostateczna funkcjonalność:


Vue.filter('toEventDate', function(eventDate) {
  let startTime = new Date(eventDate.start_time);
  let endTime = new Date(eventDate.end_time);
  let locale = 'en-EN';
  let dateFormatOptions = {
    day: 'numeric',
    month: 'long'
  };
  let timeFormatOptions = {
    hour: 'numeric',
    minute: 'numeric'
  };

  if (startTime.toLocaleDateString() === endTime.toLocaleDateString())
    return startTime.toLocaleDateString(locale, dateFormatOptions) + ' ' + startTime.toLocaleTimeString(locale, timeFormatOptions) + ' - ' + endTime.toLocaleTimeString(locale, timeFormatOptions);

  if (eventDate.start_time.substring(0, 7) == eventDate.end_time.substring(0, 7))
    return startTime.getDate() + ' - ' + endTime.getDate() + ' ' + startTime.toLocaleDateString(locale, {
      month: 'long'
    })

  return startTime.toLocaleDateString(locale, dateFormatOptions) + ' - ' + endTime.toLocaleDateString(locale, dateFormatOptions)
});

Brak komentarzy:

Prześlij komentarz