Posted on by

Sometimes, you want to give the user the ability to select from a list if things that are in the database, rather than a fixed set of options as defined in the field definition. This will require some simple PHP along with a database query, but once you get the idea, a lot of other possibilities will become available to you.

Our Example

So, for this tutorial, let’s say you have a signup form for volunteers. Your volunteers fill out the form and indicate that they are willing to volunteer their time for a project. Let’s say you also have volunteer coordinators that have a different signup form where they can select a volunteer to assign to the project. (I’ve explained how to set up different signup forms for different kinds of people in another tutorial.)

When the volunteer coordinator signs up, you will want to provide them with a dropdown selector that lists all of the volunteers. The only way to do that is to get the list of volunteers from the database and then use that to populate the dropdown.

The Query

To get our list of volunteers from the database, we need a query that gathers the information we need (in this case, their name) from the records that we know are from volunteers. Referring to the method in the Multiple Registration Forms article, we have a field in the form that is filled with the name of the page the form was on. This is how we will know whether the record was created by a volunteer or not. Let’s say the volunteer’s form is on a page named “volunteer-signup” and the coordinator’s form is on a page called “volunteer-coordinators.” To get one and not the other we need two statements.

Here is our query:

SELECT first_name,last_name 
FROM wp_participants_database
WHERE form_type LIKE "%volunteer%" 
  AND form_type NOT LIKE "%coordinator%"

That will get us our list of names of all the volunteers.

With WordPress, it’s best to use the $wpdb object for interacting with the database. To get an array of values, we use the $wpdb->get_results method like this:

<?php 
global $wpdb;
$values = $wpdb->get_col( '
   SELECT first_name,last_name 
   FROM `' . $wpdb->prefix . 'participants_database` 
   WHERE form_type LIKE "%volunteer%" 
     AND form_type NOT LIKE "%coordinator%"
' ); 
?>

There is no user input here so we don’t need to sanitize the query. This will give us an array of objects, one for each record returned.

Altering the Dropdown

This part is pretty simple if you are familiar with using WordPress actions. When the action is triggered, our function will be called, and it is given the Participants Database form element object for the current form element. Our action, in this case is documented as: pdb-form_element_build_{$type} which means if we want to use it on a dropdown-type form element, the final action slug will be pdb-form_element_build_dropdown. The action is triggered on every dropdown form element, so we need to check to see if the current element is the one we want to add the options to. Because it is an action, we won’t be returning any value. As is often the case with actions, we can change the state of the given object in the function that is triggered by the action. When that object is used next (such as to print the form element) it will include our changes.

The Plugin

Here is the fully-commented code for the plugin:

That can be downloaded as a ZIP file here, then uploaded to your WordPress using the “Add Plugin” functionality.

Posted on by

The Field Group Tabs add-on adds tabs to the single record display, record and signup forms when you add the tabs=true attribute to the shortcode. What that does is select a default tabbed template for the form, and loads the necessary javascript and CSS to show the tabs. To use a custom template with the Field Group Tabs add-on, you need to alter your custom template so that it loads the resources needed and adds the HTML to the template.

This feature as added to Field Groups Tabs as of version 1.6, so make sure you are using the latest version of Field Group Tabs.

Altering Your Custom Template to Show the Tabs

For this tutorial, we will be using a template for the record edit shortcode, but the procedure is the same for the signup form template.  It’s also the same for the single record template, although there is no submit button, so you can skip that part for the single record template.

The tabs add-on works by making two additions to the template. At the top, it adds some javascript, some CSS, and the tabs control html to the template. This is all added with a single function call. The other addition is the “next/submit” button near the bottom of the template.

At the Top of the Template

The tabs add-on uses this code to add the tab control and everything needed to make the tabs work:

<?php pdb_field_group_tabs( $this ) ?>

This is added just after the $this->print_form_head() function call, like this:

The Submit Button

To place the next/submit button, you must replace the default submit button with a function that shows either the next or submit button, depending on the plugin settings and which tab is active. This is the code that prints out the next/submit button:

<?php pdb_field_group_tabs_submit_button( $this ) ?>

The tricky thing is, this button has to go inside the group <fieldset> so that each tab has it’s own button. We also have to remove the original <fieldset> for the submit button, since we won’t need it anymore.

This is a section of the default bootstrap record template where the submit button is shown:

We want to eliminate the whole final <fieldset> and place our button inside the group fieldset, like this:

I hope that is clear, it’s a little complicated, I know.

Now, Using the Custom Template

Now, we have our custom template, you’ll need to upload it to the templates folder in your theme directory (or wherever you have your plugin templates). In the shortcode, make sure you have the tabs=true attribute as well as the template=custom attribute to select your template. The “custom” in that attribute is the name of your template, make sure it matches the name you used when you saved your template. This is all explained in the Using Custom Templates article. For example:

[pdb_record template=custom tabs=true]
Posted on by

Setting up a custom validation method is relatively easy if you’ve got some PHP skills. If you’re familiar with using WordPress filters, then you’ve got the basic knowledge you need to set this up.

If you’re not sure what WordPress filters are and how to use them, there is a good intro article that should give you the basics: WordPress Actions, Filters, and Hooks : A guide for non-developers

Generally, however, doing this is going to require some knowledge of how to write some basic code because you’re going to have to figure out how to fill your particular need. I’m giving you a very simple example so you can see how all the pieces work.

How to Build a Custom Validation

A custom validation method consists of two parts: the validation code and the validation error message. The validation code is the part that looks at the submitted value and decides whether the input is OK or not. The error message is the user feedback message that is shown when a particular type of validation error occurs.

We will need to create a callback for each of these two things. It’s best to put these in a simple plugin, but your theme functions file will do also.

The Validation Callback

This callback is set up on the ‘pdb-before_validate_field’ action. The way this works is the action is triggered just before each field validation occurs. If you set up a callback that validates the field, that field won’t get validated by the normal methods because the plugin will see that the field has already been validated.

If you refer to the docs, you’ll see the properties of the object that is passed in with this action. All we need to do in our callback is check the field to see if it is one that we are validating, then check the value to see if it is valid, then set the ‘error_type’ property to either ‘valid’ or, if it is invalid, the type of validation error it is. That validation error type is the key to a validation error message which we will define later.

An Example Validation Callback

Let’s say we’re doing something really simple like checking to make sure the value is a valid URL. If the user submits a valid URL we mark it “valid” but if it is not, we mark it “invalid url”. Here is the callback code for that:

Pretty simple, huh? Of course, a real-world example would be more complex, but you can basically do anything you want inside that function to validate the field. For instance, if you wanted to validate the field against the value of another field, you can do that by inspecting the $_POST array, which will contain all the values that are currently getting submitted.

Setting Up the Validation Error Message

This one requires a filter callback that adds your validation error message to the array of validation methods the plugin uses to give the user feedback after they submit a form.

As per the docs, the filter passes in an array of validation error messages. We just need to add our message to that array and return it so it can be shown to the user if the field validation fails. Here’s a simple example of how to do that:

And that’s all there is to that. In a real application, the error message would likely be wrapped in a gettext function so that it can be translated.

Now, all that’s left to do is test it to make sure it works the way you want.

Posted on by

A not-uncommon scenario in a form is the case of City/State selectors. If the user chooses a state, it would be nice to let them choose the city without seeing cities from other states. This same principle can apply to many situations where the value of one selector is used to limit the selections available in another.

This kind of thing typically requires some fairly complex code because real-world forms applications tend to be complicated. Most of the time, if you need this kind of dynamic behavior in your form, you’re either going to code it yourself if you’ve got the skills or hire someone with the skills to do it.

An Example of Optgroups in a Dropdpwn Selector

A Simple Approach

What if all we needed was something simple like our first example?

There is a way to do this that doesn’t require a lot of code, as long as all the options can be present when the form is loaded, and there is a simple relationship between the two selectors. The basic idea is you have a “parent” selector and a “child” selector. The parent selector determines which options are available in the child selector…in our example the parent is the state selector and the child is the city selector.

Note: this tutorial won’t work for Chosen selectors, it is for regular dropdown selectors only.

Here is How That Gets Set Up

The way this works is the child selector’s options are divided into groups using “optgroups” that correspond to the selections in the parent selector. For example, if you’ve got 25 states, the city selector will have 25 optgroups that have labels that match the states. Each of those optgroups will contain the cities for that state. This way, we know that when a state is selected, we can use the value of that selection to find it’s corresponding group in the cities, and only show the members of that group: the cities in that state.

In Participants Database, the cities dropdown is set up with a values string like this (this is not the complete string, just enough to show how it is structured):

Alabama::optgroup, Birmingham, Montgomery, Mobile, Huntsville, 
Alaska::optgroup, Anchorage, Arizona::optgroup, Phoenix, Tucson, 
Mesa, Chandler, Gilbert, Glendale, Scottsdale, Tempe, Peoria, 
Surprise, Arkansas::optgroup, Little Rock, California::optgroup, 
Los Angeles, San Diego

And the “state” selector gets a values string like this:

Alabama::AL, Alaska::AK, American Samoa::AS, Arizona::AZ, 
Arkansas::AR, California::CA

The Javascript

Now…for the code. First, this needs a custom template. If you’re not familiar with how to set one of those up, take a look at the linked article. Our code doesn’t change the body of the template at all, it just adds the javascript that performs the trick of changing which options are available in the child selector. If you want to use a different template, you can just paste the javascript into it and it will work in either a record template or a signup template.

Here is the javascript with plenty of comments to help you understand how it works. All you will need to do is make sure the parent and child field names are set to match what you’re using for the parent and child fields.

Note: this code was updated on February 17, 2017 to allow the child’s value to be shown initially

And just so you can see it in action, here it is in a signup form template. You’ll notice that it is simply inserted at the top, after the PHP close tag and before the <div> tag. When the template is loaded the script goes into action, putting a handler on the parent field so that when a selection is made, the child selector will show the appropriate selections.

 

 

Posted on by

Sometimes it’s necessary to create a custom form element to handle a specific need for a UI element in a Participants Database form. The means for doing that have been set up in the plugin, you’ll  definitely need some coding skills to get this done, so this post will only briefly cover the basic steps to setting up a custom form element. You are expected to know how to make this into your own custom form element.

The first step is to register your custom element with the plugin so that it can be selected in the field definition.

pdb-set_form_element_types

This filter is used to add the new form element identifier. The full definition array of form element types is passed through, a new element should be added to the array in the form: type_handle => title. Your custom form element type will show up in the Form Element dropdown on the Manage Database Fields page.

NOTE: This post was updated on February 15, 2017 to correct an error and add additional information

Showing a Custom Form Element in a Form

For this, we use the pdb-form_element_build_{$type} action.

This action is triggered when a form element is instantiated. When the element is instantiated, the FormElement object will be passed to the action handler. The handler is expected to fill the ‘output’ property with the HTML string. The handler argument is passed by reference so other changes to the element object are possible in addition to defining the output HTML.

This action can also be used to override an existing element build function. If the FormElement object already has it’s output property filled with HTML, the standard build method will be skipped.

Showing the Value of a Custom Form Element

Each form element has a way to show it’s value in a non-form context, and that can be customized as well. For that, we use the pdb-before_display_form_element filter which is supplied the raw value of the field and the PDb_Field_Item object for the element. Typically, you’d test the field object to see if it was your custom form element, then return the appropriate display HTML.

An Example

Let’s say you want to create a custom form element that stores an array of 3 values. You could give the element a handle of ‘array’ and a title of ‘List.’ Your filters/actions could be added like this:

add_filter( 'pdb-set_form_element_types', 'my_array_register_element' );
add_action( 'pdb-form_element_build_array','my_array_element_building_function' );
add_filter( 'pdb-before_display_form_element','my_array_element_value_display_function' );

The my_array_element_building_function() should return the PDb_FormElement object with the ‘output’ property filled with the HTML needed to display the element in a form. The my_array_element_value_display_function() should return the display value of the form element.

Here is the full code for our example. This one is way too simple to be used as-is, it’s only to show you how the parts go together, you can take it from here.

Posted on by

Let’s say you have a site where you want to register two types of people. We’ll call them “Red” and “Blue.” Each of those forms is going to have some fields in common and some fields that are different for each signup form.

The first thing to do is to organize your fields into groups. Field Groups are defined on the Manage Database Fields page under the “Field Groups” tab. One or more groups would contain all the fields that are common to both registration forms: things like name, address, email, etc.

Once you’ve got your common groups set up, you’ll need to set up at least one group for each form that contains the fields for the particular type of registration the form is for.

Tracking Which Form was Used

Since all the registrations will be contained in the same database, you’ll need an easy and reliable way to tell them apart. A good way to do this is to use a hidden field that records the name of the page the form is on.

Set up a hidden field in one of the common groups. You can name it “Form Type” or whatever you want that indicates that the value determines which form was used. In the “default” value for the hidden field, put post->post_name That will be automatically filled with the name of the page the form was on.

Setting Up the Signup Shortcodes

Once you have all your groups defined, set up your shortcodes. You’ll have one shortcode for each type of registration, and they will need to be on different pages. Setting up two different forms is done using the “groups” attribute of the shortcode.

Let’s say you have 3 field groups, one common one and one group for each type of registration form. We’ll call them “common,”  “red” and “blue.” When you set up the shortcodes, you can do it like this:

Red Form: [pdb_signup groups="common,red" ]

Blue Form: [pdb_signup groups="common,blue" ]

Telling the Registrations Apart

Now, when you list the registrations, you can easily show one or the other using a filter. Let’s say you wanted to show only the “Blue” registrations.  The blue form was on a page named “blue-registration” so you’d do it like this:

[pdb_list filter="form_type=blue-registration"]

And that would show all the records that were created using the “Blue” form.

That should get you started on your project that uses more than one kind of registration form.

Posted on by

A few months ago, I wrote a tutorial on how to automatically send an email when a record is updated. I’ve gotten several requests for something very similar: how to send an email to a person who has signed up, but ONLY after their submission has been approved. This is a good way to avoid spam submissions showing up on your site if you have an open registration form, so that anyone trying to sell you “real” Gucci bags isn’t getting added as a legitimate signup.

The first thing you’ll need to do is set up an approval checkbox as an administrative field (that is, it’s in an admin field group) and set up all your frontend displays to exclude showing unapproved records.

The original tutorial steps you through the creation of a simple plugin to add that functionality to Participants Database. You should read that article if you want to learn in detail how that is done. Anyway, the tutorial ends up with a plugin script that looks like this:

To get our functionality, what we need to do to that script is add a function that checks that the previously saved record was not approved and that the record is currently getting updated with an approval. If those conditions are met, we know that we need to send out the “welcome” email. We do that by loading the saved record, check if it’s unapproved, then check the update data to see if it is getting approved. A good way to do this is to create a function that does the checking…like this:

function pdb_record_is_getting_approved( $new_record )
{
  $old_record = Participants_Db::get_participant( $new_record['id'] );
  if ( $old_record['approved'] !== 'yes' && $new_record['approved'] === 'yes' ) {
    return true;
  }
  return false;
}

We just use that function to determine if the email should be sent or not. We put that in the section of the plugin that sends the email so it will skip sending it if the record isn’t getting approved at that point:

if ( pdb_record_is_getting_approved( $post ) ) {
    PDb_Template_Email::send( $config, $post );
  }

Pretty simple, huh? You’ll notice I used a long descriptive name for the function: that’s so the code ends up being more readable. Maybe that’s not needed for such a simple script, but it’s a good coding practice that will save you time later when you’re trying to fix bugs or change how things work.

Before you activate this plugin and start using it, uncheck the “Send Signup Response Email” in the plugin settings so that the regular signup greeting is not sent.

Here is the completed plugin:

Posted on by

I sometimes get requests to have Participants Database links to locations off the website open in a new window or tab. Depending on the context, this can be inadvisable from a user experience point of view, but even so, we need to be able to set that up sometimes. So, with that caveat in mind, this is how we do it…

To alter the way database data is shown, we use the ‘pdb-before_display_form_element’ filter. It gives us the field object which contains all the data for the field, and expects the HTML in return. If we want the plugin to do it’s thing normally, we return an empty string.

This filter is applied to all fields before getting displayed, so we want to be sure to only alter the ones we want changed. We need to determine if the field is a link field and that it has a link to an external location. If not, return the empty string.

This plugin is very simple: create a new file with the name pdb_external_links.php and code below. Upload it to your plugins folder and activate.

Pro tip: click on the filename in the code window above, then download the .zip file and install it.

That’s it, all external links will open in a new tab or window when the user clicks on them.

(Note: this post was edited for better code on Nov 30, 2016)