Hide fields in quotes and invoices the easy way

For everyone who’s looking to hide fields but don’t wanna spend money on the modules whats doing the job because its just a one time thing, here a manual how to achieve. This method is update safe since updates don’t touch modules. It’s rather recommended than changing php files directly what will be most likely overwritten next update.

In short, we create a new module whats injecting jquery to the code. This is based on Leap, but it works on every Linux system the same. It’s based on the assumption that dolibarr is installed per rpm and located in /usr/share/. It was tested on 22.0.5 but I assume it also will work on any other newer version.

First we create the folders:

mkdir /usr/share/dolibarr/htdocs/custom/mycustomui
mkdir /usr/share/dolibarr/htdocs/custom/mycustomui/core
mkdir /usr/share/dolibarr/htdocs/custom/mycustomui/core/modules
mkdir /usr/share/dolibarr/htdocs/custom/mycustomui/class

Then we create the files we need and fill them with the needed code. First the file whats hiding the fields.

nano /usr/share/dolibarr/htdocs/custom/mycustomui/class/actions_mycustomui.class.php

And we fill the file with:

<?php
class ActionsMyCustomUI {
    /**
     * Injeziert das jQuery-Skript in den HTML-Header
     */
    public function addHtmlHeader($parameters, &$object, &$action, $hookmanager) {
        // Skript nur auf den Angebotsseiten ausführen
        if (strpos($_SERVER['PHP_SELF'], '/comm/propal/') !== false || strpos($_SERVER['PHP_SELF'], '/compta/facture/') !== fa>
            echo "\n<!-- Start Custom UI jQuery -->\n";
            echo <<<JS
<script>
document.addEventListener('DOMContentLoaded', function() {
    if (window.jQuery) {
        jQuery(document).ready(function($) {
            // 1. Bearbeitungsmodus / Entwurfsmaske ausblenden
            $('select[name="mode_reglement_id"]').closest('tr').hide();
            $('select[name="demand_reason_id"]').closest('tr').hide();
            $('select[name="availability_id"]').closest('tr').hide();

            // 2. Fertige Detailansicht ausblenden (Textsuche)
            $("td:contains('Zahlungsart')").closest('tr').hide();
            $("td:contains('Payment mode')").closest('tr').hide();
            $("td:contains('Quelle')").closest('tr').hide();
            $("td:contains('Source')").closest('tr').hide();
            $("td:contains('Lieferzeit')").closest('tr').hide();
            $("td:contains('Lieferfrist')").closest('tr').hide();
            $("td:contains('Availability')").closest('tr').hide();
            $("td:contains('Kategorien')").closest('tr').hide();
            $("td:contains('Standard Dokumentvorlage')").closest('tr').hide();
        });
    }
});
</script>
JS;
            echo "\n<!-- End Custom UI jQuery -->\n";
        }
        return 0;
    }
}

In this case we hide fields for quotes and invoices. The hidden fields in that example are source, payment mode, categories, delivery time and so on. Just replace it in the code with the fields you wanna hide.

Next we create the file for the module:

nano /usr/share/dolibarr/htdocs/custom/mycustomui/core/modules/modMyCustomUI.class.php

And fill the file with the needed code:

<?php
class modMyCustomUI extends DolibarrModules
{
    public $numero;
    public $name;
    public $description;
    public $version;
    public $family;
    public $enabled;
    public $module_parts;
    public $module_position;
    public $descriptionlong;
    public $rights_class;
    public $const_name;

    public function __construct($db) {
        $this->db = $db;
        $this->family = "technic";
        $this->module_position = '95';
        $this->numero = 500020;
        $this->name = 'MyCustomUI';
        $this->description = "Injects custom jQuery";
        $this->descriptionlong = "Injects custom jQuery";
        $this->version = '1.0.0';
        $this->module_parts = array('hooks' => array('propalcard', 'facturecard', 'invoicecard', 'main'));
        $this->enabled = 1;
        $this->rights_class = "mycustomui";
        $this->const_name = 'MAIN_MODULE_MYCUSTOMUI';
    }
}

Make sure the files are owned by the webserver:

chown -R wwwrun:www /usr/share/dolibarr/htdocs/custom/mycustomui/

Thats it. On the module page in dolibarr, just refresh the page and you will find a new module, called mycustomui. Activate it and its hiding the fields pasted into the file actions_mycustomui.class.php.

Disclaimer: This example is without warranty and you use it on your own risk. I’m not responsible for any problems, caused by that code.

Thanks for sharing this, @Buzzd — clean approach and good call using a custom module rather than patching core files.

A few additions from deploying similar UI customisations for clients:

Works on Debian/Ubuntu installs too
If Dolibarr wasn’t installed via rpm and lives somewhere other than /usr/share/, the custom module path is always <dolibarr_root>/htdocs/custom/ — so the folder structure you described is identical, just the base path differs.

jQuery selector tip
For fields that have no obvious HTML id, using the label text works reliably across versions:

$('tr').filter(function() {
  return $(this).find('td').first().text().trim() === 'Your field label';
}).hide();

This is less brittle than targeting positional selectors when the form layout shifts between versions.

One caveat
jQuery injection via a module hook runs client-side, so the field value is still sent to the server if the user inspects the DOM and manually populates it. For truly enforced restrictions (e.g. hiding a discount field from sales reps) a server-side permission check is safer. For cosmetic simplification of the form it’s perfect.

Thanks again for the write-up — this kind of community knowledge saves a lot of time.

— Ali — Dolibarr AI Consultant / SiliconBlaze

Good writeup — the hook approach is exactly the right pattern for update-safe UI customisation; far more robust than editing core files directly.

A couple of additions that might help others following this:

Module number uniqueness: The example uses 500020 — make sure yours doesn’t clash with another module on the instance. The recommended range for custom modules is 500000–599999. You can spot clashes via Home > Setup > Modules/Applications (hover a module to see its number in the URL, or check llx_modules in the DB).

Broader hook coverage: To also hide fields on other document types (orders, shipments, etc.), add their hook names to module_parts['hooks'] — e.g. commandecard, shipmentcard, propalcard. The full list is on the Dolibarr developer wiki under “Hook system.”

For extra fields specifically: If the fields you want to hide are extra attributes (not core fields), Dolibarr’s built-in extra field settings at Home > Setup > [Module] > Extra Attributes let you toggle “Visible” per entity type without any custom code — useful to know before reaching for jQuery.


Ali — Dolibarr AI Consultant / SiliconBlaze.com