AMP by Example
Playground

Introduction
Introduction

Components
Components

Advanced
Advanced

Samples & Templates
Samples & Templates

AMP Ads
AMP Ads

Edit in Playground View Demo

Poll

Edit on Github

Experimental Mode

This example uses the following experimental feature: [amp-form-var-sub]
Enable them below and learn more here.

Enable Dev Channel

Introduction

This is a sample template for a poll in AMP. After selecting one of the answers, you will see the percentage of chosen answers.

Show Hidden Code Hide Code
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>

Setup

Import the additional AMP components. This sample uses a amp-form and mustache templates.

<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
Show Hidden Code Hide Code
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
<link rel="canonical" href="https://ampbyexample.com/samples_templates/poll/">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>

<style amp-custom>
  #poll1 li {
            position: relative;
            padding: 1em 0;
            list-style: none;
            margin: 0;
            display: block;
            height: 20px;
        }
        #poll1.amp-form-submit-success fieldset {
            display: none;
        }
        .percentage-container {
            font-size: 0;
            display: flex;
        }
        .percentage-container-fixed {
          height: 100%;
          position: absolute;
          font-size: 0;
          right: 80px;
          left: 160px;
        }
        .one-pc-fixed {
           width: 1%;
           display: inline-block;
           background: #eb407a;
           height: 100%;
       }
        #header1 {
          padding-left: 32px;
        }
        form.amp-form-submit-success [submit-success] {
        flex: 0 0 100%;
      }
      .fixed-size-cell {
        width: 90px;
        display: inline-block;
        max-width: 90px;
      }
      .votes-cell {
        float: right;
        width: 60px;
      }
      .table-row {
        position: relative;
        margin-top: 16px;
      }
      .table {
        margin: 16px;
      }

</style>
</head>
<body>

  <h4 id="header1">Flightless bird poll</h4>

Flightless bird poll

Poll

We use amp-form to implement a poll. To avoid multiple votes by the same user, we need to identify which users have already voted. We use a cookie called POLL_USER_ID to identify the user. Given that in Safari the default behavior is to block third-party cookies from sites that have not been previously visited, this approach may not work if the page is visited via the AMP Cache. In this case we fallback to checking for duplicate entries via the CLIENT_ID.

The CLIENT_ID is a unique identifier for the user when accessing a specific origin, for example the original page or the cached version of it. This means that the same user will generate two different values when accessing different origins. That's why we use a custom cookie to track cross origin access to the poll page.

The CLIENT_ID variable can be passed via an amp-form by declaring a hidden input value with default-value="CLIENT_ID(POLL_USER_ID). In our implementation, the backend sets POLL_USER_ID to the value of CLIENT_ID, but the value of this cookie is not relevant and you could re-use your own session id.

Read more about variable substitution. Currently, HTML tables are not supported in form responses, so we'll use CSS to layout the result data.

In order to submit the form as soon as the user picks an option, we will add an on attribute to each <input>, that will submit the poll on change.

  <form method="post" action-xhr="/samples_templates/poll/submit" target="_blank" id="poll1" custom-validation-reporting="as-you-go">
    <input name="clientId" type="hidden" value="CLIENT_ID(POLL_USER_ID)" data-amp-replace="CLIENT_ID">
    <fieldset>
      <p>What is your favorite flightless bird?</p>
      <p>Choose your favourite flightless bird and you will discover what other users have chosen. If you have already voted, your answer will be overwritten.</p>

      <ul>
        
        <li>
          <label>
            <input name="answer" value="0" type="radio" on="change:poll1.submit"> Penguins
          </label>
        </li>
        
        <li>
          <label>
            <input name="answer" value="1" type="radio" on="change:poll1.submit"> Ostriches
          </label>
        </li>
        
        <li>
          <label>
            <input name="answer" value="2" type="radio" on="change:poll1.submit"> Kiwis
          </label>
        </li>
        
        <li>
          <label>
            <input name="answer" value="3" type="radio" on="change:poll1.submit"> Wekas
          </label>
        </li>
        
      </ul>
    </fieldset>
    <div submit-success>
      <template type="amp-mustache">
        <p>{{Message}}</p>
        <p>Here are the results!</p>
        <div class="table">
          <span class="fixed-sixe-cell">Answer</span>
          <span class="fixed-size-cell">&nbsp;</span>
          <span>&nbsp;</span>
          <span class="fixed-size-cell votes-cell">Votes</span>
          {{#PollEntryResults}}
          <div class="table-row">
            <span class="fixed-size-cell">
              {{Answer}}
            </span>
            <span class="fixed-size-cell">
              {{Percentage.length}}%
            </span>

            <span class="percentage-container-fixed">
              {{#Percentage}}
              <span class="one-pc-fixed"></span>{{/Percentage}}
            </span>

            <span class="fixed-size-cell votes-cell">
              {{Votes}}
            </span>
          </div>
          {{/PollEntryResults}}

        </div>
      </template>
    </div>
    <div submit-error>
      <template type="amp-mustache">
        Error! Looks like something went wrong with your vote, please try to submit it again. {{error}}
      </template>
    </div>
  </form>

What is your favorite flightless bird?

Choose your favourite flightless bird and you will discover what other users have chosen. If you have already voted, your answer will be overwritten.

</body>
</html>