You are here

Using Webform View in Webform view 7

Same filename and directory in other branches
  1. 7.4 help/index.html

Webform View is a module that allows you to embed a view as part of a webform. Form elements (checkboxes, quantity selectors) are inserted into each result row. Data in this view can then become part of the data submitted in the webform submission.

The primary use-case this was built for is to enable a webform to be used as an order form where a user can select  items displayed in the view, and request those resources or register interest in them in a way that the reciever of the submission can work with.

Due to a change in webform added in function webform_client_form_pages() http://drupalcode.org/project/webform.git/commitdiff/7bc797adb3ff27f8dc3... the order of processing was reversed and webform 4.x is incompatible with webform_view. this cannot be cleanly fixed yet!

Desired workflow:

  • A website administrator can publish information about resources (pamphlets, publications) or even products or topics as nodes on the website. This can be added to at any time.
  • A view is created that lists these items. Full UI control of that layout uses normal view and template tools.
  • A webform is created that displays that view, and includes either a checkbox or quantity field next to each item.
  • When a user submits the form, their requests for each item are registered. Data on the submissions is managed using the Webform UI controls.

Execution:

Was hard. Webform doesn't natively support multiple/unlimited selections very well, and doesn't like the available options being dynamic very well. Although with recent developments in the webform+select+views options, a simple list of options can now be supported, anything more (item+quantity data) is still out of reach.

Instead, an extension to webform (described above) was developed. To work, it has to do some brain-surgery on both the display and the results processing. This is described here. Although there are now several moving parts that have to be configured, this was engineered to produce the desired result in a highly re-usable and configurable way.

Usage (overview):

  • Create your resource content type.
  • This content type should include an extra "can order" sort of field, which may be used to indicate where the per-row webform elements get inserted in displays. This is an additional field "render mode" called "webform placeholder" that will be available for some content fields Create it as a type:"Boolean" widget:"single on/off checkbox" field. Set its default value to TRUE. The flag and custom field is managed like this to provide maximum compatibility with normal UI-based display management and positioning options.
  • Create a view that lists your resources. Configure its display. A 'page' type display will be fine. This view should be able to use either node display or fields, as well as alternate view modes or display_suite based displays as needed.
  • Create a webform that users can use to order resources. This should contain contact details etc as needed.
  • Embed the view into the webform (new functionality). This is done using a new webform element "Embedded view".
  • Add additional webform fields as children of the view element (as if it were a fieldset). These fields will be propogated to create new webform fields for each item in the view.
  • Go back and edit the view display to configure where these webform fields (the "webform placeholder") should be placed in the display of the view. This gives you maximum layout control in how your final form will look.

At this point, using the webform should merge all functions together. Viewing the webform should display the view, and include form fields in the layout location of the "webform placeholder". Submissions to this webform should save the values for each item in the view. Generated emails should list each selection.

Usage (full setup instructions):

  1. Download/enable required modules.

    Though not required, for this demo I'll also use

    • file (core)
    • image (core)
  2. Create a "resource" content type.

    Add some basic fields, eg file and image.

    Add our marker field. "Can order" as a Boolean checkbox.

    Under "Field Settings", set "On Value" to "Can Order" and "Off Value" to "Cannot Order". Then set the default value to "Can Order".

  3. Add some sample resources.

    For variety, I'll show one that is available in hardcopy-only, one that is download-only, and one that is both. This is enabled by our "can order" checkbox field.

  4. Create a view that shows these items.

    Just a view that filters on type:resource will do here. I'll use a table+fields view display for now, though I'd recommend using teasers (or view mode) display most of the time. 
    You don't need a 'page' display, and some views options like paging will not work in this context, so leave them out.



    With a small amount of adjustment, we get a view that produces this:

    Note our "Can order" field will be where the webform will do its thing soon.
    This is the view we will embed in our webform.

  5. Create the webform.

    Add whatever normal fields you need in the webform for submission as usual.

  6. Insert the view into the webform.

    Here use the new webfrom view webform component "Embedded view". I'll call it "Order"

    In the options for this field you should choose the "View" we just created. The "Master" display should be adequate.

  7. Add webform fields as child elements to our embedded view.

    These fields will need to record at least
    A: the item name,
    B: the request submitted with this form.

    So add two fields. Importantly - they must be positioned as children of the view.
    The item name will already be apparent to users, and should not be displayed as a field, so make it hidden. (We will have to fill in data there ourselves, see below)

    I'll add a number "Quantity" field here too, though a checkbox would also work for some cases.

    A required field (eg quantity) must also be chosen. This is set in the settings screen for the embedded view component. When results are saved, any row with a blank 'quantity' will not be saved, only rows with options actually entered in them will. If we don't filter, then all the submission results list all rows each time, even if quantity was zero, and that looks messy on email notifications etc. You can only choose which field is required after adding all child fields to the parent container. This means visiting the same settings page twice.

  8. Get the item description into the webform fields.

    Sorry, This is one extra fiddly step, used to ensure that the text in the submission results names the selected item appropriately.

    1. Edit the hidden "Item requested" field and get it to use a token that will be deduced from the view data it is being applied to.
    2. Set its "default value" to the string "[node_title]".

    This was required as various view_modes and views rows may have different data available. For example you may want to add a "[field_field_sku]" or "[nid]" there as well to better identify the resource in question. User-created fields are available as [field_${field_id}] so the syntax often is [field_field_something]. This is from the way views internals names its values. [node_title] is only available in field-based-views, not teasers or view-modes! Arg? This is because, internally, the view doesn't make that data available at this point in rendering.

    There is a work-around. This is not needed in field-based views, where the value of each rows field should be available as a token like this.
    If using teaser-based views, Add an extra "Sort criteria" to your view definition. Sort on "Content: Title". This is enough to make the above token have some data to work with, even if the sort cirteria is weighted lower than the "Post date" - effectively making it an ineffective sort.
  9. Conceptual re-cap

    These fields, which we have defined using the webform UI, need to be displayed as part of a view, which is in turn being pulled in and displayed as part of a webform.
    So, when submitting the webform, the data for each item in the view will be submitted and saved as part of the webform submission.
    So far, we have used normal Views UI and normal Webform UI to set up all the pieces.
    What remains is to glue them together.

  10. Here is how that works.

    1. Configure the view to embed webform components.
    2. Go back to the view configuration.
    3. Change the "Formatter" option of our "Can order" field to use "a webform placeholder" as a display option.

      This display option is provided by webform_view, and marks where the new fields will be displayed.
      Your view preview should now look like this:

      You will not see the complete webform in the Views UI preview - it will just show the placeholders. HOWEVER, when that view is embedded in a webform (as configured earlier) those placeholders should now be displayed as form fields:

      And we have WON!
       
  11. Using that form should now produce meaningful submission reporting, emails and records in the webform data management tables.

File

help/index.html
View source
<html>
<head>
<title>Using Webform View</title>
</head>
<body>
  <h1>Using Webform View</h1>
  <p>Webform View is a module that allows you to embed a view as part of a
    webform. Form elements (checkboxes, quantity selectors) are inserted into
    each result row. Data in this view can then become part of the data
    submitted in the webform submission.</p>
  <p>The primary use-case this was built for is to enable a webform to be
    used as an order form where a user can select &nbsp;items displayed in the
    view, and request those resources or register interest in them in a way that
    the reciever of the submission can work with.</p>
  Due to a change in webform added in function webform_client_form_pages()
  http://drupalcode.org/project/webform.git/commitdiff/7bc797adb3ff27f8dc33545b41d79e902394b547
  the order of processing was reversed and webform 4.x is incompatible with
  webform_view. this cannot be cleanly fixed yet!
  <h2>Desired workflow:</h2>
  <ul>
    <li>A website administrator can publish information about resources
      (pamphlets, publications) or even products or topics as nodes on the
      website. This can be added to at any time.</li>
    <li>A view is created that lists these items. Full UI control of that
      layout uses normal view and template tools.</li>
    <li>A webform is created that displays that view, and includes either a
      checkbox or quantity field next to each item.</li>
    <li>When a user submits the form, their requests for each item are
      registered. Data on the submissions is managed using the Webform UI
      controls.</li>
  </ul>
  <h2>Execution:</h2>
  <p>Was hard. Webform doesn&#39;t natively support multiple/unlimited
    selections very well, and doesn&#39;t like the available options being
    dynamic very well. Although with recent developments in the
    webform+select+views options, a simple list of options can now be supported,
    anything more (item+quantity data) is still out of reach.</p>
  <p>Instead, an extension to webform (described above) was developed. To
    work, it has to do some brain-surgery on both the display and the results
    processing. This is described here. Although there are now several moving
    parts that have to be configured, this was engineered to produce the desired
    result in a highly re-usable and configurable way.</p>
  <h2>Usage (overview):</h2>
  <ul>
    <li>Create your resource content type.</li>
    <li>This content type should include an extra &quot;can order&quot;
      sort of field, which may be used to indicate where the per-row webform
      elements get inserted in displays. This is an additional field
      &quot;render mode&quot; called &quot;webform placeholder&quot; that will
      be available for some content fields Create it as a type:"Boolean"
      widget:"single on/off checkbox" field. Set its default value to TRUE. The
      flag and custom field is managed like this to provide maximum
      compatibility with normal UI-based display management and positioning
      options.</li>
    <li>Create a view that lists your resources. Configure its display. A
      'page' type display will be fine. This view should be able to use either
      node display or fields, as well as alternate view modes or display_suite
      based displays as needed.</li>
    <li>Create a webform that users can use to order resources. This should
      contain contact details etc as needed.</li>
    <li>Embed the view into the webform (new functionality). This is done
      using a new webform element &quot;Embedded view&quot;.</li>
    <li>Add additional webform fields as children of the view element (as
      if it were a fieldset). These fields will be propogated to create <em>new
        webform fields for each item in the view</em>.
    </li>
    <li>Go back and edit the view display to configure where these webform
      fields (the &quot;webform placeholder&quot;) should be placed in the
      display of the view. This gives you maximum layout control in how your
      final form will look.</li>
  </ul>
  <p>At this point, using the webform should merge all functions together.
    Viewing the webform should display the view, and include form fields in the
    layout location of the &quot;webform placeholder&quot;. Submissions to this
    webform should save the values for each item in the view. Generated emails
    should list each selection.</p>
  <h2>Usage (full setup instructions):</h2>
  <ol>
    <li>
      <h3>Download/enable required modules.</h3>
      <ul>
        <li><a href="http://drupal.org/project/webform">Webform</a></li>
        <li><a href="http://drupal.org/project/views">Views</a></li>
        <li>Field UI (core)</li>
        <li>Options, and List (core) - for the checkbox</li>
        <li><a href="http://drupal.org/node/1638192">Webform View</a></li>
      </ul>
      <p>Though not required, for this demo I&#39;ll also use</p>
      <ul>
        <li>file (core)</li>
        <li>image (core)</li>
      </ul>
    </li>
    <li>
      <h3>Create a &quot;resource&quot; content type.</h3> <img alt=""
      src="images/webform_view-resource_content_type.jpg" style="width: 500px;" />
      <h4>Add some basic fields, eg file and image.</h4>
      <h4>Add our marker field. &quot;Can order&quot; as a Boolean
        checkbox.</h4>
      <p>
        Under "Field Settings", set "On Value" to "Can Order" and "Off Value" to
        "Cannot Order". Then set the default value to "Can Order". <img alt=""
          src="images/webform_view-resource_content_type_fields.jpg"
          style="width: 500px;" />
      </p>
    </li>
    <li>
      <h2>Add some sample resources.</h2>
      <p>For variety, I&#39;ll show one that is available in hardcopy-only,
        one that is download-only, and one that is both. This is enabled by our
        &quot;can order&quot; checkbox field.</p> <img alt=""
      src="images/webform_view-sample_resources.jpg"
      style="width: 466px; height: 128px;" />
    </li>
    <li>
      <h2>Create a view that shows these items.</h2>
      <p>
        Just a view that filters on type:resource will do here. I&#39;ll use a
        table+fields view display for now, though I&#39;d recommend using
        teasers (or view mode) display most of the time.&nbsp;<br /> You
        don&#39;t need a &#39;page&#39; display, and some views options like
        paging will not work in this context, so leave them out.<br /> <br />
        <img alt="" src="images/webform_view-create_a_view.jpg"
          style="width: 500px;" /><br /> <img alt=""
          src="images/webform_view-view_definition.jpg" style="width: 500px;" /><br />
        With a small amount of adjustment, we get a view that produces this:<br />
        <img alt="" src="images/webform_view-view_display.jpg"
          style="width: 500px; height:" /><br /> Note our &quot;Can
        order&quot; field will be where the webform will do its thing soon.<br />
        This is the view we will embed in our webform.
      </p>
    </li>
    <li>
      <h2>Create the webform.</h2>
      <p>
        Add whatever normal fields you need in the webform for submission as
        usual.<br /> <img alt=""
          src="images/webform_view-standard_webform_fields.jpg"
          style="width: 500px;" />
      </p>
    </li>
    <li>
      <h2>Insert the view into the webform.</h2>
      <p>Here use the new webfrom view webform component &quot;Embedded
        view&quot;. I&#39;ll call it&nbsp;&quot;Order&quot;</p>
      <p>In the options for this field you should choose the
        &quot;View&quot; we just created. The &quot;Master&quot; display should
        be adequate.</p> <img alt="" src="images/webform_view-edit_component.jpg"
      style="width: 500px;" />
    </li>
    <li>
      <h2>Add webform fields as child elements to our embedded view.</h2>
      <p>
        These fields will need to record at least<br /> A: the item name,<br />
        B: the request submitted with this form.
      </p>
      <p>
        So add two fields. Importantly - they must be positioned as children of
        the view.<br /> The item name will already be apparent to users, and
        should not be displayed as a field, so make it hidden. (We will have to
        fill in data there ourselves, see below)<br /> <br /> I&#39;ll add a <strong>number</strong>
        &quot;Quantity&quot; field here too, though a <strong>checkbox</strong>
        would also work for some cases.<br /> <img alt=""
          src="images/webform_view-pseudo_fields.jpg" style="width: 500px;" />
      </p>
      <p>
        A required field (eg <em>quantity</em>) must also be chosen. This is set
        in the settings screen for the embedded view component. When results are
        saved, any row with a blank 'quantity' will not be saved, only rows with
        options actually entered in them will. <small>If we don't
          filter, then all the submission results list all rows each time, even
          if quantity was zero, and that looks messy on email notifications etc.</small>
        You can only choose which field is required after adding all child
        fields to the parent container. This means visiting the same settings
        page twice.
      </p>
    </li>
    <li>
      <h2>Get the item description into the webform fields.</h2>
      <p>Sorry, This is one extra fiddly step, used to ensure that the text
        in the submission&nbsp;results names the selected item appropriately.</p>
      <ol>
        <li>Edit the hidden&nbsp;&quot;Item requested&quot; field and <em>get
            it to use a token</em> that will be deduced from the view data it is
          being applied to.
        </li>
        <li>Set its &quot;default value&quot; to the string
          &quot;[node_title]&quot;.<br /> <img alt=""
          src="images/webform_view-identify_item_row.jpg" style="width: 360px;" />
        </li>
      </ol>
      <p>This was required as various view_modes and views rows may have
        different data available. For example you may want to add a
        &quot;[field_field_sku]&quot; or &quot;[nid]&quot; there as well to
        better identify the resource in question. User-created fields are
        available as [field_${field_id}] so the syntax often is
        [field_field_something]. This is from the way views internals names its
        values. [node_title] is only available in field-based-views, not teasers
        or view-modes! Arg? This is because, internally, the view doesn&#39;t
        make that data available at this point in rendering.</p>
      <blockquote>
        There is a work-around. This is not needed in field-based views, where
        the value of each rows field should be available as a token like this.<br />
        <em>If using teaser-based views</em>, Add an extra &quot;Sort
        criteria&quot; to your view definition. Sort on &quot;Content:
        Title&quot;. This is enough to make the above token have some data to
        work with, even if the sort cirteria is weighted lower than the
        &quot;Post date&quot; - effectively making it an ineffective sort.
      </blockquote>
    </li>
    <li>
      <h2>Conceptual re-cap</h2>
      <p>
        These fields, which we have defined using the webform UI, need to be
        displayed as part of a view, which is in turn being pulled in and
        displayed as part of a webform.<br /> So, when submitting the webform,
        the data for each item in the view will be submitted and saved as part
        of the webform submission.<br /> So far, we have used normal Views UI
        and normal Webform UI to set up all the pieces.<br /> What remains is
        to glue them together.
      </p>
    </li>
    <li>
      <h3>Here is how that works.</h3>
      <ol>
        <li>Configure the <em>view</em> to <em>embed webform
            components</em>.
        </li>
        <li>Go back to the view configuration.</li>
        <li>Change the &quot;Formatter&quot; option of our &quot;Can
          order&quot; field to use &quot;<strong>a webform placeholder</strong>&quot;
          as a display option.<br /> <img alt=""
          src="images/webform_view-render_order_flag_as_a_placeholder.jpg"
          style="width: 500px;" /><br /> This display option is provided by
          webform_view, and marks where the new fields will be displayed.<br />
          Your view preview should now look like this:<br /> <img alt=""
          src="images/webform_view-with_placeholder_fields.jpg"
          style="width: 500px;" /><br /> You will not see the complete webform
          in the Views UI preview - it will just show the placeholders. HOWEVER,
          when that view is embedded in a webform (as configured earlier) those
          placeholders should now be displayed as form fields:<br /> <img
          alt="" src="images/webform_view-final_form.jpg" style="width: 500px;" /><br />
          And we have WON!<br /> &nbsp;
        </li>
      </ol>
    </li>
    <li>Using that form should now produce meaningful submission reporting,
      emails and records in the webform data management tables.</li>
  </ol>

</body>
</html>