updated on 19-Nov-2019: Added comments on
I had a similar problem to this where I wanted multiple Rich-Text Editors and needed to access each JS instance of the editor.
I learned about about Quill JS here
My implementation is slightly different than the Code Mirror example in the following way
No Global Array to manage JS object references to editor
Outline of implementation.
Initialization does two passes. First pass renames a
div component which will wrap the JS editor. That is, the base Custom HTML will have something like this
First pass initialization will change the
id for the
div tag to be unique based on a random identifier.
The second stage initialization, will use this new
This custom / unique id, is created on the Anvil Python side, so each instance, knows its own identifier.
Then to interact with each editor, I use JQuery, to find the right element, extract the DOM node, and pass that to a static
find function in the Quill JS library, that will return a reference to the instance based on a DOM node.
Using these custom identifiers and changing the
id 's on instantiation allows to query for the correct instance without maintaining the global array.
Anyway, here is a an app that creates 4 Quill Rich Editor widgets on the same screen, with ability to interact with each editor.
Potential issue with more complex Embedding
In my “real app”, I am building a form with 4 levels of nesting … Column Panel contains a Grid panel, contains my RTF Email Form which contains the CustomHTML Form (Quill JS for Text Area.) I had to do some troubleshooting, which I thought I’d share.
When using more complex patterns, I have found the
form_show() method on my Custom HTML form, is not getting fired. It’s not an issue in the example code above, but might be an issue on more complicated embeddings (“in the wild” as it were).
My solution (not in example here, but in my real code), is explicitly calling
form_show() from my “Wrapper” Form. In this example code, it would be whatever you use to replace the
Be on the lookout! The error you will see is something like this
ExternalError: TypeError: Cannot read property '__quill' of undefined at QuillEditorWidget, line 27
Which is a symptom that the
<div id="xxx"> did not get set with the instance id. So HTML DOM node still has
specific id. Hence the
quill reference cannot be found.
The resolution is to make sure that the
form_show() method on the
CustomHTML (widget) form is called. First place to check is to ensure whatever is wrapping the
CustomHTML Form actually cascades the
Comments on Unique Identifiers
I borrowed the random string from Code Mirror example, but enhanced it by prepending a time element.
This tactic is inspired by python SimpleFlake implementation, which has an issue in that Sculpt / Anvil does not allow all Python Random module functions. The result is the pure SimpleFlake implementation only works in Server modules.
Presentation on SimpleFlake if you are interested.
Anyway, I used a similar tact, grab the time in seconds, and combine with random portion (6 random characters from an alphabet of 36 letters)
It might be a bit overkill, but I might re-use this when I need a more robust distributed UUID since the collision likelihood is small enough for my needs. (i.e match a random selection of 6 / 36 for a given second … i.e there are over two billion ways to draw 6 characters out of an alphabet of 36, accounting for fact that each draw is ordered, (A, B, C does not collide with C, B, A) and repeats are OK, AAA is a valid unique identifier.
So the Anvil Forms compliant conflation of SimpleFlake with @DavidWylie 's implementation.