Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

The wordpress editor is not broken in repeater fields, the implementation is #259

Open
jacobnoah opened this issue Jul 18, 2023 · 2 comments

Comments

@jacobnoah
Copy link

Hi Typerocket team,

I believe I have solved a huge issue for you when it comes to generating a new repeater block with an editor (wordpress editor) field inside of it. In my implementation I was using tinyMCE with the wordpress editor to update settings etc. The issue stems from the fact there is a hidden repeater group that core.js uses to clone whenever you add a new block. This clones the exact elements above including the id of the textarea that gets changed into the tinymce editor. By using some chaining inside the function that lives on line 141 of core.js I removed the div with the class of control that contains both the texteditor and the tinymce editor. Then I create an html string with var html = "

<textarea class='tinyEditor' id='tinymce_123'></textarea>
"; I then appended this string in the right place in the new repeater block. In my javaScript I was using a mutation observer which looks for when new textareas get added to the dom. (there are other ways to do this) but when this change was observed it would simply init tinyMCE with the selector set to '.tinyEditor' and voila the new editor works and does not get stale. This would be extremely helpful to me as well as future customers at least for a documentation guide. I would be happy to share more if needed.

Thanks,

@kevindees
Copy link
Member

@jacobnoah

Thanks so much for sharing this. We will take a look at getting this into the core.

@jacobnoah
Copy link
Author

I actually have some more generalized code to share and also have a fix for when you reorder the modules when creating a page.

In this function in core.js: e(document).on("click", ".tr-repeater .controls .add", function () {

I added a function called makeID just to generate a random id for the new editor.

function makeId(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
let counter = 0;
while (counter < length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
counter += 1;
}
return result;
}

            var html = `<div class='control'><textarea class='tinyEditor' id='mce_editor_${makeId(13)}_'></textarea></div>`;

            
            jQuery(r[0]).find('.tinyEditor').parent().replaceWith(html);

}

You can see I just create some html for the new control element then I used the variable r which contains the entire dom for the sortable subgroups and do some jQuery to find the textarea just added with the class I gave it ('tinyEditor') I get that parent and then replace that parent which should be the control div with the html.

Then for the drag/drop feature since I have tinymce I was able to just loop over all editors and remove them and then reinit them after and everything works!

e(".tr-components").sortable({
start: function (e, t) {
return t.item.startPos = t.item.index()
},
update: function (t, r) {
var a, n, i, o, l, s, c;
jQuery(".tinyEditor").each(function () {

            tinymce.execCommand("mceRemoveEditor", false, this.id);
            tinymce.execCommand("mceAddEditor", false, { id: this.id, options: {} });
        });
        return c = r.item.parent(), o = c.data("id"), i = e("#frame-" + o), n = i.children().detach(), l = r.item.index(), s = r.item.startPos, a = n.splice(s, 1), n.splice(l, 0, a[0]), i.append(n)
    }

Let me know if I can be of more help. Thanks!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Development

No branches or pull requests

2 participants