Creating a Daily/Monthly/Weekly Check-In Function

Hey there, I’ve gone through the tutorials and am new to building with AppGyver. It seems intuitive but I am struggling to get a basic daily/weekly/monthly check-in polling function to work. It’s a binary yes or no poll with a submission button. The check-in window is for a set period of time either daily, weekly, or monthly which will be determined by the user upon setup. It seems simple but can’t figure out what I’m doing wrong or how to make it work properly.

I’d like to make it where:

  • Can only select one checkbox at a time

  • The description text also checks/unchecks the checkbox that it is associated with

  • Tie the submit button to ensuring at least one checkbox is checked

  • Resetting check-in ability after a set period of time

It seems quite basic yet I am struggling. I am very much a business user and not an engineer by training besides being able to do very basic HTML, CSS, and limited knowledge of Javascript.

Any advice is greatly appreciated!

Did you watch the Todo app tutorial video at https://docs.appgyver.com?

Simplest way to create the checkbox logic is to have a pageVars.checkedId page variable, and bind your checkbox state to a formula such as current.id === pageVars.checkedId (assuming your repeating the checkboxes from a data source), and then set the logic for tapping the whole repeated component to set pageVars.checkedId to current.id.

The submit button would then simply check !IS_EMPTY(pageVars.checkedId).

To ensure you can check in only once in a certain time period, you could use the Set item to storage API to set lastSubmitAt key item to NOW() on submit. Similarly, you’d set a checkinPeriod item to "day"/"week"/"month" when the user is setting up their app. You’d also set these items to respectively named app variables.

Now, in global canvas, on app load, you would use Get item from storage to get both saved items, and set them to app variables. You now have a system where your lastSubmitAt and checkinPeriod app variables always have the right data as saved/submitted by the user.

Then, you can simply run a DATETIME_IS_BEFORE(appVars.lastSubmitAt, NOW(), appVars.checkinPeriod) to see if the last submit timestamp is before current timestamp in the given precision (which is the last parameter, i.e. day/week/month). See https://docs.appgyver.com/reference/formula_functions/date/datetime_is_before for the full docs.

That was a bit densely packed answer, but I hope it helps!

1 Like

Thanks @Harri_Sarsa ! I didn’t see that specific to-do list tutorial. I only went through the prompts in Composer before attempting to build. Will give this a watch and the go through your recommendation above.

Appreciate your help!

Thanks again for laying this out.

I’ve gone through all the tutorials again and started following the instructions above. I’m getting stuck on:

This is what I’ve been doing:

In the logic section of the repeated checkbox component going to EVENT Component tap --> Set Page Variables. Then within the Set Page Variables logic selecting Variable name to be checkedID then setting Assigned value using a formula current.id

I’ve also tried applying the same logic flow to the checkbox onChange event without success as well.

Do you know what I’m doing wrong?

Seems alright. :thinking: Is the pageVars.checkedId getting change if you use e.g. the debugger to view the app state?

If you can share your app ID, I can also take a quick look at this!

That would be fantastic Harri! I’m not sure what I did exactly :thinking:. The page I’m working on is Check-In 2 and app ID is 96784

It’s a binary time interval check-in of yes I did this or no I didn’t.

I haven’t had a chance to work on the time interval piece that you outlined in your initial reply.

One immediate issue is that you’ve bound the Disabled property to current.id === pageVars.checkedId, when it should be the Value field that’s bound.

You can also do it so that instead of the checkbox primitive, you have an icon whose Icon name is bound to a formula like

IF(current.id == pageVars.checkedId, "dot-cicrle-o", "circle-o")

That renders a more radio button style UI.

1 Like

Awesome! I like that a lot. Thanks so much for your help.

I’ll play around with the radio style UI and let you know if I run into any other issues.

Alright so to simplify this a bit in a new app canvas. I’ve moved away from checkbox then submit flow to two static buttons for each challenge check-in.

I’ve also included the create a challenge flow that sets the checkinPeriod and a few other details. I’m hoping to either disable or hide the check-in buttons when a user has already checked in for that time period on the details page.

I’m struggling to get that functionality to work using the below guidelines you laid out earlier.

Can you help me troubleshoot where I’m going wrong?

App ID 97782

@Harri_Sarsa got it sorted!

Question though. I see that I’ve managed to disable buttons using your formula above so after a check-in those buttons disable and text appears saying you’ve checked-in already.

How do I know it will become clickable again if I haven’t set the length to “day”, “week”, “month”? Do I need to define the check-in period terms or does the logic understand “day”, “week”, “month” equates to the 24 hours, 7 days, & 30 days?

I’m loving AppGyver by the way! As someone not technical by nature I am starting to pick up how to build applications! :grinning:

We use Moment.js internally, so https://momentjs.com/docs/#/query/is-before/ should clarify how the last parameter works.

@William_Glass did the Moment.js doc clarify things?

@Harri_Sarsa it did clarify thank you! It is properly printing the correct boolean of true or false. Now my issue is disengaging or hiding the buttons. I tried simply binding the formula (below) to disabled or visible state of the button component itself and that didn’t allow the buttons to become visible or enabled once it was in a new check-in time period.

DATETIME_IS_BEFORE(data.myChallenges.lastSubmitAt, NOW(),data.myChallenges.checkinPeriod)

I also tried using the logic canvas and an IF condition to the hide component and show component using the same formula above. That also hasn’t worked properly.

I know the function seems to be working as I’ve printed the “true” & “false” statements on the screen to double check. Additionally, I have tied strings to print “time to check-in” or “you’ve already checked-in for this period.” Using this formula:

IF(DATETIME_IS_BEFORE(data.myChallenges.lastSubmitAt, NOW(),data.myChallenges.checkinPeriod),“You’ve already checked-in for this time period.” , “It’s time to check-in”)

How do I make it where the buttons are clickable during the check-in window and disabled when they’ve already checked-in?

You can use Set component property flow function in any logic canvas to change the button’s property “disabled” to true.

While @Sasu_Makinen is technically correct, using Set component property directly should be discouraged – it’s better to make your components react to bound values.

The real reason it’s not working is because the formulas you post are only re-evaluated if the constituent parameters change – so only if data.myChallenges.lastSubmitAt or data.myChallenges.checkinPeriod change.

So, instead of NOW(), you could have an appVars.now and add a loop to Global canvas that sets its value to NOW() e.g. every 1 second.