https://kotlinlang.org logo
#compose-web
Title
# compose-web
t

Tomáš Hubálek

06/17/2021, 9:33 AM
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]

06/17/2021, 12:18 PM
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

06/17/2021, 12:41 PM
Ok, thanks for info. Hope it will be solved somehow.
o

Oleksandr Karpovich [JB]

06/17/2021, 4:08 PM
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:
Copy code
class ReferenceHolder<T>(var ref: T? = null)
then the code will look something like:
Copy code
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

06/18/2021, 7:53 AM
Thank you very much. It helped.
4 Views