Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulating contenteditable in SVG without foreignobject

I have written a web-application where users can create svg elements with text. I want to simulate contenteditable elements inside the svg elements, so that users can dynamically edit the content of the svg elements. That is, when a user clicks on one of these elements, a cursor should appear so that the text can be edited. I do not want to use foreignobject to achieve this, since this is not supported by IE. I couldn't find anything useful about this online, so is there any way to do this?

EDIT: To clarify, here is an example:

<svg>
    <rect width="192" height="192" style="stroke-width: 3; fill:red"></rect>
    <text x="30" y="20">A sample text</text><!-- when the user clicks on this, it should be editable-->
</svg>
like image 807
Guido Passage Avatar asked Dec 06 '13 17:12

Guido Passage


2 Answers

Here's an example:

<div contenteditable="true">
    <svg>
        <circle cx="10" cy="10" r="5" fill="green" />
        <text y="2em">Hello world</text>
    </svg>
</div>

http://jsfiddle.net/ZEAwB/

Works in Opera 18, Chrome 33, Firefox (Nightly) 28 and IE9. Probably works in earlier versions of Opera, Chrome and Firefox too, not quite sure how far back though.

like image 141
Erik Dahlström Avatar answered Nov 03 '22 00:11

Erik Dahlström


@Erik Dalhström's solution doesn't seem to address the question: He wants to be able to edit text content atop ("inside") an SVG object, as the example showed. On Firefox, Erik's code indeed makes the text editable, but beneath the 10 x 10 circle, and not inside the SVG space.

I found a workaround at https://github.com/artursapek/mondrian/issues/12 :

when the user clicks on an SVG <text> element, set the contenteditableattribute on the nearest ancestor in HTML namespace to true (e.g. document.body.contentEditable = true;), then make the SVG <text> element selectable (e.g. svgTextElement.style.webkitUserSelect = 'text';).

When the user finishes editing the text (e.g. by clicking on canvas) set the contentEditable attribute on the ancestor back to false.

I haven't tried this, hope someone reports back if this works. We shouldn't have to wait for CSS 2.0 to get this very obviously needed functionality.

like image 45
Pete Zelchenko Avatar answered Nov 02 '22 23:11

Pete Zelchenko