Voting in Gravity Forms

This is one of those unique needs but with base elements that are likely to be useful in other scenarios. It looks at the logical operators in Gravity Forms which require no programming knowledge, looks at using cookies to discourage more than one entry, and finally moves to using the API to display data. That’s a decent tour of complexity and capability.

Origin Story

People wanted to vote. They get to vote for 5 people. There are 5 known people on the ballot (multi-select checkbox) but people can also write in candidates but they could submit no more than 5 people total. Additionally we wanted to prevent people from voting again but did not want the overhead of user accounts and did not want to compromise privacy by using email addresses. And the final goal was to have a visible count of votes cast.

Party of 5 Solution1

Gravity Forms will let you do conditional logic. In this case I set up our primary field as a checkbox with our 5 main people as options. I then made 5 free entry text fields. I set the logic so that each free entry field will be hidden if the paired checkbox is checked. Checking person 1 results in free entry field 1 going away, checking person 2 removes free entry 2 etc. etc.
Gravity Forms screenshot showing the logic operators described above.

One Person, One Vote

We’re just going to give voters a cookie and look for that cookie if they come back. If it’s there, we’ll redirect to an already voted page. This is pretty much stock from this Stack Exchange conversation.

//PREVENT DUPLICATE VOTING BY COOKIE -- yeah, not strong but it is what it is
add_action( 'gform_after_submission_4', 'wpse_set_submitted_cookie', 10, 2 );

function wpse_set_submitted_cookie( $entry, $form ) {

    // Set a third parameter to specify a cookie expiration time, 
    // otherwise it will last until the end of the current session.

    setcookie( 'wpse_form_submitted', 'true' );

add_action( 'template_redirect', 'wpse_protect_confirmation_page' );

function wpse_protect_confirmation_page() {
    if( is_page( 'vote' ) && isset( $_COOKIE['wpse_form_submitted'] ) ) {
        wp_redirect( home_url( '/already-voted/' ) );

Voting Transparency

I opted to leave the free entry portion alone for this round. That stuff gets messy and the most you can do is show a list of free entry elements sorted alphabetically.

I used the Gravity Forms API to look at the data and then spit out via shortcode. You could make this more extensible with another query to see how many options were in the form field but for this purpose we knew there were 5 and so it looks like this.

$form_id = 4;//FORM ID
  $entries = GFAPI::get_entries($form_id, $search_criteria, $sorting, $paging, $total_count );
  foreach ($entries as $key => $value) {  
      if ($value['1.1']){
        $vote_1 = $vote_1+1;
        $candidate_1 = $value['1.1'];
      if ($value['1.2']){
        $vote_2 = $vote_2+1;
        $candidate_2 = $value['1.2'];
      if ($value['1.3']){
        $vote_3 = $vote_3+1;
        $candidate_3 = $value['1.3'];
      if ($value['1.4']){
        $vote_4 = $vote_4+1;
        $candidate_4 = $value['1.4'];
      if ($value['1.5']){
        $vote_5 = $vote_5+1;
        $candidate_5 = $value['1.5'];

     $html .= '<ul><li>' . $candidate_1 . ' - ' . $vote_1 . ' votes</li>';
     $html .= '<li>' . $candidate_2 . ' - ' . $vote_2 . ' votes</li>';
     $html .= '<li>' . $candidate_3 . ' - ' . $vote_3 . ' votes</li>';
     $html .= '<li>' . $candidate_4 . ' - ' . $vote_4 . ' votes</li>';
     $html .= '<li>' . $candidate_5 . ' - ' . $vote_5 . ' votes</li></ul>';

Comments on this post

  1. greg said on August 3, 2020 at 4:22 pm

    How could I add a photo to each voting option?