So I newly created an app, a time-in-time-out system. I want to be able to override the add icon below and turn it into a โtime inโ or โtime outโ button that automatically saves to my Google Sheets (since the system-generated add action below has to open a form first before saving). How do I do that? I created my own behavior that does this but itโs always this add action button that shows up.
Unfortunately, there is not a way currently to override or replace the default Add button. A feature request has been opened for this.
Maybe we can offer alternatives? How are storing the โTime Inโ and โTime Outโ?
single table but separate rows for In and Out
Then I assume you have a single column that you set for In or Out? If so, then you could use the โPlusโ button as is and auto-populate the In/Out value.
Assuming you are capturing daily In/Outs, you can check if no time records exist and if none auto-set value to โInโ. If an โInโ row exists then set to โOutโ.
If there could be multiple In/Outs then check that the count for each is equal or not equal - equal means default to โInโ and not-equal default to โOutโ.
I hope this helps!
Thanks but I donโt want user to be able to tamper with the inputs, but he must save right away. How do I do that?
If you are using a Form, You would place the expression to auto-set โInโ or โOutโ in the App Formula. Users cannot change values set this way. You would probably want to do the same with the captured Time. Then basically the user taps the โPlusโ button and then taps โSaveโ.
If you are only saving a timestamp, this is obviously, this is less than ideal.
Is there any other info a user needs to provide to time in or out?
If you set the option โProminenceโ as โDo not displayโ and then you create your own โAddsโ button with the LINKTOFORM(โฆ), you are able to overwrite the system generated โAddsโ button. Or do I misunderstand the request?
Close enough. I donโt wanna link to form. I wanna populate data in the background and save right away upon clicking button.
There is another option I have seen others use. Create a Gallery view as the main view and treating each gallery item as a button. You use the โRow Selectedโ behavior to attach a custom action.
In your case the idea might be to have two gallery items, one for โInโ and one for โOutโ. You could use the logic I explained above to show/hide the gallery items. When a gallery item is tapped, it runs your attached custom action to create the proper time entry row. And then the view switched to show the other gallery item. A neat side-effect of using this approach is that the gallery items can be images so you can use ANY image as your displayed โbuttonโ.
Here is an example post with a sample image showing several gallery items being used as buttons.
So Iโve made it in the way you suggested it. But is there a way to display details even if the IN and OUT times are still empty, like below?
Which suggestion are you using?
I am a little confused here and unclear about your data structure. Could you post an image of your Time AppSheet tables with the columns defined? I can help you better that way.
Maybe I am wrong but I didnโt think we could get our own actions to show up on Table and Deck views as overlay - effectively replacing the system Add button in those views (see example image above). Custom โOverlayโ buttons only show on Detail views.
@WillowMobileSystems You are able to use your own Overlay action with the table view if it doesnโt have anything to do with the existing recordsโฆ like if you want to open a form view with the LINKTOFORM(). This app is for example doing thatโฆ
Oh, wow! Then I stand corrected. I am sure I tried this before but obviously didnโt do something right. Iโll try it again now.
From this post I get that we set the system action to โDo Not Displayโ. But what is required to get the custom button to show instead?
You need to set it as โDisplay Overlayโ
Ok, I see how it works now. That overlay action must be non-row specific which makes sense.
There isnโt an action to simply โadd a rowโ. There is an โadd a row based on values from this rowโ but that means the action acts on a specified row and canโt be used as an overlay action in a Table or Deck view.
In your case, you could use @Aleksi 's approach with launching the Form with your own custom overlay actions solely for the purpose of using a different action icons - one for in and one for out. You can also pre-set column values when navigating to the Form. I would think you still would want to show/hide the actions based on user status as already in or out. And as such, the same expressions simply move to the actionsโs behavior to show/hide the actions. From a users perspective, it is still a click to open the Form and a click to Save.
To get to a design where a single click adds an in/out record, it seems the Gallery View might be the best option.
The gallery suggestion
Here they are
TimeFilter
is the table for displaying Time In
and Time Out
.
TimeMode
is the table for IN
and OUT
TimeInOut
is the table for all IN
and OUT
transactions
I think you may have made this a lot more complicated than it should be. The TimeFilter and TimeMode tables are really representative of activities you expect to perform on the TimeInOut table. You will find yourself implementing a LOT of extra functionality in order to keep those tables populated and/or updated.
I would recommend having only two tables - an Employees table and the TimeInOut table.
The TimeInOut table would have a Ref column to the Employee table from which you can pull the Employee Email and/or Name.
Based on your sample view, I would also recommend that instead of separate In and Out records, have In and Out columns. This neatly ties the In and Out times together making it easier to display them in your view.
Filtering, if still needed after these changes, is accomplished by either a FILTER() function or a Slice.
In am not 100% clear on what Mode means. If it is determining In/Out mode, that can be derived from the state of the data - especially if you use In and Out columns. So, no table required.
So you mean to say, every day has its own row of in and out inside TimeInOut
table? Is there a way to automatically insert a dummy row when a new day starts, or upon opening app?
Yes or a new record for each In/Out session - for lack of better term. For example, some might have an In/Out before lunch break and another In/Out after.
I donโt think you need a dummy record.
What I would do is use a table to setup the Gallery View. Ahhh, maybe this is what you intended for the TimeMode table?
The idea is to show these Gallery table rows as โbuttonsโ in the Gallery view. At the start of the day, an employee would only see the In โbuttonโ. When tapped a new TimeInOut row is added and populated with the In time and user info. The Gallery view then detects this incomplete row and automatically shows the Out โbuttonโ and hides the In โbuttonโ. When the Out โbuttonโ is tapped, the incomplete row is updated with the Out time. Once the TimeInOut row is completed, the Gallery view again switches to show only the In โbuttonโ.
This is of course a simplified description. Implementation is not difficult. But being new, there will be a small learning curve to get the necessary actions created and working correctly.
Is any of this helping?
Yes Iโm getting the idea. Itโs the implementation thatโs my issue. How do I make the โInโ button show at the start of the day? You canโt display 2 tables at the same time. I still wanna show time in
as --:--:--
by default.
AppSheet does have the concept of a dashboard which allows you to display two, or more, views simultaneously.
Ok, so this is a requirement? The app MUST be able to show an โAttendance for Todayโ view, as in your example above, when no time entries have yet been made for the day? I see now why you were suggesting a dummy record.
If not a requirement, I think what I would do is use a dashboard with the In/Out buttons at the top and below is a table showing the Attendance History. This gives a user much more information at a glance.
Yes itโs a requirement.
Sadly I canโt hide the header in dashboards. And I donโt want them to redirect to another page upon clicking.
I have been playing with this trying to implement the sample view you provided with the requirements you have imposed.
Unfortunately, I do not think it is possible to get the exact implementation you are looking for. With some compromise, you can certainly get the same results.
As I understand it, you wish to open directly to your sample view. To create the view you propose requires using a Detail view. However, Detail views require a single row reference to display. Normally, through navigation in the app, that row reference is passed to the Detail view.
As far as I know, there is not a way to open the app to a Detail view with some pre-selected row reference. Even If the view were based on a Slice with only a single row, that Slice is a LIST of 1 row reference as opposed to the row reference itself.
If someone knows how this can be done, please chime in.
A compromise could be opening to some view with a way to navigate to the desired Detail view. If you have plans for other features within the app, this might be the way to go.
If we can solve that problem of opening to a Detail view with a row already displayed, then you would be golden. You can use Inline Actions to add Time In and Time Out. Below is a view I created showing this. Note the green Time In button in left-hand image and red Time Out button in right-hand image.
Wait, whatโs going on here? Can someone summarize the goal?
As I understand it, the requirement is for a user to be presented a view like that shown in post #15 of this thread on initial opening of the app. With the โโ:--:โโ values for in and out.
The user would tap/click some Time In action (inline, overlay, etc) and a new row is added (or possibly updates some pre-existing row) for the day with Time In populated. The user stays on the view and later taps/clicks some Time Out action to complete the attendance record for the day.
Initially the thought was separate in and out rows but after seeing the required view, I advocated for In and Out columns.
Its very simple in concept but I am not seeing how it can be achieved as stated without some compromises.
Any ideas?
I think you can do that creating a SLICE table of your dataset and for each SLICE you can assign the action you want to show overlay. After that you can create a View for each SLICE you need.
@Timothy_Gandionco @WillowMobileSystems
Please check the sample app called โPunch In or Outโ from www.appsheet.com/portfolio/531778. It sounds that you are looking for an app like that.
Yes, I agree there are many other ways to get the same results. I was trying to stay within the design and constraints specified.
@Timothy_Gandionco It seems you might need to compromise on design. Is there something else acceptable for your app?
Yep. Iโve practically made two versions:
Time in/out
v1
v2
Summary
v1
v2
With the help of @Grant_Stead, it turns out I was wrong about how the Detail View behaves. It WILL show rows based on a slice at app start-upโฆeven if more than one row. It will simply use an ANY() function to effectively select the first row.
My issue was, even though the test of the Slice seemed to return the correct row, at run time of the app, the Slice was actually returning NO rows. I mention this only because itโs something we all need to be aware of - test of slice doesnโt necessarily match app run time. In my case I had a mis-match between what the Slice expected and the action updates that led to no rows returned. Once I got that right then it was just a matter of tweaking to get the Action icons to show at expected states of the row.
The main trick is getting the Slice to return the correct data row. I used an expression like this:
IF(COUNT(SELECT(Attendance[Attendance ID], AND([Employee].[Email] = USEREMAIL(), DATE([Time In]) = TODAY()))) = 1,
AND([Employee].[Email] = USEREMAIL(), DATE([Time In]) = TODAY()),
[Attendance ID] = "3c61ffa5"
)
That last part, [Attendance ID] = "3c61ffa5"
, is the reset row. A single dummy row, similar to what you had suggested, that each user will see to start the In/Out procedure.
My โTime Inโ action shows the green icon and ADDS a new data row for the user, populating the logged in user and the Time In value.
The โTime Outโ action shows the red icon, assumes the Slice has done its job in selecting a row with only the In time completed and UPDATES the rowโs Time Out.
To get the โโ:--:โโ part of the design, I manage the In and Out times as TEXT, not DateTime.
I then end up with the following sequence of views for a user. I didnโt bother disabling the Edit action for my testing. Of course, for this app it should be removed.
Initial Day View
Immediately after clicking Time In action - set for Time Out - Note update still in progress.
Immediately after clicking Time Out Action - remains for user for rest of day - next day will reset
Once this basic processing flow is established, then the app can be enhanced to accommodate many variations of the In/Out process.
Yep this is how it works in the v2 of my app, the detailed view. Thanks for all your inputs.
Last. Can I center this text?
The closest I can think because of original specs, would be this one. You can find the sample app called โPunch In Out From Table Viewโ
User | Count |
---|---|
32 | |
25 | |
24 | |
23 | |
15 |