tinymce / tinymce-svelte

Svelte wrapper
MIT License
23 stars 6 forks source link

simple example with <Editor> inside a form #31

Closed dmccallie closed 1 month ago

dmccallie commented 1 year ago

My apologies for asking such a basic question, but I am struggling to create a simple Svelte-friendly <form> element that contains a TinyMCE element such that when the form submission is triggered, the content is included in the formData that gets sent to the +page.server.js page.

In the documentation for non-Svelte examples, one can use the tinymce.init() function to set the configuration.selector value to point to one or more textareainside the <form>.

But as far as I can tell, with the Svelte wrapper for TinyMCE, we cannot call the tinymce.init() function directly, and must use the <Editor> component to instantiate TinyMCE.

However, when I put the <Editor> component inside a multi-input <form>, the formData that gets returned does not include the content from the editor. I am trying to support use:enhance so that Javascript is not required, but I can't seem to find a way to get the <Editor> to put its data into the submitted formData object.

I'm sure it's simple, but I am stumped. Could someone please point me to a simple example?

Thanks in advance!

exalate-issue-sync[bot] commented 1 year ago

Ref: INT-3091

dmccallie commented 1 year ago

OK, I may have answered my own question, but it seems too hacky??

Is using a hidden<div> to enclose the <Editor> a good way to tie the <Editor> to a <textarea> but without the <Editor> being visible? The snippet of code below seems to work, and the formData does include the <textarea> content.

Is this the best way to do it?

 <form>
       <div hidden > 
        <Editor {conf} bind:value={value} />
    </div>
    <TextArea label="Enter your text here" id="content" name="content" bind:value={value}></TextArea>
  </form>
jscasca commented 1 year ago

Hey @dmccallie unfortunately, I think you would need to handle your own submission to account for custom elements here.

I don't quite follow exactly what you are trying to do exactly. Is this related to #30 ? Do you have a small replication of what you are trying to accomplish?

dmccallie commented 1 year ago

Thanks for replying. Yes, #30 was when I was trying to use multiple inline elements on a page. I gave up on that quest and dropped back to a single, regular (not inline) editor inside a simple form. I then was unable to get the form to submit correctly, until I came up with the hacky code above, using a hidden DIV to hide the <Editor> and then binding the data to an associated <TextArea> as per the snippet above.

This seems to work via standard form submission, but it seems sort of hacky, and I was wondering if there was a better way?

Is there a simple Svelte example of a form submission that relies on use of the <Editor> component? Maybe the only clean way is with using a javascript submit hook, but with Svelte that ought not be necessary?

I think the key issue may be what to do about the lack of access to tinymce.init() when using Svelte?

Thanks for any help you have.

jscasca commented 1 year ago

To the best of my understanding, this may have been an oversight on the component side. It was created with the goal of being used as a reactive element which bind the value and you read that value at the time of submitting using on:submit.

That took me down a rabbit hole. Apparently, the issue is that the original element is created without a name and thus not being read by the form. Additionally, changes do not appear to be saving properly unto the original textarea. This could probably be better addressed by the component or handled by the user but would require to create a wrapper around the component.

Basically, the best way to handle the editor content at the time inside a form is to do:

  let editor1 = '';
  let editor2 = '';

  const handleForm = (e) => {
    const formContent = {
      name: editor1,
      content: editor2
    };
    console.log('submitting', formContent);
    // Submit content
  }
...
<form on:submit={handleForm}>
    <Editor bind:value={editor1}/>
    <Editor bind:value={editor2}/>
  </form>

The other question is, why would you want to use tinymce.init() tho?

Regardless of the usage, the point remains: tinymce-svelte needs to do a better job at being a form component. Either by creating relevant documentation or by satisfying the default behaviour of an input element. With that in mind I will mark this as a feature request.

dmccallie commented 1 year ago

Thank you @jscasca for digging in to this.

The reason I asked about tinymce.init() is that almost all of the tinymce documentation uses this function to set up the various configurations for tinymce, and it can do this without having to create a specific element on the page. OTOH, with the <Editor> component, you can't get access to the init() function, and it seems much less clear to me how to achieve some of the cool demonstrations in the documentation. Maybe some examples of how to replicate the non-Svelte examples while using the Svelte <Editor> would he helpful?

Thanks for the example of how to use on:submit. I may need to change my code to this approach, but surprisingly, so far, the "hack" (outlined in my earlier post) of using a hidden <Editor> along with a named <textarea> whose value is bound to the hidden <Editor> seems to work! The form's submit picks up the data from the named <textarea> even though it was captured using tinymce. Weird, but seems to work.

jscasca commented 1 year ago

You can use the conf property to achieve all the advanced stuff from other examples. You can find an example in a recent thread #29

If you have any particular thing you want to achieve feel free to ask and we will be happy to provide examples while we build up more documentation

tiny-stale-bot commented 1 month ago

This issue is stale because it has been open 30 days with no activity. Please comment if you wish to keep this issue open or it will be closed in 7 days.

tiny-stale-bot commented 1 month ago

This issue was closed because it has been stalled for 7 days with no activity.