Taking Reservations in Gravity Forms

I should have written this post first, but I didn’t.

Give me some credit. I’m still writing stuff on the Internet. The years have proven that’s a higher bar than one might expect.

So, we want people to be able to register for events and we want to be able to send them emails, mark attendance, a few other things. Events Calendar Pro is our plugin of choice for events. I’ve expanded the options there a bit with Advanced Custom Fields Pro.

I use ACF to add three fields. There’s one for a Zoom link, one for a registration limit, and the final one is a repeater field for resources.1 I like ACF for this as it gives me more control and easier access to the data (as opposed to using Events Calendar additional fields).

Add the reservation form to all events

The following code takes some of the ACF fields and just puts them in the Gravity Form entry as hidden fields that I’ve set to allow field to be populated dynamically. It also puts the form in the event.

To more easily modify the Events Calendar template, you can copy over the file in your theme at tribe-events > single-event.php

$values = array(
       	'event_name' => get_the_title(),
       	'event_id' => get_the_ID(),
       	'zoom_link' => get_field('zoom_link'),
       	'event_date' => tribe_get_start_date(),
       	'resources' => dlinq_event_resources()
       	); 
     gravity_form( 5, false, false, false, $values, false, null, true, null, null);

Show who registered

Since we’re logging the event_id in the form, we can easily show who registered for that event.

We’re using the good old GFAPI::get_entries to search the form (ID = 5) for posts that have the right event ID.

We also use current_user_can(‘edit_posts’) to make sure only admins can see these registration.

Then we spit out all the registrations so that we have a list of names and a button that lets us mark a person as attending. That data gets written to the Gravity Forms entry via ajax.

function dlinq_registered_people(){
	if(current_user_can('edit_posts')){//are you an admin? good . . . 
		global $post;
		$post_id = $post->ID;
		$search_criteria = array(
			    'status'        => 'active',
			    'field_filters' => array(
			        'mode' => 'any',
			        array(
			            'key'   => '6', //where the event ID gets written
			            'value' => $post_id
			        )
			    )
			);
	 
		// Getting the entries
		$results = GFAPI::get_entries( 5, $search_criteria );
		if($results){
			echo "<div class='registration-block'><h2>Registrations</h2><ol>";

			foreach ($results as $key => $result) {

				$entry_id = $result["id"];
				$created = $result["date_created"];
				$first = $result["1.3"];
				$last = $result["1.6"];
				$email = $result["3"];
				$attendance = $result["8"];
				$attend_class = ($attendance == 'No') ? '' : 'present';
				echo "<li class='reg'>
						<span class='reg-name'><a href='mailto:{$email}'>{$first} {$last}</a></span>						
						<span class='reg-date'>{$created}</span>
						<span class='reg-state'>attended: <button class='attend {$attend_class}' data-entry='{$entry_id}' data-state='{$attendance}'>{$attendance}</button></span>

					</li>";
			}
			echo "</ol></div>";
		}		

	}
	
}

Ajax attendance

I always have to look this up and then get irritated before I get all the pieces of WP ajax working.

// register the ajax action for authenticated users
add_action('wp_ajax_dlinq_attendance_update', 'dlinq_attendance_update');
function dlinq_attendance_update() {
    $entry_id = $_REQUEST['entry_id'];
    $entry_state = $_REQUEST['entry_state'];
    if($entry_state == 'No'){
    	$entry_state = 'Yes';
    } else {
    	$entry_state = 'No';
    }
    GFAPI::update_entry_field( $entry_id, '8', $entry_state, '' );
}
function dlinqAttendance(){
	if(document.querySelector('.attend')){
		const attendButtons = document.querySelectorAll('.attend');
		attendButtons.forEach((button) => {
		  button.addEventListener('click', () => {
		    jQuery.ajax({
	        type: "POST",
	        url: dlinq_attendance_update.ajax_url,
	        data: {
	            action: 'dlinq_attendance_update',
	            // add your parameters here
	            entry_id: button.dataset.entry,
	      			entry_state: button.dataset.state,
	      			nonce : dlinq_attendance_update.nonce,
	        },
	        success: function (output) {
	           button.classList.toggle('present');//add or remove class
	           button.innerHTML = button.innerHTML == 'No' ? 'Yes' : 'No';//change button text
	           button.dataset.state = button.dataset.state  == 'No' ? 'Yes' : 'No';//change data attribute

	        }
        });
		  });
		});
	}
}

1 Likely overkill.

Leave a Reply