Golden glory

Condensing custom contact data in FluentCRM admin view

I absolutely love FluentCRM, but have found that custom contact data can get a bit unwieldy to navigate in contact profiles when you’ve got a lot there. So here’s a snippet to customise and condense things.

There’s not much PHP in this one – all we’re doing is adding a script element to the FluentCRM admin app. Then the fun begins! You can read about the hook we’re using in the FluentCRM docs here.

First, we set an interval to run things every ten seconds, because FluentCRM is a SPA in the site backend. Then we check and see if FluentCRM custom fields exist in the document, and if not, we just don’t do anything. A little inelegant, but gets the job done.

Then we query for an array of nodes for each custom field group. For each node in that array, we instantly return if there’s no label, so we don’t do anything to any fields that aren’t part of a group.

Then we just do a bit of work on the DOM to put put each group in a details element, so we can selectively open and close which groups we want to see, and save a bunch of vertical space in the admin view.

<?php
add_action('fluent_crm/admin_app', function () {
    ?>
    <script>
        setInterval(() => {
            const customCrmFields = document.querySelector('.fluentcrm_custom_fields')
            if (customCrmFields && customCrmFields.getAttribute('data-detail-layout') !== "done") {
                const bits = document.querySelectorAll('.fluentcrm_custom_fields .el-form--label-top > div');
                bits.forEach((node) => {
                    if (!node.querySelector(":scope .fc_item_label")) {
                        return;
                    }
                    const name = node.querySelector(":scope .fc_item_label").innerText;
                    const layout = node.querySelector(":scope .fluentcrm_layout");

                    const deets = document.createElement('details');
                    const summary = document.createElement('summary');
                    summary.innerText = name;

                    deets.append(summary);
                    deets.append(layout);

                    node.append(deets);
                    node.querySelector(":scope .fc_item_label").remove();

                    node.style.border = "1px solid";
                    node.style.marginTop = ".5rem";
                    summary.style.borderBottom = "1px solid";
                    summary.style.padding = "0.5rem";
                    layout.style.padding = "0.5rem";
                })
                customCrmFields.setAttribute('data-detail-layout', 'done');
            }
        }, 10000);
    </script>
    <?php
});

Make it yours

This is just what I’ve got set up, but you might want to do some things differently, like changing the length of the interval timer, doing something different with the markup, or applying different styles.

Recent posts