Last active
April 10, 2026 14:57
-
-
Save cliffordp/c0b48b14f0f6f42d27c79e8f39013774 to your computer and use it in GitHub Desktop.
Gravity Forms: add the READONLY property to an input UNTIL it gets a value set
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * This snippet: https://gist.github.com/cliffordp/c0b48b14f0f6f42d27c79e8f39013774 | |
| * DEMO: https://share.zight.com/bLu9x8Y6 (3min) | |
| * WHAT: This adds the READONLY property to an input field and then removes it AFTER this same field has a value in it. | |
| * .readonly-until-value -> because self-referential, it's hidden until this field gets a value entered, such as via Populate Anything. | |
| * .readonly-until-value-77 -> the field with this class will be READONLY until Field #77 has a value. | |
| * WHY: Useful when a text field gets a dynamically-filled value but you want the input to remain editable thereafter. | |
| * EXAMPLE: a "County" text input (Field #9) has class `readonly-until-value-77` so when Full Address text input (Field #77) | |
| * gets a value (from human or dynamic), then County (#9) has its READONLY removed because #77 got a value. The idea is that | |
| * County would be dynamically-filled once Full Address is entered, but it remains editable for user correction and/or in case | |
| * it does not get a value entered (remains blank but is no longer READONLY). | |
| * HOW-TO: | |
| * 1. Install and activate the Code Chest plugin: https://gravitywiz.com/gravity-forms-code-chest/ (this code is formatted for use in that plugin). | |
| * 2. Paste this snippet into the form's Code Chest JavaScript input. | |
| * 3. Add the `readonly-until-value` or `.readonly-until-value-77` class to a text input field (not tested on other field types). | |
| */ | |
| gform.addAction("gfcc_deferred", function () { | |
| if (window['gfcc_poller_started_GFFORMID']) return; | |
| window['gfcc_poller_started_GFFORMID'] = true; | |
| var checkAllFields = function() { | |
| jQuery("#gform_GFFORMID .gfield").each(function () { | |
| var $field = jQuery(this); | |
| var classes = $field.attr("class") || ""; | |
| var match = classes.match(/readonly-until-value(?:-(\d+))?(?:\s|$)/); | |
| if (!match) return; | |
| var explicitSourceId = match[1] || null; | |
| var isSelfReferential = !explicitSourceId; | |
| var $inputs = $field.find("input, select, textarea").not(':button, :submit, [type="hidden"]'); | |
| if ($inputs.length === 0) return; | |
| if (!$inputs.first().data('ro_initialized')) { | |
| $inputs.data('ro_initialized', true); | |
| $inputs.prop("readonly", true).attr("tabindex", -1); | |
| if (isSelfReferential) { | |
| $field.css("visibility", "hidden"); | |
| } else { | |
| var $sourceLabel = jQuery("#field_GFFORMID_" + explicitSourceId + " .gfield_label").first(); | |
| if ($sourceLabel.length) { | |
| var labelName = $sourceLabel.text().replace(/\*/g, '').trim(); | |
| $inputs.attr("title", "First, enter " + labelName); | |
| } | |
| $inputs.on("focus.ro_bounce", function () { | |
| jQuery("#input_GFFORMID_" + explicitSourceId).focus(); | |
| }); | |
| } | |
| } | |
| var $monitoredInputs = $inputs; // Default to self | |
| if (!isSelfReferential && explicitSourceId) { | |
| // Since this explicitly relies on a source field (-77), we shift our surveillance | |
| // to evaluate if Field 77 has data inside it yet instead. | |
| var $sourceField = jQuery("#field_GFFORMID_" + explicitSourceId); | |
| if ($sourceField.length) { | |
| $monitoredInputs = $sourceField.find("input, select, textarea").not(':button, :submit, [type="hidden"]'); | |
| } | |
| } | |
| // Check if the monitored field has a value | |
| var hasValue = false; | |
| $monitoredInputs.each(function() { | |
| var type = jQuery(this).attr('type'); | |
| if (type === 'checkbox' || type === 'radio') { | |
| if (jQuery(this).is(':checked')) hasValue = true; | |
| } else { | |
| var val = jQuery(this).val(); | |
| if (val && String(val).trim() !== "") hasValue = true; | |
| } | |
| }); | |
| // If the appropriate event condition is met, unlock! | |
| if (hasValue && $inputs.prop("readonly")) { | |
| if (isSelfReferential) { | |
| $field.css("visibility", ""); | |
| } | |
| $inputs | |
| .prop("readonly", false) | |
| .removeAttr("readonly") | |
| .removeAttr("tabindex") | |
| .removeAttr("title") | |
| .off("focus.ro_bounce"); | |
| } | |
| }); | |
| }; | |
| checkAllFields(); | |
| setInterval(checkAllFields, 333); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment