[OH3] Widget: How to use calendar week / week of the year

I am trying to create a widget, that shows different item depending on the calendar week/week of the year.
The widget is a list and I use the filter function to show/hide certain items.
But I can’t set the filter for calendar week/week of the year.

For other thinks I use dayjs but =dayjs().weekYear() does not work.

Is there a way to use the calendar week in the filter section of an list widget.

My approach:

The item are in groups called “Week_#”(0-3)

Then I filter with:

filter: loop.item.groupNames.indexOf(‘Week_’ + CALENDAR_WEEK % 4 ) >= 0

But I don’t know how to use the calendar week/ week of the year.

Can you share the actual code of the widget? It is unclear why you need to filter the repeater array at all if you already have the items in a known group.

The basic idea is a list of items.
Some of these items should be visible every Monday, every Tuesday etc.
I have done this with a filter like this:

filter =loop.item.groupNames.indexOf('Day_' + dayjs().day()) >= 0

Every item that should be visible on Monday is in the group Day_0, every Tuesday item is in the group Day_1 etc.

So far so good.

Some of the items should only be visible on the first Monday of a four-week schedule, or on Tuesday of the second week on the same four-week schedule (always 4 weeks Schedule atm).

My idea was to put these items in two (or more) groups. Day_0 for Monday and Week_0 for the first week in the four-week schedule. Then filter with:

filter: loop.item.groupNames.indexOf('Day_' + dayjs().day()) >= 0 && loop.item.groupNames.indexOf('Week_' + *CALENDAR_WEEK* % 4) >= 0

Items that appear every week, have to be in groups Week_0 - Week_ 3 (and at least one Day group).

Here is the very basic widget:

uid: test_widget
tags:
timestamp: Sep 13, 2021, 11:44:55 AM
component: f7-card
config:
  title: '=dayjs().day() === 0 ? "Montag" : dayjs().day() === 1 ? "Dienstag" : dayjs().day() === 3 ? "Mittwoch" : dayjs().day() === 4 ? "Donnerstag" : dayjs().day() === 5 ? "Freitag" : dayjs().day() === 6 ? "Samstag" : "Sontag"'
slots:
  content:
    - component: oh-list
      slots:
        default:
          - component: oh-repeater
            config:
              for: item
              sourceType: itemsWithTags
              itemTags: TestTag
              filter: loop.item.groupNames.indexOf('Day_' + dayjs().day()) >= 0 #&& loop.item.groupNames.indexOf('Week_' + *CALENDAR_WEEK* % 4) >= 0
              fragment: true
            slots:
              default:
                - component: oh-list-item
                  config:
                    title: =loop.item.name
                    item: =loop.item.name

The question is: How can I use the calendar week number (37 for this week) in an widget?

An alternative could be to use (proxy) switch items and only show the ones that are on and switch them on with rules.

weekYear() is not available because it requires a day.js plugin that is not loaded.
The currently loaded plugins is rather limited:

This list is not final, only those plugins with universally useful functionality or a tiny overhead were included, but PRs that add more will likely be accepted.

Surely better, if you use widget expressions to make complex computations or derive states rather than just formatting the display, you’re probably doing something wrong.

You could have a single number item and a very simple rule that keeps the current day in your 4-week period (i.e. incremented every day and resets to 0 when it reaches 28).

To display the name of the 15th day (if the 4-week period starts on Monday) you can use:
=dayjs().startOf('isoWeek').add(15, 'day').format('dddd')
(replace 15 with your item’s state)
If your language in Regional Settings is German it will yield “Dienstag” in this case.
If you want it in English:
=dayjs().locale('en').startOf('isoWeek').add(15, 'day').format('dddd')
But if your regional settings are not to set to German you can’t use locale('de') - only English and the current language are loaded.
And btw after you’re replaced with the state of the item (number of days after the first Monday of the period) should always be the current day, so if it’s not, you know that the rule failed to run at least once - can happen if your system was offline. Then you just adjust the item.

1 Like

That sounds absolutely reasonable, thank you.

Good approach, I think i got the idea. That should work, thanks. Will try it ASAP :slight_smile: