Hiding standard fields in forms

Jordy Veldhuis
Jordy Veldhuis
  • Updated

Sometimes you want to hide certain fields in a form from end users, for example because they are filled in automatically, because they are intended only for agents, or because the same field should be requested on one form but not on another. This article explains how to do this through the Help Center theme.

Read this first: can you do it without code?

Hiding fields through the theme is a workaround. There are two standard solutions that often work better because they also apply to the API, email, and ticket view:

  • Conditional fields (Admin Center > Objects and rules > Tickets > Forms > Conditions). This lets you show a field only when another field has a specific value. This is the right solution if hiding the field depends on what the customer enters.
  • Field visibility (turn off the field setting "Editable for end users"). The field then disappears from all forms in the Help Center. This is useful only if you do not want to show the field to end users anywhere.

Only when you want to show a field on one form but not another, and this does not depend on an entered value, should you use the theme-based approach below.

Which method is right for your theme?

There are two generations of request forms, and they require different approaches. First check which one you have: open templates/new_request_page.hbs in your theme.

  • Does it contain <div id="new-request-form"></div> and a <script type="module"> with renderNewRequestForm? Then you have the new form (Copenhagen v2 and later). Use method A.
  • Does it contain {{#form 'request'}} with separate fields? Then you have the classic form. Use method B.

Note: in the new form, the div.form-field wrapper no longer exists, and jQuery is not available. Scripts from older articles and from the internet therefore do not work there.

Preparation: retrieve the correct IDs

  • Form ID: Admin Center > Objects and rules > Tickets > Forms. Open the form; the ID is in the URL.
  • Field ID: Admin Center > Objects and rules > Tickets > Fields. Open the field; the ID is in the URL. In the form's HTML, identify the field by name="request[custom_fields][VELD_ID]".

✅ Method A - New form (Copenhagen v2 and later)

The form is built by JavaScript after the page loads. This means you cannot search for the fields immediately after loading; you need a MutationObserver that waits until they appear. Add the script below to the bottom of templates/new_request_page.hbs.

<script>
  (function () {
    // formulier-ID : [veld-ID's die verborgen worden]
    var HIDDEN_FIELDS = {
      "360000111111": [
        "360000222222", // Naam van het veld, voor je collega van later
        "360000333333"
      ],
      "360000444444": [
        "360000222222"
      ]
    };

    var formId = new URLSearchParams(window.location.search).get("ticket_form_id");
    var fieldIds = formId ? HIDDEN_FIELDS[formId] : null;
    if (!fieldIds || !fieldIds.length) return;

    // Zoek de wrapper van een veld: klim omhoog tot het element ook het label bevat.
    function fieldWrapper(el, form) {
      var node = el.parentElement;
      for (var i = 0; i < 6 && node && node !== form && node !== document.body; i++) {
        if (node.querySelector("label")) return node;
        node = node.parentElement;
      }
      return null;
    }

    function hideFields() {
      var form = document.querySelector("#new-request-form form") ||
                 document.querySelector("#new-request-form");
      if (!form) return false;
      var done = 0;
      fieldIds.forEach(function (id) {
        var input = form.querySelector('[name="request[custom_fields][' + id + ']"]');
        if (!input) return;
        var wrapper = fieldWrapper(input, form);
        if (!wrapper) return;
        if (wrapper.dataset.cmHidden !== "true") {
          wrapper.dataset.cmHidden = "true";
          wrapper.style.display = "none";
        }
        done++;
      });
      return done === fieldIds.length;
    }

    var container = document.getElementById("new-request-form");
    if (!container) return;

    if (!hideFields()) {
      var observer = new MutationObserver(function () {
        if (hideFields()) observer.disconnect();
      });
      observer.observe(container, { childList: true, subtree: true });
      setTimeout(function () { observer.disconnect(); }, 15000);
    }
  })();
</script>

👉 The form URL then looks like this: /hc/nl/requests/new?ticket_form_id=FORM_ID. If the user switches forms, the page reloads with the new ID in the URL, and the selection is automatically correct.

Hiding the subject or description

These two fields do not have a custom field ID. Instead, use [name="request[subject]"] and [name="request[description]"] in the same function.

If you also want to prefill them, input.value = "..." does not work: the form is a React component and overwrites the value again. Use this:

function setValue(el, value) {
  var proto = el.tagName === "TEXTAREA"
    ? window.HTMLTextAreaElement.prototype
    : window.HTMLInputElement.prototype;
  Object.getOwnPropertyDescriptor(proto, "value").set.call(el, value);
  el.dispatchEvent(new Event("input", { bubbles: true }));
}

Does the description use a WYSIWYG editor? In that case, prefilling it does not work reliably. Instead, preferably fill in the subject through a trigger after the ticket has been created.

Method B - Classic form

If you still have an older theme with {{#form 'request'}}, div.form-field does exist and the classic approach can be used. Here too, add the script to the bottom of templates/new_request_page.hbs.

<script>
  document.addEventListener("DOMContentLoaded", function () {
    var formId = new URLSearchParams(window.location.search).get("ticket_form_id");
    if (formId !== "FORM_ID_HIER") return;

    ["request_subject", "request_description"].forEach(function (id) {
      var el = document.getElementById(id);
      if (el && el.closest(".form-field")) el.closest(".form-field").style.display = "none";
    });

    document.getElementById("request_subject").value = "Nieuw ticket";
  });
</script>

In this theme, custom fields have the ID request_custom_fields_VELD_ID.

Two things that often go wrong

1. Required fields prevent submission

Zendesk validates a hidden field as usual. If the field is required, the customer sees a message when submitting that fields marked with an asterisk are required, even though the field itself is not visible anywhere. Therefore, always set hidden fields to not required, or fill them in after creation using a trigger.

2. The fields still appear in the ticket details

Hiding applies only to the request form. On the page for a submitted ticket (request_page.hbs), Zendesk displays all form fields in the sidebar, including empty ones. In this template, the field ID is not available in Handlebars, so filtering by ID is not possible there. What you can do is not display fields without a value at all. Add this to the bottom of templates/request_page.hbs.

<script>
  (function () {
    function isEmpty(dd) {
      // Alleen dd's zonder child-elementen; status, organisatie, CC's en
      // bijlagen bevatten wel elementen en blijven dus altijd staan.
      if (dd.children.length > 0) return false;
      return dd.textContent.replace(/[\s\-‐-―−]/g, "") === "";
    }

    function hideEmptyDetails() {
      document.querySelectorAll(".request-details dd").forEach(function (dd) {
        if (!isEmpty(dd)) return;
        var dt = dd.previousElementSibling;
        if (dt && dt.tagName === "DT") dt.style.display = "none";
        dd.style.display = "none";
      });
    }

    if (document.readyState === "loading") {
      document.addEventListener("DOMContentLoaded", hideEmptyDetails);
    } else {
      hideEmptyDetails();
    }
  })();
</script>

If an agent later fills in such a field, it appears in the sidebar again. If you want to exclude this, you must return to the field setting "Editable for end users."

Testing

  1. Upload the theme as a preview, not immediately as live.
  2. Open /hc/nl/requests/new?ticket_form_id=FORM_ID and check whether the correct fields are hidden.
  3. Switch to another form and check whether the correct set of fields disappears there.
  4. Submit a test ticket and check whether submission succeeds (required fields).
  5. Open the ticket as an end user and check the ticket details in the sidebar.
  6. Repeat this in every active language of your Help Center.

Note about theme updates

These scripts are in your templates. If you update the theme to a new version of Copenhagen, the templates are overwritten and the scripts disappear. Put the changes in version control or document them for each customer, and restore them after every update.

When is this useful?

  • When the same field should be requested on one form but not on another
  • When end users may fill in only specific fields
  • For onboarding or request forms with a fixed ticket structure
  • When you want to standardize subject lines