Formatter API

Implementation of a new formatter

After creating a new formatter in the workspace, a text editor will open with the formatter implementation template.

The formatter is represented as a JavaScript function with the signature initially provided in the template:

function formatText(input) {
         return { 
                formattedText: input.textToFormat,
                cursorPosition: input.cursorPosition 
          };
}

Description of the formatter function signature:

Parameter name
Type
Type
Description

input.textToFormat

input

String (JAVA)

Text to be formatted. You should convert the JAVA type of the variable to the JavaScript (new String(input.textToFormat); ) in order to call methods for the String (e.g. replace())

input.locale

input

String (JAVA)

A string specifying the language in which the form is displayed (e.g. "pl", "en"). You should convert the JAVA type of the variable to the JavaScript (new String(input.locale); ) in order to call methods for the String (e.g. replace())

input.cursorPosition

input

int

Cursor position in the text field before formatting

output.formattedText

output

String

Text after formatting

output.cursorPosition

output

String

Cursor position in the text field after formatting - an integer in the range <0,output.formattedText.length> - if a number outside the range is provided, the webforms application will not change the cursor position (the browser's default behavior will be preserved)

The formatter implementation should be done by changing only the inside of the function.

For correct operation the formatter must be a valid JavaScript. Otherwise, when attempting to save the formatter in the current user workspace, an appropriate system error message will be generated.

Sample formatter code (adds a thousand separator to a number and always sets the cursor to the end):
function formatText(input) {
    if (typeof input.textToFormat == 'undefined') {
        return  {
            formattedText: "",
            cursorPosition: -1
        };
    }
     
    let number_format = function(number, decimals, dec_point, thousands_sep) {
        number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
        let n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0
                    : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ','
                    : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.'
                    : dec_point, s = '', toFixedFix = function(n, prec) {
            let k = Math.pow(10, prec);
            return '' + Math.round(n * k) / k;
        };
        s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
        if (s[0].length > 3) {
            s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
        }
        return s.join(dec);
    }
     
    let textToFormat = new String(input.textToFormat + "");
    textToFormat = textToFormat.replace(/\s+/g, '');
    textToFormat = textToFormat.replace(/,/g, '.')
    textToFormat = textToFormat.replace(/[^\d^\.]/g,'');
     
    let temp = parseFloat(textToFormat);
    if(isNaN(temp)){
        return {
            formattedText: "",
            cursorPosition: -1
        };
    }
    let resultText = number_format(temp, 2, ',', ' ');
     
    return {
        formattedText: resultText,
        cursorPosition: resultText.length
    };
}

Version with the caret placed at the natural position (taking thousand separators into account). The formatter below will not work for an EMAIL TextField due to JavaScript limitations (input type="email" does not implement caret position retrieval).

Version with the caret placed at the natural position
function formatText(input) {
 
    let spacesInInput;
    let localCursorPosition;
     
    if(input.cursorPosition) {
        localCursorPosition = input.cursorPosition;
    }
     
    if(input.textToFormat) {
        if(input.textToFormat.startsWith('0')) {
            localCursorPosition--;
        }
        spacesInInput = (input.textToFormat.match(/ /g) || []).length;
    } else {
        return  {
            formattedText: "",
            cursorPosition: -1
        };
    }
     
    let number_format = function(number, decimals, dec_point, thousands_sep) {
        number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
        let n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0
                    : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ','
                    : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.'
                    : dec_point, s = '', toFixedFix = function(n, prec) {
            let k = Math.pow(10, prec);
            return '' + Math.round(n * k) / k;
        };
        s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
        if (s[0].length > 3) {
            s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
        }
        return s.join(dec);
    }
     
    let textToFormat = new String(input.textToFormat + "");
    textToFormat = textToFormat.replace(/\s+/g, '');
    textToFormat = textToFormat.replace(/,/g, '.')
    textToFormat = textToFormat.replace(/[^\d^\.]/g,'');
     
    let temp = parseFloat(textToFormat);
    if(isNaN(temp)){
        return {
            formattedText: "",
            cursorPosition: -1
        };
    }
    let resultText = number_format(temp, 2, ',', ' ');
     
    let caretPosition = localCursorPosition ? localCursorPosition : resultText.length;
    let spacesAfterParse = (resultText.match(/ /g) || []).length;
 
    if(spacesAfterParse > spacesInInput) {
        caretPosition++;
    } else if(spacesAfterParse < spacesInInput) {
        caretPosition--;
    }
 
    return {
        formattedText: resultText,
        cursorPosition: caretPosition
    };
}

Handling of formatters according to the previous template

For formatters created according to the previous template shown below, the cursor after formatting the text will be set to the end if it was at the end before formatting. If the cursor was positioned within the text, then after formatting the cursor in the field will be set to the same position it was before formatting.

function formatText(textToFormat, locale) {
        return  formattedText;
}

Description of the previous formatter function signature:

Parameter name
Type
Type
Description

textToFormat

input

String

Text to be formatted

locale

input

String

A string specifying the language in which the form is displayed (e.g. "pl", "en")

formattedText

output

String

Text after formatting

Limitations

  • Formatters cannot use prototype inheritance mechanisms

  • In formatters that format outputs from a service, objects passed to the formatter are Java objects; to perform string operations you must convert them to JavaScript objects (e.g.: const textToFormat = new String(input.textToFormat + ""))

Demo form: demoFormatters

Last updated

Was this helpful?