Using pre-filled Webforms

Tape currently doesn’t have Webforms built in however this shouldn’t put you off we are spoilt for choice with Forms providers from the old favourites like JotForms and Google Forms to newer options like Tally.so and Fillout.

Yesterday I said in this thread that if I couldn’t find a guide to using Webforms with Tape I would post one well there is one specifically about Webforms which is here it is a guide to using Google Forms written by Tim, there is also one about using Fillout forms sub-form feature here

However, I thought I would add one anyway. In this guide, I will use Fillout and show you how you can ‘Pre-fill’ aspects of the form as well.

Fillout account

Sign up for a free Fillout account you can do everything we want to do with a free account and lots more.

Build your form

This is a simple matter of adding field types from the left-hand pane and giving them names, you add pages at the bottom

:information_source: You can add display logic to fields and pages if required.

Once you have your form layout go into the settings:


In the settings, you want the URL Parameters option. This is where you add the fields you want to pre-fill I have added three you can add as many as you want however the ref one is key as that is going to hold our Tape Record ID which will enable us to update the relevant record when the form is submitted.:

Now if we go back into the edit screen and click on a field we can add a Pre-fill into the placeholder, this enables people to see the data you already have and update it if they want.
To do this select the field you want to pre-fill the placeholder and go across to the Placeholder option on the right a blue plus will appear:


Click the plus button then in the box that appears click on the link symbol on the left and the URL options will appear:


We are nearly finished with the form for now but before we move to Tape let’s publish the form. When you click publish you get another window with the link to the form:

we want the link, so click copy, Fillout is nice to us and gives us the link to the form with placeholders for our pre-fill fields:
https://forms.fillout.com/t/dsWTqutRgXus?ref=xxxxx&fName=Jason&sName=xxxxx
If you don’t have a clipboard manager paste that into a text file or somewhere you can get it back.

Create your URL in Tape

If you move into Tape you need two fields you may not have. These are a Number field for your ref and the other is a calculation field to create your URL. In my example they look like this:


To create your calculation field you will need to add a valid calculation this is where the URL you copied from Fillout comes into play.
I have split the URL into two so that you can see both the base URL and the ‘pre-fill’ part:

const b = 'https://forms.fillout.com/t/dsWTqutRgXus?';
const u = `ref=${ï»ż@refï»ż}&fName=${ï»ż@First Nameï»ż}&sName=${ï»ż@Surnameï»ż}`;
`${b}${u}`

For a unique reference, you could use a Unique ID field I tend to use the Record ID but you do have to add that to the field via automation so do what feels right to you.

Setting up the Webhook

We need to link the form to the Tape app, the first step is to create an automation in Tape with a Webhook trigger:

Once you have created the automation in Tape you can copy the URL:

Link the form to Tape

Time to head back into Fillout Select Integration from the top options and then Webhook:


Paste your copied Tape Webhook URL into the URL field:

Press the test button, and check that you get a Status:200 message before moving back to Tape

Complete the Tape Automation

Hit the refresh button in your Tape webhook and the box will fill with a whole raft of information, if it looks confusing don’t worry it is not as bad as it first looks:

@Webhook payload / formId = dsWTqutRgXus
@Webhook payload / formName = DemoForm
@Webhook payload / submission / submissionId = 
@Webhook payload / submission / submissionTime = 2024-08-07T09:04:29.335Z
@Webhook payload / submission / lastUpdatedAt = 2024-08-07T09:04:29.335Z
@Webhook payload / submission / questions / 0 / id = xy5UumKVeKn3g9fg5QuSQL
@Webhook payload / submission / questions / 0 / name = First Name
@Webhook payload / submission / questions / 0 / type = ShortAnswer
@Webhook payload / submission / questions / 0 / value = null
@Webhook payload / submission / questions / 1 / id = 5XjjEJZpMuyvhyJuEey8ag
@Webhook payload / submission / questions / 1 / name = Surname
@Webhook payload / submission / questions / 1 / type = ShortAnswer
@Webhook payload / submission / questions / 1 / value = null
@Webhook payload / submission / questions / 2 / id = a7BhvHNyuTawK9gKv9D2oq
@Webhook payload / submission / questions / 2 / name = Known As
@Webhook payload / submission / questions / 2 / type = ShortAnswer
@Webhook payload / submission / questions / 2 / value = null
@Webhook payload / submission / questions / 3 / id = vbcDMrmEhQTdK1H8xvzK4G
@Webhook payload / submission / questions / 3 / name = Your address
@Webhook payload / submission / questions / 3 / type = Address
@Webhook payload / submission / questions / 3 / value / address = 
@Webhook payload / submission / questions / 3 / value / city = 
@Webhook payload / submission / questions / 3 / value / state = 
@Webhook payload / submission / questions / 3 / value / zipCode = 
@Webhook payload / submission / questions / 3 / value / country = United Kingdom
@Webhook payload / submission / questions / 4 / id = atqSJaWzMZXa9oX6et42Ad
@Webhook payload / submission / questions / 4 / name = Email
@Webhook payload / submission / questions / 4 / type = EmailInput
@Webhook payload / submission / questions / 4 / value = null
@Webhook payload / submission / questions / 5 / id = 79iJxaNPkRHNSqdgNNZXCE
@Webhook payload / submission / questions / 5 / name = Phone number
@Webhook payload / submission / questions / 5 / type = PhoneNumber
@Webhook payload / submission / questions / 5 / value = null
@Webhook payload / submission / urlParameters / 0 / id = ref
@Webhook payload / submission / urlParameters / 0 / name = ref
@Webhook payload / submission / urlParameters / 0 / value = null
@Webhook payload / submission / urlParameters / 1 / id = fName
@Webhook payload / submission / urlParameters / 1 / name = fName
@Webhook payload / submission / urlParameters / 1 / value = Jason
@Webhook payload / submission / urlParameters / 2 / id = sName
@Webhook payload / submission / urlParameters / 2 / name = sName
@Webhook payload / submission / urlParameters / 2 / value = null

Tape splits the payload out into variables for you which can be handy however form providers quite often don’t send ‘Null’ fields (Fillout does) which then changes the numbers and everything breaks so to be safe we will pull the data out of the payload manually.

If you go to the top right of the payload window Variables will appear click on that and you get an option Paylaod which will give you the payload in JSON format. You want this so click the option:


now your payload window will look something like this:

{
  "formId": "dsWTqutRgXus",
  "formName": "DemoForm",
  "submission": {
    "submissionId": "",
    "submissionTime": "2024-08-07T09:04:29.335Z",
    "lastUpdatedAt": "2024-08-07T09:04:29.335Z",
    "questions": [
      {
        "id": "xy5UumKVeKn3g9fg5QuSQL",
        "name": "First Name",
        "type": "ShortAnswer",
        "value": null
      },
      {
        "id": "5XjjEJZpMuyvhyJuEey8ag",
        "name": "Surname",
        "type": "ShortAnswer",
        "value": null
      },
      {
        "id": "a7BhvHNyuTawK9gKv9D2oq",
        "name": "Known As",
        "type": "ShortAnswer",
        "value": null
      },
      {
        "id": "vbcDMrmEhQTdK1H8xvzK4G",
        "name": "Your address",
        "type": "Address",
        "value": {
          "address": "",
          "city": "",
          "state": "",
          "zipCode": "",
          "country": "United Kingdom"
        }
      },
      {
        "id": "atqSJaWzMZXa9oX6et42Ad",
        "name": "Email",
        "type": "EmailInput",
        "value": null
      },
      {
        "id": "79iJxaNPkRHNSqdgNNZXCE",
        "name": "Phone number",
        "type": "PhoneNumber",
        "value": null
      }
    ],
    "calculations": [],
    "urlParameters": [
      {
        "id": "ref",
        "name": "ref",
        "value": null
      },
      {
        "id": "fName",
        "name": "fName",
        "value": "Jason"
      },
      {
        "id": "sName",
        "name": "sName",
        "value": null
      }
    ],
    "quiz": {},
    "documents": [],
    "scheduling": [],
    "payments": []
  }
}

In this we can see each field that we have in our form and within each field there is an id we are going to use this to pull the relevant value for each field.

      {
        "id": "79iJxaNPkRHNSqdgNNZXCE",
        "name": "Phone number",
        "type": "PhoneNumber",
        "value": null
      }

JSONata is an incredibly useful library and we will use it to pull out the value for each field using the id from the payload as the designator. I have sent a test form submission and as you can see from the following image:

  1. The ID is xy5UumKVeKn3g9fg5QuSQL
  2. The value of the First Name field is Jason

You can also see that the field data is buried under the submission object and then questions in the payload.


So how do we get that information out of the payload?

jsonata(`submission.questions[id="xy5UumKVeKn3g9fg5QuSQL"].value`).evaluate(webhook_payload_parsed)`

Now we know how to get the data out of the payload we can use that to fill in our record fields.

  1. We need to get the ref from the payload so we can search for the relevant record the easiest way is to use a calculation block and build a variable to search for.
  2. We search for the record using the ref from the payload in our new variable.
  3. We update the record using the id of the field to find the value of the field.

If we create a test record we can see the prefill URL in the form link field waiting to be sent to the user.


click on the link and your form opens with the prefilled fields visible:

We can now correct the information in the form and when we press submit the data will be sent to Tape and the record will be updated, incredibly quickly.

Two things of note here the address update is so intelligent it just takes the information it is given and updates the record with that information, I often forget how clever it is and worry about my address mapping being wrong. The second is that the form link will also be updated with the new information so if it needs to be used again it will have the latest information pre-filled.

As I said at the start I have used Fillout for this, but it is a similar process with most other form providers. Hopefully the above makes sense as always feel free to get in touch if you have any questions.

3 Likes

Fantastic guide @Jason

1 Like

Thank you. Helpful and thorough as always!

1 Like

Hey Jason,
thank you for your phenomenal contribution to this community!

I’m trying to use your guide to create a simple system to let my clients update their personal data for invoicing. In this way I could insert a link on every transactional mail footer, to allow them change the Fillout prefilled form.

Unfortunately I’m facing some problem:

  1. Email and Phone fields are an array, so I’m getting [object Object] as a result, instead of the first value;

  2. I have no idea how to split the Address field into subfields;

  3. How should I format the date in order to be readable by Fillout?

  4. Using your formula I was getting spaces and symbols in the URL, causing errors in the browser tab, so I changed it (with chatGPT help) in this way:

const b = 'https://forms.fillout.com/t/somecode?';

const params = [
    { key: 'ragsoc', value: @Nome },
    { key: 'referente', value: @Referente },
    { key: 'email', value: @Email },
    { key: 'tel', value: @Telefono },
    { key: 'address', value: @Indirizzo },
    { key: 'codf', value: @CodFiscale },
    { key: 'piva', value: @PIVA },
    { key: 'pec', value: @PEC },
    { key: 'sdi', value: @CodSDI }
];

const queryString = params
    .filter(param => param.value) // Only keep params that have a value
    .map(param => `${param.key}=${encodeURIComponent(param.value)}`) // Encode and format as key=value
    .join('&'); // Join all key=value pairs with '&'

const url = `${b}${queryString}`; // Combine the base URL with the query string

How could I improve this automation?

Michele

Hi @Michele

The emails can be split out in a calculation field, this post here goes through a lot of the options however for a comma-separated list of just the addresses you can:

const ee = ï»ż@Emailï»ż.map(function (obj) {return obj.value}).join();

this will give you something like:
6546787@jmc.tools,56473452@jmc.tools which may be good enough for you if not then at least you have a string you can spaces to etc.

Now the address I don’t have a quick simple solution for someone else might but realistically with your form as it is I think you are going to need to send each part of the address separately. I am not sure you can do that in a calculation field however you can do it in an automation as each part of the address is given separately:
wf_contact_field_address_location_city
As I said someone else may know the combination of words and . to break it down in the calculation field but I haven’t as yet :slight_smile:

I hope that helps if not let me know. I am a bit short of time today but can look over the weekend if need be.

1 Like

Now that I have a bit more time, I’d like to expand on the address field. As we know, the @address field is a single-line string, so while we could split it into its parts using commas, this approach requires consistency in the address format. This might work in some countries but is unlikely to be reliable in the UK and certainly won’t work across different countries. Therefore, unless someone can suggest an easy method to split the address into its components, it will need to be done through automation. I’ve encountered an issue with this approach, which I’ll discuss in more detail later.

Let’s work with the following address field:

If you’re looking for a quick solution, you can build the address part of your URL directly using the @ variables in the field:


A more refined approach would be to build it within a script block and then add it to the field. This method allows us to encode the components and ensure they exist, which prevents null values from being added to our Fillout fields.

const street = !!contact_field_address_location_street_address ?encodeURIComponent(contact_field_address_location_street_address): "";
const city = !!contact_field_address_location_city ? encodeURIComponent(contact_field_address_location_city): "";
const state = !!contact_field_address_location_state ? encodeURIComponent(contact_field_address_location_state):"";
const postcode = !!contact_field_address_location_postal_code ? encodeURIComponent(contact_field_address_location_postal_code) : "";
const fAdd = !!contact_field_address_location_string ? encodeURIComponent(contact_field_address_location_string):"";

const address = `st=${street}&city=${city}&state=${state}&pc=${postcode}&add=${fAdd}`;
var_address = address;

Alternatively, you can use the method suggested by @Michele, which is likely even neater:

const params = [
    {key: 'st', value: contact_field_address_location_street_address},
    {key: 'city', value: contact_field_address_location_city},
    {key: 'state', value: contact_field_address_location_state},
    {key: 'pc', value: contact_field_address_location_postal_code},
    {key: 'add', value: contact_field_address_location_string},
];

const queryString = params
    .filter(param => param.value)
    .map(param => `${param.key}=${encodeURIComponent(param.value)}`)
    .join('&');

console.info(queryString);
var_address = queryString;

Both the second and third methods should produce the same result, while the first method might create a non-clickable URL due to spaces:


In our URL calculation field, we can now add the add-line field to complete our URL:

When we click on the link, we get a form with the address parts:
.

This is where I’ve encountered some issues, which might be specific to the UK, especially since I live in Wales:

  1. The City should be appearing as Liverpool.
  2. Generally, I feel the County (Merseyside, in our example) in the UK should be mapped to the State field. Additionally, many people in Wales (a country) might be offended if Wales were listed as a State!

Ideally, the form should look like this:

Finally, here’s how the form setup might appear:

4 Likes

Wow @Jason : this solution you proposed is just perfect.
Now my webforms are behaving as expected.

Now I just need to perform the second part of the automation, to update records when a user edit and save a Fillout form.

Thank you, as always!

4 Likes