Whilst working on a redesign of an RSPCA branch website I came across a tidy solution to make the interface for potential adopters completing the online adoption form more intuitive

The redesign uses a custom post type (CPT) to store the animals that are available for adoption on the website. This works great for having archive and single templates for the CPT. I wanted to go a step further with the CPT and automatically populate a form field on the adoption form page with the names of the animals available for adoption.

This was quite easy to do using one of the built-in functions of GravityForm called gform_pre_render . It allowed me to run a custom get_posts  query to grab post titles (animal names) from the CPT as well as filter the posts by my custom taxonomy as our CPT can hold cats, rabbits or guinea pigs. The post titles are then populated as the values for the checkbox field I am using to select the animal the adopter is interested in. Pre-populating this field meant no-one had to think about adding or removing animals from the form field when animals are added or removed from the site.

Whilst thinking about the problem, I discovered a few tutorials online for replacing checkboxes with actual images which is a fantastic way of presenting the animal options in a nice clear visual manner.

I already had a function to grab my CPT which meant I could then access post thumbnail image information from the query. The post thumbnail was then used to build the value of the checkbox field for each of the animals. The result is a nice visual interface:


The full code for this function and the related CSS styling can be found below. Note that no jquery was used to perform this modification.

// Change '2' to the ID of your form
add_filter( 'gform_pre_render_2', 'populate_checkbox' );
add_filter( 'gform_pre_validation_2', 'populate_checkbox' );
add_filter( 'gform_pre_submission_filter_2', 'populate_checkbox' );
add_filter( 'gform_admin_pre_render_2', 'populate_checkbox' );

function populate_checkbox( $form ) {

    foreach( $form['fields'] as &$field )  {
        // Change '41' to the ID of your checkbox field
        $field_id = 41;
        if ( $field->id != $field_id ) {
        // adjust your get_posts query as necessary
        $args = array(
                'post_type' => 'pet',
                'post_status' => 'publish',
                'posts_per_page' => -1,
                'tax_query' => array(
                                'taxonomy' => 'pet_category',
                                'field' => 'slug',
                                'terms' => 'cat'

        $posts = get_posts( $args );

        $input_id = 1;
        foreach( $posts as $post ) {

            $feat_image_url = wp_get_attachment_image( get_post_thumbnail_id( $post->ID ), 'thumbnail' );
            $feat_image_url .= '<br />' . $post->post_title;

            if ( $input_id % 10 == 0 ) {

            $choices[] = array( 'text' => $feat_image_url, 'value' => $post->post_title );
            $inputs[] = array( 'label' => $post->post_title, 'id' => "{$field_id}.{$input_id}" );


        $field->choices = $choices;
        $field->inputs = $inputs;


    return $form;

And the CSS

    Change 2 and 41 to your form ID and field ID
.gform_wrapper .gfield_checkbox li[class^="gchoice_2_41_"] {
	display: inline-block;

.gform_wrapper .gfield_checkbox li input[type="checkbox"][id^="choice_2_41_"] {
	display: none;

.gform_wrapper .gfield_checkbox li label[id^="label_2_41_"] {
	border: 1px solid #fff;
	padding: 10px;
	display: block;
	position: relative;
	margin: 10px;
	cursor: pointer;
	-webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;

label[id^="label_2_41_"]:before {
    font-family: "font-icons";
	font-size: 32px;
	color: #1abc9c;
	content: " ";
	display: block;
	background-color: transparent;
	position: absolute;
	top: -5px;
	left: -5px;
	width: 25px;
	height: 25px;
	text-align: center;
	line-height: 28px;
	transition-duration: 0.4s;
	transform: scale(0);

label[id^="label_2_41_"] img {
	transition-duration: 0.2s;
	transform-origin: 50% 50%;

:checked + label[id^="label_2_41_"] {
	border-color: #ddd;

:checked + label[id^="label_2_41_"]:before {
	content: "\e6c8";
	background-color: transparent;
	transform: scale(1);

:checked + label[id^="label_2_41_"] img {
	transform: scale(0.9);
	box-shadow: 0 0 5px #333;
	z-index: 0;