Drupal Display Suite Webform Submissions as Tabbed Panes

In recent blog posts I keep covering my recent project to accept submissions of student references for a campus offered Program.

I wanted a nice way to view a large number of submissions per student application. To do this, I leveraged a module I’ve heard of readily but rarely use, Display Suite (DS).

Display Suite allows you to take full control over how your content is displayed using a drag and drop interface. Arrange your nodes, views, comments, user data etc. the way you want without having to work your way through dozens of template files. A predefined list of layouts (D7 only) is available for even more drag and drop fun!

By defining custom view modes (build modes in D6), you can define how one piece of content should be displayed in different places such as teaser lists, search results, the full node, views etc.

Knowing this, I set about creating my own view_mode for a student application and I basically created a Display Suite Code Field which loads the Nth submission for a record as a tabbed pane. The tabbed panes in DS actually also require the field_group module. However many submissions we want to show in tabbed panes in Drupal is completely controlled in the DS Administrative GUI screen.

The end result layout I wanted visually is:

reference_tabs

I define the above layout 100% using Display Suite’s Admin GUI, it configuration looks like:

ds_student_record

Then I make a custom code field per Reference Number and each code field has the following code in it (in the above image ref render 1 is such a code field):

<?php
return _mymodule_render_reference_tab($entity->nid);
?>

Really that is all the code within the DS Code Field. This is a good practice, to call a function that does our work of rendering a tabbed item. How do they all share 1 function you might ask?! The answer is static variables in PHP functions.

The code for this function is:

/**
 * This function walks through known submissions and returns 1 result per
 * invocation request after page load.
 */
function _summer_session_logic_render_reference_tab($nid) {
  static $submission_content = NULL;
  static $ref_num = NULL;

  if ($submission_content === NULL) {
    $submission_content = _mymodule_render_reference_submissions(
        _mymodule_lookup_submitted_references_for_applicant_record(
        $nid
    ));
  }
  if ($ref_num === NULL) {
    $ref_num = 0;
  }

  $content = (isset($submission_content[$ref_num]) && !empty($submission_content[$ref_num])) ? $submission_content[$ref_num] : "<p>No reference submitted.</p>";

  $ref_num++;
  return $content;
}

Whoa! What’s going on here?! The 2 helper functions hopefully will enlighten you:

/**
 * This function looks up completed submission SIDs for the given Node Id.
 */
function _mymodule_lookup_submitted_references_for_applicant_record($nid) {
  $efq = relation_query('node', $nid);
  $efq->addTag('LookupSubmittedReferences');
  $efq->propertyCondition('relation_type', 'user_has_survey');
  $result = $efq->fieldCondition('field_rel_webform_submitted', 'value', 1)
      ->execute();
  $survey_relations = relation_load_multiple(array_keys($result));

  $submission_ids = array();
  foreach ($survey_relations as $relation) {
    $submission_ids[] = $relation->field_rel_webform_sid[LANGUAGE_NONE][0]['value'];
  }
  return $submission_ids;
}

/**
 * This function builds an array of HTML fragments of rendered submissions from
 * a collection of Submission IDs.
 */
function _summer_session_logic_render_reference_submissions($sids) {
  $content = array();
  if (count($sids)) {
    module_load_include('inc', 'webform', 'includes/webform.submissions');
    $webform_nid = 1;
    $webform_node = node_load($webform_nid);

    foreach ($sids as $sid) {
      $submission = webform_get_submission($webform_nid, $sid, TRUE);
      $webform_renderable = webform_submission_render($webform_node, $submission, 'test@test.com', 'html');
      $content[] = drupal_render($webform_renderable);
    }
  }
  return $content;
}

So, in a nutshell when the page loads for the page /open-applications/MASTER_NUMBER the following occurs:

  • Find all submissions associated to the Node ID.
  • Render all the submissions once and store the result in an array.
  • The DS code field(s) simply “request” to render a submission and the static variables “walk” through the submissions and return only 1 submission per Tab.
  • note: I also add a Tag to the RelationQuery EntityFieldQuery, since it’s an EFQ I made to use JOINs or other custom SQL to get the behavior I want from the Query. A tag lets me alter the query at runtime in PHP before it’s passed off to SQL.

In order to add more Submissions or Tabs to our page. We’d add them to the CSV and Migration for this project — then simply change the Display Suite settings for this page and add more Code Fields into the tabset. Each code field would simply call _mymodule_render_reference_tab($entity->nid); for its content. In my opinion this setup is very maintainable from a developer perspective!

Looking for quality Drupal Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , , , , , , , , , | Posted under Drupal | RSS 2.0

Author Spotlight

David Gurba

David Gurba

I am a web programmer currently employed at UCSB. I have been developing web applications professionally for 8+ years now. For the last 5 years I’ve been actively developing websites primarily in PHP using Drupal. I have experience using LAMP and developing data driven websites for clients in aviation, higher education and e-commerce. If you’d like to contact me I can be reached at david.gurba@arvixe.com

Leave a Reply

Your email address will not be published. Required fields are marked *


3 × = 3

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>