How to include basic "indent characters" in Sugar description and see the text correctly indented on record view (without having to edit it) ?

Hello,

I have a small issue and there is probably a trick but I don't get it.

I want to fill a basic description field (textarea) with some text, including indentation character (\t or mulitples spaces) to display the text in a proper way.

Unfortunatelly, the formating characters are removed from the view (but are still there because the text is correctly indented when I edit it).

any Idea?

  • Hi Frédéric,

    When Sugar renders the detail view template, I believe they only convert new lines (\n) to breaks (<br>) for display. In order to get it to respect tabs and multiple spaces, you'd likely have to customize the textarea field to convert them to html characters.

  • Hi ,

    that was what I was hoping to avoid :-(.

    But this also confirm that I am not totally dumb so it is only half a bad news.

    Thanks for your feedback.

    Fred

  • Hi Frédéric,

    I might have some good news! I spent some time doing a quick proof of concept and have some steps and an example download for you.


    Here's the general idea of what a developer would need to do:

    To accomplish our desired formatting, we will first need to create a custom helper function for the handlebar templates.

    ./custom/JavaScript/CustomHandlebarHelpers.js

    /**
     * Custom Handlebar helpers.
     *
     * These functions are used in handlebars templates.
     * @class Handlebars.helpers
     * @singleton
     */
     (function(app) {
        app.events.on("app:init", function() {
            /**
             * convert text to HTML for formatting
             */
            Handlebars.registerHelper("customTextToHTML", function (text)
            {
                text = Handlebars.Utils.escapeExpression(text);
                text = text.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + '<br>');
                text = text.replace(/(\t)/g, '&nbsp;&nbsp;&nbsp;&nbsp;');
                text = text.replace(/(\x20)/g, '&nbsp;');
                return new Handlebars.SafeString(text);
            });
        });
    })(SUGAR.App);
    

    Next, we need to create a JSGrouping to register our new function.

    ./custom/Extension/application/Ext/JSGroupings/CustomHandlebarHelpers.php

    <?php
    
    foreach ($js_groupings as $key => $groupings) {
        $target = current(array_values($groupings));
        if ($target == 'include/javascript/sugar_grp7.min.js') {
            $js_groupings[$key]['custom/JavaScript/CustomHandlebarHelpers.js'] = 'include/javascript/sugar_grp7.min.js';
            break;
        }
    }
    

    Finally, we need to copy ./clients/base/fields/textarea/detail.hbs to custom/clients/base/fields/textarea/detail.hbs and replace all instances of {{nl2br}} with {{customTextToHTML}}

    ./custom/clients/base/fields/textarea/detail.hbs

    <div> 
        {{#if value.short}} 
            {{#if collapsed}} 
                {{customTextToHTML value.short}}&hellip; 
            {{else}} 
                {{customTextToHTML value.long}} 
            {{/if}} 
            <button data-action="toggle" class="btn btn-link btn-invisible toggle-text"> 
                {{#if collapsed}} 
                    {{str 'LBL_TEXTAREA_MORE' module}} 
                {{else}} 
                    {{str 'LBL_TEXTAREA_LESS' module}} 
                {{/if}} 
            </button> 
        {{else}} 
            {{customTextToHTML value.long}} 
        {{/if}} 
    </div>
    

    Navigate to Admin > Repairs > Quick Repair and Rebuild and you should be good to go!


    You can download the module loadable package from here:
    upsertconsulting.com/.../




  • Hi

    thank you for this quick and great feedback. I will try as soon as possible.

    Have a good day

    Fred

  • Although I think that 's solution is probably a cleaner one, the getDescription function in the textarea field controller is used to clean up the short and the long versions of the text to be displayed in the non-edit-view.

    A quick test shows that adding the space and tab replacements that  has in the custom handlebars helper achieves the goal (I actually did a quick test by temporarily changing the core code - DO NOT DO THIS in any environment as a permanent solution - ALWAYS use the extension framework)

    getDescription: function(description, short) {
       short = !!short; 
       description = Handlebars.Utils.escapeExpression(description);
       description = short ? this.getShortComment(description) : description;
       description = this.insertHtmlLinks(description);
       //replace tabs with nbsp
       description = description.replace(/(\t)/g, '&nbsp;&nbsp;&nbsp;&nbsp;');
       //replace spaces with nbsp
       description = description.replace(/(\x20)/g, '&nbsp;');
       return new Handlebars.SafeString(description);
    },

    One would then assume that one could extend the textarea controller in the custom directory to achieve the goal without the need for a custom handlebars helper.

    FrancescaS

  • Hey everyone,

    there's a simpler solution - just add style="white-space: pre;" to the <div> styles. The default detail.hbs has a single <div> that contains some HBS logic - keep in mind that, if you just add this style to the <div> that's there, the first line will be indented because the whitespace in the .hbs file is also included (see e.g. here). The solution is to ensure that the actual text is not surrounded by whitespaces, by wrapping all the places a value actually gets inserted in a new div. Here's an example that should work:

    <div>
    {{#if value.short}}
    {{#if collapsed}}
    <div style="white-space: pre;">{{nl2br value.short}}&hellip;</div>
    {{else}}
    <div style="white-space: pre;">{{nl2br value.long}}</div>
    {{/if}}
    <button data-action="toggle" class="btn btn-link btn-invisible toggle-text">
    {{#if collapsed}}
    {{str 'LBL_TEXTAREA_MORE' module}}
    {{else}}
    {{str 'LBL_TEXTAREA_LESS' module}}
    {{/if}}
    </button>
    {{else}}
    <div style="white-space: pre;">{{nl2br value.long}}</div>
    {{/if}}
    </div>

  • I definitely like Gabriels solution the best! Oddly enough, using his solution I think you might also be able to drop the use of nl2br in the hbs file: 

    <div>
    {{#if value.short}}
    {{#if collapsed}}
    <div style="white-space: pre;">{{value.short}}&hellip;</div>
    {{else}}
    <div style="white-space: pre;">{{value.long}}</div>
    {{/if}}
    <button data-action="toggle" class="btn btn-link btn-invisible toggle-text">
    {{#if collapsed}}
    {{str 'LBL_TEXTAREA_MORE' module}}
    {{else}}
    {{str 'LBL_TEXTAREA_LESS' module}}
    {{/if}}
    </button>
    {{else}}
    <div style="white-space: pre;">{{value.long}}</div>
    {{/if}}
    </div>