PageSourceSearch

https://www.robinaireheating.com/wp-content/plugins/gravityforms-s…/js/gf-sbjs-populate-fields.js?ver=1.0

js robinaireheating.com collected 2026-10-09 03:40:52 UTC 10,897 bytes, 279 lines download raw bytes

1/**
2 * Populate Gravity Forms hidden fields with SBJS attribution data
3 * This allows the data to be passed through to Zoho and other integrations
4 */
5
6(function($) {
7    'use strict';
8
9    /**
10     * Helper function to get a cookie value by name
11     */
12    function getCookie(name) {
13        var value = "; " + document.cookie;
14        var parts = value.split("; " + name + "=");
15        if (parts.length === 2) {
16            return decodeURIComponent(parts.pop().split(";").shift());
17        }
18        return null;
19    }
20
21    /**
22     * Parse SBJS cookie value (format: key1=value1|key2=value2|...)
23     */
24    function parseSBJSCookie(cookieValue) {
25        if (!cookieValue) return {};
26        
27        var data = {};
28        var pairs = cookieValue.split('|');
29        
30        for (var i = 0; i < pairs.length; i++) {
31            var pair = pairs[i].trim();
32            if (pair) {
33                var parts = pair.split('=');
34                if (parts.length === 2) {
35                    var key = parts[0].trim();
36                    var value = parts[1].trim();
37                    data[key] = value;
38                }
39            }
40        }
41        
42        return data;
43    }
44
45    /**
46     * Get SBJS attribution values from cookies
47     */
48    function getSBJSData() {
49        var sbjsCurrent = getCookie('sbjs_current');
50        var data = {};
51        
52        if (sbjsCurrent) {
53            var parsed = parseSBJSCookie(sbjsCurrent);
54            // Map SBJS keys to friendly names
55            data.source = parsed.src || '(none)';
56            data.medium = parsed.mdm || '(none)';
57            data.campaign = parsed.cmp || '(none)';
58        } else {
59            data.source = '(none)';
60            data.medium = '(none)';
61            data.campaign = '(none)';
62        }
63        
64        return data;
65    }
66
67    /**
68     * Find hidden field by label (case-insensitive, partial match)
69     */
70    function findFieldByLabel($form, labelText) {
71        var searchText = labelText.toLowerCase();
72        
73        // Try to find by label text
74        var $labels = $form.find('label');
75        var $field = null;
76        
77        $labels.each(function() {
78            var labelTextLower = $(this).text().toLowerCase().trim();
79            if (labelTextLower === searchText || labelTextLower.indexOf(searchText) !== -1) {
80                var $label = $(this);
81                var fieldId = $label.attr('for');
82                
83                if (fieldId) {
84                    $field = $form.find('#' + fieldId);
85                } else {
86                    // If no 'for' attribute, try to find input within the label
87                    $field = $label.find('input[type="hidden"]');
88                }
89                
90                // If still not found, try to find the next sibling input
91                if (!$field || $field.length === 0) {
92                    $field = $label.next('input[type="hidden"]');
93                }
94                
95                if ($field && $field.length > 0) {
96                    return false; // Break the loop
97                }
98            }
99        });
100        
101        // Fallback: try to find by field admin label or CSS class
102        if (!$field || $field.length === 0) {
103            $field = $form.find('input[type="hidden"][data-label*="' + labelText + '"]');
104        }
105        
106        // Another fallback: try to find by admin label in Gravity Forms structure
107        if (!$field || $field.length === 0) {
108            $form.find('input[type="hidden"]').each(function() {
109                var $input = $(this);
110                var $wrapper = $input.closest('.gfield');
111                if ($wrapper.length) {
112                    var $adminLabel = $wrapper.find('.gfield_admin_label');
113                    if ($adminLabel.length && $adminLabel.text().toLowerCase().indexOf(searchText) !== -1) {
114                        $field = $input;
115                        return false;
116                    }
117                }
118            });
119        }
120        
121        return $field;
122    }
123
124    /**
125     * Populate hidden fields with SBJS data
126     * @param {jQuery} $form - The form jQuery object
127     * @param {boolean} silent - Whether to suppress console logging
128     * @param {boolean} force - Whether to force update even if value hasn't changed (for submission)
129     */
130    function populateHiddenFields($form, silent, force) {
131        silent = silent || false;
132        force = force || false;
133        var sbjsData = getSBJSData();
134        var populated = false;
135        
136        // Find and populate Source field
137        var $sourceField = findFieldByLabel($form, 'Source');
138        if ($sourceField && $sourceField.length > 0) {
139            // Disable autocomplete to prevent browser interference
140            $sourceField.attr('autocomplete', 'off');
141            var currentValue = $sourceField.val();
142            if (force || currentValue !== sbjsData.source) {
143                $sourceField.val(sbjsData.source);
144                // Use native setAttribute as fallback to ensure value is set
145                if ($sourceField[0]) {
146                    $sourceField[0].setAttribute('value', sbjsData.source);
147                }
148                if (!silent) {
149                    console.log('>>> SBJS: Populated Source field with:', sbjsData.source);
150                }
151                populated = true;
152            }
153        } else if (!silent) {
154            console.warn('>>> SBJS: Could not find Source hidden field');
155        }
156        
157        // Find and populate Medium field
158        var $mediumField = findFieldByLabel($form, 'Medium');
159        if ($mediumField && $mediumField.length > 0) {
160            // Disable autocomplete to prevent browser interference
161            $mediumField.attr('autocomplete', 'off');
162            var currentValue = $mediumField.val();
163            if (force || currentValue !== sbjsData.medium) {
164                $mediumField.val(sbjsData.medium);
165                // Use native setAttribute as fallback to ensure value is set
166                if ($mediumField[0]) {
167                    $mediumField[0].setAttribute('value', sbjsData.medium);
168                }
169                if (!silent) {
170                    console.log('>>> SBJS: Populated Medium field with:', sbjsData.medium);
171                }
172                populated = true;
173            }
174        } else if (!silent) {
175            console.warn('>>> SBJS: Could not find Medium hidden field');
176        }
177        
178        // Find and populate Campaign field
179        var $campaignField = findFieldByLabel($form, 'Campaign');
180        if ($campaignField && $campaignField.length > 0) {
181            // Disable autocomplete to prevent browser interference
182            $campaignField.attr('autocomplete', 'off');
183            var currentValue = $campaignField.val();
184            if (force || currentValue !== sbjsData.campaign) {
185                $campaignField.val(sbjsData.campaign);
186                // Use native setAttribute as fallback to ensure value is set
187                if ($campaignField[0]) {
188                    $campaignField[0].setAttribute('value', sbjsData.campaign);
189                }
190                if (!silent) {
191                    console.log('>>> SBJS: Populated Campaign field with:', sbjsData.campaign);
192                }
193                populated = true;
194            }
195        } else if (!silent) {
196            console.warn('>>> SBJS: Could not find Campaign hidden field');
197        }
198        
199        return populated;
200    }
201
202    /**
203     * Track which forms have been populated to prevent duplicate logging
204     */
205    var populatedForms = {};
206
207    /**
208     * Initialize on document ready and form render
209     */
210    $(document).ready(function() {
211        // Wait a bit for SBJS to initialize
212        setTimeout(function() {
213            // Populate fields on all existing forms
214            $('form[id^="gform_"]').each(function() {
215                var $form = $(this);
216                var formId = $form.attr('id');
217                
218                // Set autocomplete="off" on all hidden fields to prevent browser interference
219                $form.find('input[type="hidden"]').attr('autocomplete', 'off');
220                
221                populateHiddenFields($form);
222                populatedForms[formId] = true;
223            });
224        }, 500);
225    });
226
227    // Also populate when Gravity Forms renders/updates forms
228    $(document).on('gform_post_render', function(event, form_id, current_page) {
229        var $form = $('#gform_' + form_id);
230        if ($form.length > 0) {
231            var formId = $form.attr('id');
232            
233            // Set autocomplete="off" on all hidden fields to prevent browser interference
234            $form.find('input[type="hidden"]').attr('autocomplete', 'off');
235            
236            setTimeout(function() {
237                // Only log if this form hasn't been populated yet
238                var silent = populatedForms[formId] || false;
239                populateHiddenFields($form, silent);
240                populatedForms[formId] = true;
241            }, 100);
242        }
243    });
244
245    // Update fields right before form submission to ensure latest values
246    $(document).on('gform_pre_submission', function(event, form_id) {
247        var $form = $('#gform_' + form_id);
248        if ($form.length > 0) {
249            // Force update on pre-submission to override any autofill/autocomplete values
250            populateHiddenFields($form, true, true);
251        }
252    });
253
254    // Also handle AJAX form submissions - use synchronous approach to ensure values are set
255    $(document).on('submit', 'form[id^="gform_"]', function(e) {
256        var $form = $(this);
257        // Force update immediately before submission to override any autofill/autocomplete
258        // Use force=true to ensure SBJS data always wins
259        populateHiddenFields($form, true, true);
260        
261        // Also set values directly using native methods as a final safeguard
262        var sbjsData = getSBJSData();
263        var $sourceField = findFieldByLabel($form, 'Source');
264        var $mediumField = findFieldByLabel($form, 'Medium');
265        var $campaignField = findFieldByLabel($form, 'Campaign');
266        
267        if ($sourceField && $sourceField.length > 0 && $sourceField[0]) {
268            $sourceField[0].value = sbjsData.source;
269        }
270        if ($mediumField && $mediumField.length > 0 && $mediumField[0]) {
271            $mediumField[0].value = sbjsData.medium;
272        }
273        if ($campaignField && $campaignField.length > 0 && $campaignField[0]) {
274            $campaignField[0].value = sbjsData.campaign;
275        }
276    });
277
278})(jQuery);
279

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.