Thread
#compose-web
    t

    Tomáš Hubálek

    1 year ago
    I have a question related to edit texts in Safari. There is known bug/feature that causes that when you change input text value from JavaScript then cursor/carret jumps to the end. In JavaScript there is a workaround that saves cursor position before setting value then modify value and then restore cursor position (see eg. https://stackoverflow.com/a/29440988 for reference) I'm thinking how to do this in JetPack Compose for web. Storing cursor position using
    remember
    ?
    o

    Oleksandr Karpovich [JB]

    1 year ago
    I was writing some idea about this. But then I realized that the current compose-web API won't let implement it. (If we're talking about Input element) indeed, it seems possible to remember the cursor position. But you don't have a place to set it back. The idea was to use DomSideEffect, but you can't access it for Input anymore. We'll need to figure it out.
    t

    Tomáš Hubálek

    1 year ago
    Ok, thanks for info. Hope it will be solved somehow.
    o

    Oleksandr Karpovich [JB]

    1 year ago
    we discussed your scenario a bit, and actually there is a way to do it, although the code is not really concise: first, you'll need a class to keep the reference to the HtmlElement:
    class ReferenceHolder<T>(var ref: T? = null)
    then the code will look something like:
    val textState = remember { mutableStateOf("") }
            val cursorPosition = remember { mutableStateOf(0) }
    
            Div {
                val reference = remember { ReferenceHolder<HTMLInputElement>() }
    
                Input(type = InputType.Text, value = textState.value, attrs = {
                    ref {
                        reference.ref = it as HTMLInputElement
                        onDispose {
                            reference.ref = null
                        }
                    }
                    onTextInput {
                        cursorPosition.value = it.nativeEvent.target?.asDynamic()?.selectionStart ?: 0
                        textState.value = it.inputValue
                    }
                })
    
                DomSideEffect {
                    println("The previous cursor position was = ${cursorPosition.value}")
                     // you can use reference.ref to access your Input element and set its cursor
                }
            }
    or you can even use element in
    DomSideEffect { yourDivElement -> }
    to get to the input from its parent. In this case there is no need for
    val reference = ...
    and
    ref { reference.ref = ...}
    Although, a variant with
    reference
    seems to be more reliable
    t

    Tomáš Hubálek

    1 year ago
    Thank you very much. It helped.