Lv_textarea formatter

So I’m trying to have an input text_area with a special formatting.
Is it possible to have a text_area set with a set of accepted characters but to attach a formatter ?

So basically I want my textArea to only accept number.
But I want I want the final text to be displayed differently. ( \d\d/\d\d )

lv_obj_t* _inputWidget = lv_textarea_create(lv_scr_act(),0);
lv_textarea_set_accepted_chars(_inputWidget,"0123456789"); //mask
lv_textarea_set_max_length(_inputWidget,4);
lv_obj_set_event_cb(_inputWidget,formatterCb);

Nb I don’t want to allow the “/” char, I want to have a postCb formatted which would basically do

int expDate = atoi(lv_textarea_get_text(_inputWidget);
sprintf("%02d/%02d,expDate/100,expDate%100), 

This is a simple example, but I have other more complex needs (where input != display)
How do you guy do it ?

There isn’t any built-in feature for this that I’m aware of, so you would have to manually process the input and modify the text area accordingly.

Actually LV_EVENT_VALUE_CHANGED can be used for this purpose.

I’ve just added an example for this:
https://docs.lvgl.io/latest/en/html/widgets/textarea.html#text-auto-formatting

Yes but is not exactly the same @kisvegabor.
I end up writting something similar. but actually I’d be more convenient for user to have 2 separate “const char*” to deal with.
In you example for instance.

  • We wanted user to only insert numeric char but we have to allow “:”. Thus I might be wrong be we need to handle this “bad input” in callback. (Which is a bit late considering text_area would have already put it into his buffer).
  • You can’t check the rawInput versus a simple validator. You will need to unformat first.

Here what I had as callback for something similar.

void editViewButtonsEventHandler(lv_obj_t* /*obj*/, lv_event_t event) {
        EditView* editView(static_cast<EditView*>(LvglUserInteraction::Pimpl::getInstance()._currentView));
        if (editView) {
            if (event == LV_EVENT_KEY) {
                uint32_t key = *(uint32_t*)lv_event_get_data();
                switch (key) {
                case ':':
                case '/':
                case ' ':
                    lv_textarea_del_char(editView->_inputWidget);
                    break;
                case LV_KEY_ESC:
                    editView->_result = UserInteractionInput::INPUT_CANCEL;
                    editView->_quit = true;
                    break;
                case LV_KEY_ENTER: {
                    //need validation
                    bool isvalid = true;
                    editView->_input = lv_textarea_get_text(editView->_inputWidget);
                    if (editView->_inputValidator) {
                        if (editView->_inputFormatter) {
                            removeAllUnAuthChars(editView->_input);
                        }
                        isvalid = (*editView->_inputValidator)(editView->_input.c_str()); //on compare avec la valeur raw
                    }
                    if (isvalid) {
                        editView->_result = UserInteractionInput::INPUT_OK;
                        editView->_quit = true;
                    }
                    break;
                }
                default:
                    if (editView->_inputFormatter) {
                        editView->_input = lv_textarea_get_text(editView->_inputWidget);
                        removeAllUnAuthChars(editView->_input);
                        std::string formattedStr = (*editView->_inputFormatter)(editView->_input.c_str());
                        lv_textarea_set_text(editView->_inputWidget, formattedStr.c_str());
                    }
                }
            }
        }
    }

Another alternative could be to use LV_EVENT_INSERT in the Text area. Can you use it as a validator hook?

A really good improvement would be to create a “filer” feature for the Text area. For example:

  • date [0-1][0-9]/[0-3][0-9] or [0-12]/[0-31]
  • IP address: [0-255].[0-255].[0-255].[0-255]

The character out of [] could be inserted automatically.