Jump to content

Programmatically Updating Hidden Form Field Values After the Squarespace Form Changes

Go to solution Solved by sorca_marian,

Recommended Posts

Hello everyone,

I am attempting to programmatically set two hidden form field values (i.e. SQF_RID and SQF_SID) based on a tracking ID that I pick up from a variety of sources, including from cookies which means I cannot use the Squarespace querystring parameters to set the form fields.

As many of you know, you can no longer use the following standard javascript that many of us had long utilized before the Squarespace Form changes a few months back.

function setFormField(name, value) {
    // Grabbing the form field by its name
    var field = document.getElementsByName(name)[0];

    // Checking if the field exists and is a text or hidden field
    if (field && (field.type === 'text' || field.type === 'hidden')) {
        // Setting the value of the field
        field.value = value;
    }
}

 

@sorca_marian has created an excellent YouTube video and associated GitHub code samples that are generally applicable to this topic. In it he references a relevant StackOverflow thread that itself references a related blog article. I highly recommend following Marian's YouTube channel if you are interested in Squarespace javascript coding solutions.

 

Unfortunately, I can't seem to get his code samples to work with my site. I believe the values are initially set correctly but must be overwritten by the Squarespace React implementation at some point as the original default form values are what show up when the form is submitted.

Here are the three functions that I am currently testing that have not worked thus far:

function changeHiddenFieldValueVersion1(fieldId, value) {
        var input = document.getElementById(fieldId);
        if (!input) return; // Exit if the element is not found

        var nativeInputValueSetter = Object.getOwnPropertyDescriptor(
            window.HTMLInputElement.prototype,
            "value"
        ).set;
        nativeInputValueSetter.call(input, value);

        var inputEvent = new Event("input", { bubbles: true });
        input.dispatchEvent(inputEvent);
    }


function changeHiddenFieldValueVersion2(fieldId, value) {
        var input = document.getElementById(fieldId);
        if (!input) return; // Exit if the element is not found

        Object.defineProperty(input, "value", {
            value: value, // Programmatically changed value
            writable: true
        });

        var inputEvent = new Event('input', { bubbles: true });
        input.dispatchEvent(inputEvent);
    }
  
function changeHiddenFieldValueVersion3(fieldId, value) {
        var input = document.getElementById(fieldId);
        if (!input) return; // Exit if the element is not found

        var nativeInputValueSetter = Object.getOwnPropertyDescriptor(
            window.HTMLInputElement.prototype,
            "value"
        ).set;
        nativeInputValueSetter.call(input, value);

        var inputEvent = new Event("input", { bubbles: true });
        input.dispatchEvent(inputEvent);

        var changeEvent = new Event('change', { bubbles: true });
        input.dispatchEvent(changeEvent);
    }

 

Here are the function calls that are being called onInit that I'm using (using hardcoded values for test purposes). 

(function() {
 
  // Establish a function that does stuff.
  var onInit = function() {
    // TODO: Remove cookie page code
    var page = window.location.pathname;
    
    // Make sure page is a promotable page, which is only the homepage for now
    if (page == '/home' || page == '/')
    {
      
        changeHiddenFieldValueVersion3('hidden-64ca8128-d5af-46d9-9804-6e2c8b3f79a4', 'TESTRIDVAL'); 
    }
    
    
    
  };

  // Initialize the fn on site load.
  onInit();

  
  // Reinit. the fn on each new AJAX-loaded page.
  window.addEventListener("mercury:load", onInit);
})();

 

Does anyone have any advice on why this code shouldn't be working? I would greatly appreciate any working code samples that address my particular issue. Happy to like/follow/recommend the online social media accounts of helpful responders.

Additionally, Squarespace technical support should really be providing some contribution to these threads in service of their paying customers. Hope this changes for the better in the future.

Edited by NovaSites
Link to comment

Hello @NovaSites,

I'm glad you like my content. Thank you for recommending it.

Have you tried to add normal form fields to the form, hide them with CSS, and fill those fields with JavaScript?

I have a code to hide the fields publicly but show them in the control panel: https://github.com/sorcamarian/squarespace-tricks/blob/main/Style/only-visible-in-control-panel.css

And here is the video 

 

Edited by sorca_marian
Link to comment

Thanks so much @sorca_marian. I tried your advice and here's what I'm experiencing thus far:

I've hidden the divs that contain the form text fields using simple CSS (e.g. display: none).

I can get your code samples to work from the console in Chrome Developer Tools, similarly to how you instructed in your videos. In the console, I can set any text field value and I can programmatically hide the surround divs as well (although I opted for CSS here for simplicity). Hidden input types do not seem to be settable in the same way (although it's possible I am doing something incorrectly).

When I try to replicate the code that works in the console in the Code Injection Header section of my html file, it doesn't work for some reason.

I suspect it has to do with the execution timing (onInit in my current code) of when I am attempting to set the text field values in my actual code versus how/when I am setting them through the console.

Here is the code from my site that is not setting/persisting the text field values:

(function() {
 
  // Establish a function that does stuff.
  var onInit = function() {
    // TODO: Remove cookie page code
    var page = window.location.pathname;
    
    // Make sure page is a promotable page, which is only the homepage for now
    if (page == '/home' || page == '/')
    {

      // Hide the div element
      divElement2.style.display = 'none';
      
        changeHiddenFieldValueVersion2('id="text-c8497229-d39f-40d4-8747-c10b953ed4c1-field"', 'RIDVAL');
        changeHiddenFieldValueVersion2('text-13c3c81c-09fe-4c25-9ef0-89681a9f4bf1-field', 'SIDVAL');
      
      
    }
    
    
    
  };
    
  
    
  

  // Initialize the fn on site load.
  onInit();

  
    
  // Reinit. the fn on each new AJAX-loaded page.
  window.addEventListener("mercury:load", onInit);
})();

 

Does anyone know why my form changes would work in the console but not in the code above? Is there another event handler I should be embedding the calls within? (More generally, can anyone explain the execution timing mechanisms of how Squarespace's React implementation handles the form creation, user entry and submissions processes?)

Thanks in advance! I will continue to research this problem and post any findings and solutions in this thread for the broader community.

Link to comment

The code might run before the react form is implemented.

Try using the below code.
It checks when the react form was added on the page.
 

document.addEventListener("DOMContentLoaded", function(){

    var targetNode = document.querySelector('.form-block');

    // Options for the observer (which mutations to observe)
    var config = { childList: true, subtree: true };

    // Callback function to execute when mutations are observed
    var callback = (mutationList, observer) => {    
        mutationList.forEach(mutation => {
            // debugger;
            if( mutation.addedNodes.length ) {
                mutation.addedNodes.forEach(addedNode => {
                    if(addedNode.classList.contains("react-form-contents")){
                        console.warn("Found react form mutation");
                        observer.disconnect();
                        startMyChangesOnTheForm();
                    }
                });
            }
        });
        
    };

    // Create an observer instance linked to the callback function
    const observer = new MutationObserver(callback);
    // Start observing the target node for configured mutations
    observer.observe(targetNode, config);



    function startMyChangesOnTheForm() {
        // Do the programmatical canges on the form
    }

});

1. targetNode is the container or the form. If you have multiple forms, make sure to target the ".form-block" of that individual form.
2. Inside the function startMyChangesOnTheForm(), put the code that makes changes on the values of the form

 

Edited by sorca_marian
Link to comment

Thank you so much @sorca_marian!!! Your code samples worked perfectly.

I had a couple of experienced javascript developers take a look at this problem with no luck. You clearly have an expert-level understanding of both front-end web development technologies and the nuances of the Squarespace environment. Squarespace should frankly hire you as a developer advocate for these forums.

I might have some work for you down the road and would love to connect offline. What's the best way for me (and others in the community) to contact you?

Lastly, the contributions of developers like Marian to these forums is incredibly valuable. I learned a ton from his posts and videos and I'd strongly encourage anyone interested in programmatically customizing their Squarespace sites to follow his YouTube channel.

Link to comment

I am happy that the solution worked.

Thank you very much for the kind words.

You can message me here on my profile or contact me through www.abzglobal.net or marian@abzglobal.net

Edited by sorca_marian
Link to comment
  • Solution

I created a video and explain the code just in case somebody is interested
 

 

Link to comment
  • 7 months later...

Hey @sorca_marian, I've watched your video because I'm running into a similar issue. In short, I'm able to automatically populate a form field (hidden via hidden field or via CSS) with Google Tag Manager but the value is not passing when sending. 

My goal is to pass the GCLID value when someone is sending a form. I'm able to store the full URL with parameters in a 1st party cookie. Next, I create a variable so that I have the GCLID isolated. I'm also able to fill the hidden field (SQF_GCLID) with that GCLID. But when I hit send, the value is not showing in Google Sheets. Instead of a hidden field, I've also tried to add a regular field and hide it with css (display : none) but nothing happens either. 

Based on the solution you've provided here, what might go wrong here? 

The page that I'm trying to setup like this is: https://shorturl.at/qh1Ff The URL already has a gclid in it so you should see the same value ('1337') in this field as seen in the screenshot: 

gclid.thumb.png.73b4fa94a196c639a325ff11d6ebb269.png 

Link to comment

Hey @Cedric_D,

First I thought that the issue was when trying to modify the value of an SQS hidden field which will not work.

Can you use the Developer Tools and pause the JavaScript execution before the form is submitted to check if the hidden field with CSS has the desired value?
This approach should work.
In case during the JavaScript execution pause the value of the field is the desired one but is not being sent to Google Sheet try to create a new Squarespace form and connect again the Google Sheet.
Also, check in the Console of Developer Tools if you have any JavaScript errors.

Let me know if this works

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

×
×
  • Create New...

Squarespace Webinars

Free online sessions where you’ll learn the basics and refine your Squarespace skills.

Hire a Designer

Stand out online with the help of an experienced designer or developer.