Adding a Check-Out Page to Rock

  • By Michael Garrison One Year Ago

The Rock Check-in functions are great, and many churches are using this weekly around the world. But a common request is to also provide "Check-Out" functionality, so that they can be sure everyone's accounted for.

Although Rock doesn't support this natively (yet?), the devs appear to have been considering and planning for this use from the earliest days of Rock, and so have built in everything we need to make a check-out system ourselves. And the stock blocks even assume that check-out will be a function: the CheckInManager page, for instance, will stop showing kids that we check out with the system we'll create in this post, but without removing the entire attendance record the way the "Delete" button in CheckInManager does.

All we need to do is create the interface to actually check the kids out.

Step 1: Create a check-out page

I created our check-out page under the "Check-in Configuration" pages, but you can put it wherever you'd prefer. To create a new page, go to the page you'd like it to be a child of (such as the "Check-in Configuration" page), and click the Child Pages button on the Admin bar at the bottom of the screen. Now click the + button to add a new page and call the page "Check-out" (or whatever you'd like to call it), with the Full Width layout. Refer to the Building Websites documentation or earlier posts for more information. Once it's created, click on the Check-out link that appears in the Child Pages dialogue, and you'll be on your new page.

If this new page's parent has a menu of sub-pages on it, you may want to make this page's button look pretty there by clicking the Settings button on the admin toolbar, and adding a Font Awesome identifier to the "Icon CSS Class" input, such as fa fa-check-circle.

Step 2: Add the list of kids available to check-out

Click the Zones button on the admin toolbar and add a block in the "Main" zone, of type Dynamic Data. I called this block "Check-out list". Click OK to dismiss the dialog, then click Blocks on the admin toolbar and click the  Edit Criteria button on the fly-out menu for your new block. Here's the Query:

v7.5 and below v8.3 and above

    '<img src="/GetImage.ashx?id=' + CAST(p.[PhotoId] as varchar(10)) + '&maxwidth=50&maxheight=50">' AS "img"
    ,p.[NickName] + ' ' + p.[LastName] AS "Name"
    ,g.[Name] "Group"
    ,s.[Name] "Schedule"
    ,c.[Name] "Campus"
    ,'<a class="btn btn-danger btn-sm grid-delete-button" href="/page/{{ PageParameter.PageId }}?checkout=' + CAST(a.[Id] as varchar(10)) + '"><i class="fa fa-times"></i></a>' AS "CheckOut"
    [Attendance] a
    LEFT JOIN [PersonAlias] pa ON a.[PersonAliasId]=pa.[Id]
    LEFT JOIN [Person] p ON pa.[PersonId] = p.[Id]
    LEFT JOIN [AttendanceOccurrence] ao ON a.[OccurrenceId] = a.[Id]
    LEFT JOIN [Group] g ON ao.[GroupId]=g.[Id]
    LEFT JOIN [Schedule] s ON a.[ScheduleId]=s.[Id]
    LEFT JOIN [Campus] c ON a.[CampusId]=c.[Id]
    a.[ScheduleId] IS NOT NULL
   --AND a.[StartDateTime] >= DATEADD(HOUR, -1, GETDATE())
    AND a.[StartDateTime] > '{{ "Now" | Date:"yyyy-M-d" }}'
    AND a.[EndDateTime] IS NULL
    AND a.[Id] <> @checkout

This gives you a list of everyone who was checked in today, and a button that links you right back to this page with the ID of the attendance record set as a page parameter. Since the person may not be actually checked out when this block loads, that last line uses the ID that may or not be set in the parameter, to exclude the identified person from the list. In order for that to work, we need to add @checkout=0 to the "Parameters" input. Uncheck all of the Grid Actions but make sure that "Show Grid Filter" is checked, then click Save.

(Note: the commented-out line with DATEADD(HOUR, -1, GETDATE()) is an alternate scheme for filtering kids to check-out; if you uncomment that line by deleting the two dashes at the beginning, and comment out the line below it, it would only show you kids checked in within the last hour. It's just an example; if you're comfortable with SQL, feel free to tweak the checkin time cutoff). 

Step 3: Actually check the kids out

If you click the red X button once you've added that block, you'll see that the identified child indeed disappears from the list. But only because we've excluded them from the query; they haven't been actually checked out. If you reload the page they'll show up on the list again. So let's add the block that will actually remove them from the list.

Add a second "Dynamic Data" block to the same zone as the list (I called it Set check-out), but once you've created the block you'll probably want to drag this up above the first block you added. So your list of blocks in the Main zone should look something like this:


Here's the query for this new block:

UPDATE [Attendance] SET [EndDateTime]=GETDATE() WHERE [Id]=@checkout AND [EndDateTime] IS NULL;
    p.[NickName] + ' ' + p.[LastName] AS "Name"
    [Attendance] a
    LEFT JOIN [PersonAlias] pa ON a.[PersonAliasId]=pa.[Id]
    LEFT JOIN [Person] p ON pa.[PersonId] = p.[Id]
WHERE a.[Id]=@checkout

Once again, we'll need to add @checkout=0 to the "Parameters" input. Now add the following in "Formatted Output":

{% for row in rows %}
    <div class="alert alert-warning">{{row.Name}} has been checked out</div>
{% endfor %}

NOW when click one of the delete buttons, assuming the address of your page is something like /page/123, it will direct you to /page/123?checkout=54321 and "check out" the attendance record with ID 54321 by adding an "EndDateTime" value of the current timestamp. The Attendance ID is something that was already looked up and embedded in the "Delete" button, so the user never even needs to know about it.

If you have multiple check-out stations, they can use the "Filter Options" fields at the top of the list to specify a single schedule, campus, class or a combination of any of the above to trim the list down to just the kids they need to see.


Slick, eh?

Three cheers for the visionary Spark team!

Spark Development Network
Flagstaff, AZ

Michael Garrison recently left his job in Architecture to become one of the "new guys" at Spark (the "Core Team"), but he's still helping out Christ's Church of Flagstaff and other non-profits with tech needs in his off-hours, trying to make computers do what computers do best, so that people are freed to do what we do best: relate with people!