Textbox - place blinking cursor at end after char removal

Hi,

I have a textbox component that accepts only certain characters and in particular the number 0-9. This is achieved by defining a list of allowed characters and then checking if any typed characters belong to this list. If not, then they are removed.

Though this works as intended locally, online if an “illegal” character is typed e.g. the letter ‘a’ it removes and it places the blinking cursor at the beginning of the input field. Ideally, I would prefer the blinking cursor to stay in place i.e. at the end of the typed characters.
For demonstration see https://run.pavlovia.org/Yiannis_A/ds I have tried different approaches including using the slice method but nothing worked.

Any advice will be much appreciated.

See below for code:

Begin Routine

allowedList = ['0','1','2','3','4','5','6','7','8','9']

Every Frame Python

if len(textbox_2.text)>0:
    for i in textbox_2.text:
        if i not in allowedList:
            textbox_2.text = textbox_2.text.replace(i, '')

Every Frame JS

var _pj;
function _pj_snippets(container) {
    function in_es6(left, right) {
        if (((right instanceof Array) || ((typeof right) === "string"))) {
            return (right.indexOf(left) > (- 1));
        } else {
            if (((right instanceof Map) || (right instanceof Set) || (right instanceof WeakMap) || (right instanceof WeakSet))) {
                return right.has(left);
            } else {
                return (left in right);
            }
        }
    }
    container["in_es6"] = in_es6;
    return container;
}
_pj = {};
_pj_snippets(_pj);
if ((textbox_2.text.length > 0)) {
    for (var i, _pj_c = 0, _pj_a = textbox_2.text, _pj_b = _pj_a.length; (_pj_c < _pj_b); _pj_c += 1) {
        i = _pj_a[_pj_c];
        if ((! _pj.in_es6(i, allowedList))) {
            textbox_2.text = textbox_2.text.replace(i, "");
        }
    }
}

I was facing a similar issue and I solved it as follows for PsychoJS. In my case, I liked to prohibit the return character in responses and was also facing the issue that the cursor was always placed at the beginning of the textbox once I replaced its content. Note: the textbox is called “textbox” in my PsychoPy experiment.

The following code did the trick:

// remove all return characters in the response
const text_without_return_chars = textbox.text.replace(/[\r\n]/g, '');

if (text_without_return_chars !== textbox.text) {
    textbox.text = text_without_return_chars;

    // ensure cursor is positioned at end of textfield once it was edited
    window.getSelection().setPosition(textbox._pixi._dom_input.lastChild, textbox._pixi._dom_input.lastChild.length);
 }