TypeRocket / typerocket

TypeRocket is a highly integrated MVC WordPress framework with beautiful UI components for the modern developer.

Home Page:https://typerocket.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

jacobnoah opened this issue · comments

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,

@jacobnoah

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

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!