SVG editable text


I’m a newbie to Elm and playing around with elm/SVG. Need some help on “Editable Text” on the “Text” elelements of the SVG.

Here is an example codepen I’m trying to reproduce.

Here is my sample Elm code

import Html exposing (Html)
import Svg exposing (..)
import Svg.Attributes exposing (..)

main : Html msg
main =
    [ viewBox "0 0 400 400"
    , width "400"
    , height "400"
        [ x "140"
        , y "130"
        , fill "black"
        , textAnchor "middle"
        , dominantBaseline "central"
        [ text "I want this text to be dynamically Editable"

I did try to modify the example Text Fields · An Introduction to Elm to work with SVG’s. But no sucess. Any inputs will be helpful.


So the core stuff you need to set up looks something like this

You have a dynamic value, therefore it has to come from the model and then you create a Msg which is handled by update to change the model, and the text changes with it.

It seems like you don´t want a html input though but rather an svg you can directly type in. I don´t know if you can modify the native input to work that way, but I imagine you can get there just using the onKeyDown event and sending the keypresses directly onwards. The core setup will always be the same though, where you will have a model, a Msg type, an update function that changes the model according to the kind of Msg received and a view that renders based on the model.

Thank you @Earsinkle for your response. Your solution provides 50 % of what I was looking for.
That is mainly because I was not clear with my requirements.
In your suggested solution, there is a different input field and then you type the message or text what you want to be displayed. That is okay for basic purposes. But doesn’t solve the problem I have.

  1. With the suggested approach, we always end up having an editable input filed displayed on the screen.
  2. If we don’t have that visible text field to edit, then user doesn’t know that text field is editable.

My requirement is when user “clicks” or “double clicks” that text, I would like the user to be able to edit the text. Now with your suggested solution, we could make it work like this, add this new editable input html field and hide it when done. That seems like a good solution. But I want that editable field to overlap on the position of the original text, that gives better user experience.

The other option of on key pressed events like in game example given. I would like the trigger to happen only when a particular text of interest is clicked. There could be multiple text fields visible in the scene or viewport and want the option to change those text indipendent of one another. That user intent is best captured only when the user specifically clicks or double clicks a text field of his choice.

I was trying to overlap the position of the “html input” element on the text itself. But I’m not able to control the position of the input field. Not sure how to achive that.
While looking for similar option I bumped in to “foreginobject” element of SVG. This seems to work for the normal SVG created by hand. But not with the html file generated with Elm compiler. So there are some limitations I’m hit with. But when I inspect the elm generated html page. I could see the content hidden inside the div tag. But for some reason doesn’t show up how it does when I copy paste the MDN example in to normal html file.

There are other limitations I found with elm/SVG package. “href” tags doesn’t work if I want the text to follow a path using elements. But we are digressing from the initial topic here :slight_smile:

This is how I have done it, and it is a long way from simple! But also, possibly more than you need. I am not sure that SVG text elements can be editable so…

This is an SVG drawing and it has an SVG foreignobject element inside of it, which is an HTML element that is content editable. The editor is built with mweiss/elm-rte-toolkit.

1 Like

Thank you @rupert for your response. I understood how it needs to be done. As you mentioned I could use the “foreginobject” element and got it working.


This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.