August 21, 2023

Connect an Elementor Form to Google Sheet

Play Video

Connecting your Elementor form to Google Sheet can be a game-changer for many website owners. It streamlines the process of collecting and storing data without the need for additional plugins or tools. In this post, we’ll explore two methods to achieve this connection: using a code snippet and the ‘Make’ no-code solution.


Method 1: Connecting Elementor Form to Google Sheets Using a Code Snippet

This method involves using a specific code snippet that acts as a bridge between your Elementor form and Google Sheets. It’s a straightforward approach for those who are comfortable working with code.

1. Copy the code

/**
 * Google app-script to utilise Elementor Pro From webhook.
 *
 * In order to enable this script, follow these steps:
 * 
 * From your Google Sheet, from the "Exstensions" menu select "App Script"…
 * Paste the script from this gist into the script code editor and hit Save.
 * From the "Deploy" menu, select Deploy as web app…
 * Choose to execute the app as yourself, and allow Anyone, even anonymous to execute the script. (Note: depending on your Google Apps instance, this option may not be available. You will need to contact your Google Apps administrator, or else use a Gmail account.)
 * Now click Deploy. You may be asked to review permissions now.
 * The URL that you get will be the webhook that you can use in your elementor form, You can test this webhook in your browser first by pasting it.
 * It will say "Yepp this is the webhook URL, request received".
 * Last all you have to do is set up and Elementor Pro Form with a form name and Webhook action pointing to the URL from above.
 *
 * Update: 09/06/2022
 *  - Name the sheet: you can now add a field (could be hidden) to your form labeled "e_gs_SheetName" and set the defualt value to the name of the sheet you want to use.
 *  - Set the Order: you can now add a form field (hidden) labeled "e_gs_order" and set its defualt value to the names of the columns you want to seperated by comma in the order you want, any other colum not in that list will be added after.
 *  - Exclude Columns: you can now add a field (could be hidden) labeled "e_gs_exclude" and set its value to the names of the columns you want to exclude seperated by comma.
 */

// Change to true to enable email notifications
let emailNotification = false;
let emailAddress = "Change_to_your_Email";



// DO NOT EDIT THESE NEXT PARAMS
let isNewSheet = false;
let postedData = [];
const EXCLUDE_PROPERTY = 'e_gs_exclude';
const ORDER_PROPERTY = 'e_gs_order';
const SHEET_NAME_PROPERTY = 'e_gs_SheetName';

/**
 * this is a function that fires when the webapp receives a GET request
 * Not used but required.
 */
function doGet( e ) {
    return HtmlService.createHtmlOutput( "Yepp this is the webhook URL, request received" );
}

// Webhook Receiver - triggered with form webhook to published App URL.
function doPost( e ) {
    let params = JSON.stringify( e.parameter );
    params = JSON.parse( params );
  postedData = params;
    insertToSheet( params );

    // HTTP Response
    return HtmlService.createHtmlOutput( "post request received" );
}

/**
 * flattenObject
 * Flattens a nested object for easier use with a spreadsheet
 * @param ob
 * @returns {{}}
 */
const flattenObject = ( ob ) => {
    let toReturn = {};
    for ( let i in ob ) {
        if ( ! ob.hasOwnProperty( i ) ) {
            continue;
        }

        if ( ( typeof ob[ i ] ) !== 'object' ) {
            toReturn[ i ] = ob[ i ];
            continue;
        }

        let flatObject = flattenObject( ob[ i ] );
        for ( let x in flatObject ) {
            if ( ! flatObject.hasOwnProperty( x ) ) {
                continue;
            }
            toReturn[ i + '.' + x ] = flatObject[ x ];
        }
    }
    return toReturn;
}

/**
 * getHeaders
 * normalize headers
 * @param formSheet
 * @param keys
 * @returns {*[]}
 */
const getHeaders = ( formSheet, keys ) => {
    let headers = [];

    // retrieve existing headers
    if ( ! isNewSheet ) {
        headers = formSheet.getRange( 1, 1, 1, formSheet.getLastColumn() ).getValues()[0];
    }
  const newHeaders = keys.filter( h => ! headers.includes( h ) );
  headers = [ ...headers, ...newHeaders ];
  // maybe set order
    headers = getColumnsOrder( headers );
  // maybe exclude headers
    headers = excludeColumns( headers );
  // filter out control columns
  headers = headers.filter( header => ! [ EXCLUDE_PROPERTY, ORDER_PROPERTY, SHEET_NAME_PROPERTY ].includes( header ) );
  return headers;
};

/**
 * getValues
 * normalize values
 * @param headers
 * @param flat
 * @returns {*[]}
 */
const getValues = ( headers, flat ) => {
    const values = [];
    // push values based on headers
    headers.forEach( ( h ) => values.push( flat[ h ] ) );
    return values;
}

/**
 * insertRowData
 * inserts values to a given sheet at a given row
 * @param sheet
 * @param row
 * @param values
 * @param bold
 */
const insertRowData = ( sheet, row, values, bold = false ) => {
    const currentRow = sheet.getRange( row, 1, 1, values.length );
    currentRow.setValues( [ values ] )
        .setFontWeight( bold ? "bold" : "normal" )
        .setHorizontalAlignment( "center" );
}

/**
 * setHeaders
 * Insert headers
 * @param sheet
 * @param values
 */
const setHeaders = ( sheet, values ) => insertRowData( sheet, 1, values, true );

/**
 * setValues
 * Insert Data into Sheet
 * @param sheet
 * @param values
 */
const setValues = ( sheet, values ) => {
    const lastRow = Math.max( sheet.getLastRow(), 1 );
    sheet.insertRowAfter( lastRow );
    insertRowData( sheet, lastRow + 1, values );
}

/**
 * getFormSheet
 * Find or create sheet for form
 * @param sheetName
 * @returns Sheet
 */
const getFormSheet = ( sheetName ) => {
    const activeSheet = SpreadsheetApp.getActiveSpreadsheet();

    // create sheet if needed
    if ( activeSheet.getSheetByName( sheetName ) == null ) {
        const formSheet = activeSheet.insertSheet();
        formSheet.setName( sheetName );
        isNewSheet = true;
    }
    return activeSheet.getSheetByName( sheetName );
}

/**
 * insertToSheet
 * magic function where it all happens
 * @param data
 */
const insertToSheet = ( data ) => {
    const flat = flattenObject( data ),
        keys = Object.keys( flat ),
        formSheet = getFormSheet( getSheetName( data ) ),
        headers = getHeaders( formSheet, keys ),
        values = getValues( headers, flat );

    setHeaders( formSheet, headers );
    setValues( formSheet, values );

    if ( emailNotification ) {
        sendNotification( data, getSheetURL() );
    }
}

/**
 * getSheetName
 * get sheet name based on form field named "e_gs_SheetName" if exists or used form name
 * @param data
 * @returns string
 */
const getSheetName = ( data ) => data[SHEET_NAME_PROPERTY] || data["form_name"];

/**
 * getSheetURL
 * get sheet url as string
 * @returns string
 */
const getSheetURL = () => SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getUrl();

/**
 * stringToArray
 * split and trim comma seperated string to array
 * @param str
 * @returns {*}
 */
const stringToArray = ( str ) => str.split( "," ).map( el => el.trim() );

/**
 * getColumnsOrder
 * used to set the columns order, set this by adding a form field (hidden) named "e_gs_order"
 * and set its value to the names of the columns you want to seperated by comma in the order you want,
 * any other colum not in that field will be added after
 * @param data
 * @param headers
 * @returns {*}
 */
const getColumnsOrder = ( headers ) => {
    if ( ! postedData[ORDER_PROPERTY] ) {
        return headers;
    }
    let sortingArr = stringToArray( postedData[ORDER_PROPERTY] );
  // filter out non existing headers
  sortingArr = sortingArr.filter( h => headers.includes( h ) );
  // filterout sorted headers
  headers = headers.filter( h => ! sortingArr.includes( h ) );

  return [ ...sortingArr, ...headers ];
}
/**
 * excludeColumns
 * used to exclude columns, set this by adding a form field (hidden) named "e_gs_exclude"
 * and set its value to the names of the columns you want to exclude seperated by comma
 * @param data
 * @param headers
 * @returns {*}
 */
const excludeColumns = ( headers ) => {
    if ( ! postedData[EXCLUDE_PROPERTY] ) {
        return headers;
    }
    const columnsToExclude = stringToArray( postedData[EXCLUDE_PROPERTY] );
    return headers.filter( header => ! columnsToExclude.includes( header ) );
}

/**
 * sendNotification
 * send email notification if enabled
 * @param data
 * @param url
 */
const sendNotification = ( data, url ) => {
    MailApp.sendEmail(
        emailAddress,
        "A new Elementor Pro Forms submission has been inserted to your sheet", // mail subject
        `A new submission has been received via ${data['form_name']} form and inserted into your Google sheet at: ${url}`, //mail body
        {
            name: 'Automatic Emailer Script'
        }
    );
};

Source: Github

2. Google App Script Setup

  1. Open Google App Script in a new browser tab.
  2. Create a new project and paste the copied code into the script editor.

3. Deployment

  1. In Google App Script, go to the ‘Deploy’ option.
  2. Choose ‘Web App’ and deploy the project.
  3. Upon deployment, you’ll receive a unique webhook URL. Make sure to copy this URL.

4. Integrate with Elementor

  1. Go to your website’s Elementor form settings.
  2. Look for the webhook option and paste the copied URL from the previous step.

5. Test the Integration

  1. Fill out your Elementor form on the website and submit it.
  2. Check your Google Sheets to see if the submitted data appears correctly.

Method 2: Using ‘Make’ to Connect Elementor Form to Google Sheets

For those who prefer a no-code solution, ‘Make’ offers a seamless way to connect your Elementor form to Google Sheets. It’s user-friendly and doesn’t require any coding knowledge.

1. Setting Up ‘Make’

  1. First, create an account on ‘Make‘.
  2. Once logged in, choose the option to create a new scenario.

2. Webhook Creation

  1. In ‘Make’, add a custom webhook to your scenario.
  2. This webhook will generate a unique URL. Copy this URL for later use.

3. Elementor Integration

  1. Head back to your Elementor form settings on your website.
  2. Replace any existing webhook URL with the one copied from ‘Make’.

4. Data Transfer Setup

  1. In ‘Make’, set up the data transfer process.
  2. Direct the platform to send the received data from the Elementor form to your desired Google Sheet.

5. Testing

  1. As before, fill out the Elementor form on your website and submit.
  2. Check the specified Google Sheet to ensure the data has been transferred correctly.

Final Thoughts:

Connecting your Elementor form to Google Sheet can significantly streamline your data collection and storage process. Whether you’re comfortable with code or prefer a no-code solution, there’s a method to suit your needs. By following the steps outlined above, you’ll have a seamless integration in no time. Happy data collecting!

Required Resources

Elementor Logo
Free Options
Credit to Edan Ben-Atar
Edan Benatar is a digital entrepreneur specializing in WordPress, Shopify, SEO, and marketing. Through his agency, he helps businesses enhance their online presence. On his YouTube channel, Edan shares insights into scaling his agency and products.
Visit
Connect an Elementor Form to Google Sheet
Welcome back!
Enter your Helwp credentials to sign in.

No Account yet? Sign Up

My Account
Menu
Give Feedback
Describe your feedback *
Rate Helwp
Share
Facebook
Twitter
LinkedIn
Reddit
Email
WhatsApp
Telegram
Pocket
Report
Problem *
Describe the problem
Want us to reply?
Your E-Mail
Affiliate Disclosure

At Helwp, we’re committed to transparency and honesty. Therefore, we want to inform you that some of the links on our website are affiliate links. This means that, at no additional cost to you, we may earn a small commission if you click through and make a purchase.

We only promote products or services that we genuinely believe in. These affiliate commissions help us to maintain the website and continue to provide you with free, high-quality WordPress content.

If you are interested in how you can support us even further, check out our support page.