PageSourceSearch

https://resource-center.generalassemb.ly/wp-content/mu-plugins/ga-utm-saver/ga-utm-saver.js

js generalassemb.ly collected 2026-09-24 07:32:33 UTC 5,161 bytes, 141 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function () {
2    const $ = jQuery;
3
4    if (typeof $ === 'undefined') {
5        console.error('jQuery is not available. Gravity Forms hooks depend on it.');
6        return;
7    }
8
9    const storageKey = 'gaTrackingParameters';
10    const performanceConsentGroupId = 'C0002';
11
12    const fieldMappings = {
13        'ga_source': 'input_1000',
14        'ga_medium': 'input_1001',
15        'ga_campaign': 'input_1002',
16        'ga_term': 'input_1003',
17        'ga_content': 'input_1004',
18        'ga_gclid': 'input_1005'
19    };
20
21    function saveTrackingParameters() {
22        try {
23            const paramMap = {
24                'utm_medium': 'ga_medium',
25                'utm_source': 'ga_source',
26                'utm_campaign': 'ga_campaign',
27                'utm_content': 'ga_content',
28                'utm_term': 'ga_term',
29                'gclid': 'ga_gclid'
30            };
31            const originalParamNames = Object.keys(paramMap);
32            const params = new URLSearchParams(window.location.search);
33            const currentParams = {};
34            let existingParams = {};
35
36            originalParamNames.forEach(function (originalName) {
37                const value = params.get(originalName);
38                if (value !== null && value !== '') {
39                    const newKeyName = paramMap[originalName];
40                    if (newKeyName) {
41                        currentParams[newKeyName] = value;
42                    }
43                }
44            });
45
46            const existingJson = localStorage.getItem(storageKey);
47            if (existingJson) {
48                try {
49                    const parsed = JSON.parse(existingJson);
50                    if (typeof parsed === 'object' && parsed !== null) {
51                        existingParams = parsed;
52                    }
53                } catch (e) {
54                    console.error('GTM Init Error: Could not parse existing ' + storageKey + '. Resetting.', e);
55                    existingParams = {};
56                }
57            }
58
59            const finalParams = Object.assign({}, existingParams, currentParams);
60
61            localStorage.setItem(storageKey, JSON.stringify(finalParams));
62
63        } catch (e) {
64            console.error('GTM Error in mapped ' + storageKey + ' script:', e);
65        }
66    }
67
68    function getTrackingData() {
69        let trackingData = {};
70        try {
71            const trackingJsonString = localStorage.getItem(storageKey);
72            if (trackingJsonString) {
73                const parsedData = JSON.parse(trackingJsonString);
74                if (typeof parsedData === 'object' && parsedData !== null) {
75                    trackingData = parsedData;
76                }
77            }
78        } catch (error) {
79            console.error(`Error reading or parsing localStorage item "${storageKey}":`, error);
80        }
81        return trackingData;
82    }
83
84    function populateHiddenFields(formElement, trackingData) {
85        const $form = $(formElement);
86        Object.entries(fieldMappings).forEach(([dataKey, inputName]) => {
87            const $field = $form.find(`input.gform_hidden[name="${inputName}"]`);
88            if ($field.length) {
89                const valueToSet = trackingData[dataKey] || '';
90                $field.val(valueToSet);
91            }
92        });
93    }
94
95    function executeTrackingAndPopulation() {
96        if (typeof OptanonActiveGroups !== 'undefined' && OptanonActiveGroups.includes(performanceConsentGroupId)) {
97            saveTrackingParameters();
98
99            const trackingData = getTrackingData();
100            $('form').each(function() {
101                populateHiddenFields(this, trackingData);
102            });
103            return true;
104        }
105        return false;
106    }
107
108    $(document).on('gform_post_render', function (event, formId) {
109        const $form = $(`#gform_wrapper_${formId}`).find('form');
110        if ($form.length) {
111            const trackingData = getTrackingData();
112            populateHiddenFields($form, trackingData);
113        }
114    });
115
116    if (typeof gform !== 'undefined' && gform.utils && typeof gform.utils.addAsyncFilter === 'function') {
117        gform.utils.addAsyncFilter('gform/submission/pre_submission', async function (submissionData) {
118            const formElement = submissionData.form;
119            if (formElement && formElement.tagName === 'FORM') {
120                const trackingValues = getTrackingData();
121                populateHiddenFields(formElement, trackingValues);
122            }
123            return submissionData;
124        });
125    }
126
127    window.dataLayer = window.dataLayer || [];
128    const originalDataLayerPush = window.dataLayer.push;
129    window.dataLayer.push = function() {
130        const result = originalDataLayerPush.apply(window.dataLayer, arguments);
131        for (let i = 0; i < arguments.length; i++) {
132            const eventArg = arguments[i];
133            if (eventArg && eventArg.event === 'OneTrustGroupsUpdated') {
134                setTimeout(executeTrackingAndPopulation, 100);
135            }
136        }
137        return result;
138    };
139
140    setTimeout(executeTrackingAndPopulation, 750);
141});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.