Skip to content
This repository has been archived by the owner on Mar 29, 2023. It is now read-only.

Fix SimpleMDE initialization for namespaced models and nested objects #8

Merged
merged 4 commits into from Mar 4, 2020
Merged

Conversation

sedubois
Copy link
Contributor

Fixes #7

@michelegera
Copy link
Contributor

@sedubois thanks for this PR!

I’ve actually refactored things a little bit to clean up the partial, and added some tests.

Can you verify that it still fixes your use case? If so, I’ll merge it!

@sedubois
Copy link
Contributor Author

sedubois commented Feb 20, 2020

Yes @michelegera it works for when editing a Course::Translation directly.

However I found another issue when editing a nested model. My Course dashboard has translations: Field::NestedHasMany.with_options(class_name: "Course::Translation") (see this gem) and when editing the course (/courses/:id/edit), in this case the editor doesn't load properly. That's because textareas have IDs like course_translations_attributes_XXX_about.

How about selecting .simple_markdown textarea? But because for some reason this piece of javascript is being executed twice, need to guard against double execution otherwise two editors will appear one above the other. This quick hack works:

    $(function() {
      if(!window.mde_initialized) {
        new SimpleMDE({element: document.querySelector('.simple_markdown textarea')});
        window.mde_initialized = true;
      }
    });

Also would there be a way for this code to run when a new textarea gets added to the DOM (when clicking "Add Course/Translation") instead of only when the page loads? Otherwise the editor only loads when editing an existing nested course, instead of when creating a new one.

@sedubois
Copy link
Contributor Author

Also would there be a way for this code to run when a new textarea gets added to the DOM (when clicking "Add Course/Translation") instead of only when the page loads?

Something like the code below gets close, when clicking "Add Course/Translation" a new Markdown editor gets initialzed in the newly created field, but then unfortunately the other one stops working (you may notice that my Javascript skills are not very sharp):

<%= content_for :javascript do %>
  <script type="text/javascript">
    $(function() {
      if(!window.mde_initialized) {
        window.mde_initialized = true;

        function initSimpleMarkdown() {
          elem = $('.simple_markdown textarea:not(.simple_markdown--initialized)');
          elem.each(function(index, value) { new SimpleMDE( {element: value }); });
          elem.addClass("simple_markdown--initialized");
        }

        document.addEventListener("click", function (event) {
          var target = event.target;
          if (target.tagName === "A" && target.dataset['association']) {
            setTimeout(function() { initSimpleMarkdown() }, 0);
          }
        }, true);

        initSimpleMarkdown();
      }
  </script>
<% end %>

@michelegera michelegera changed the title Fix DOM ID when using namespaced model Fix SimpleMDE initialization for namespaced models and nested objects Mar 2, 2020
@michelegera
Copy link
Contributor

Hey @sedubois, sorry for the late reply.

Thanks for exposing edge cases that I had not taken into consideration. I took some time to come up with a solution that should fix both issues (namespaced models and dynamically-added, nested form).

What I did was:

  • Add a data-simplemde attribute to the text areas and use that as a hook to initialize SimpleMDE, rather than inferring the element id and potentially missing other edge cases (I should have done it from day one!)
  • Leverage MutationObserver APIs to watch the DOM for changes and initialize other editors as they get injected in the main form.

Let me know how that works for you.

@sedubois
Copy link
Contributor Author

sedubois commented Mar 3, 2020

Hi @michelegera, thanks very much for trying to fix this.

I've tested it as follows:

# Gemfile
gem 'administrate-field-simple_markdown', git: "https://github.com/sedubois/administrate-field-simple_markdown", ref: "9a15bfac"

I then open /admin and click on Courses on the left, then click on one course, then click "Edit ". Unfortunately the editor does not load in this case, it's justs a textarea. I see however that the textarea contains data-simplemde="true":

Screenshot 2020-03-03 at 09 36 41

However a workaround is to reload the page (Cmd-R). In this case, the editor loads fine.

I think it's because of Turbolinks. When commenting out turbolinks.start() from my admin.js JS pack (which is loaded with <%= javascript_pack_tag "admin" %> in app/views/layouts/admin/application.html.erb), then the editor loads fine even when navigating from another page.

Maybe it's possible to fix it by adding something like this? Or is there a more general way so that this plugin remains agnostic to Turbolinks, such as listening to state changes on the history stack?

document.addEventListener("turbolinks:load", function(elem) {
  initSimpleMDE(elem);
})

Use the data attribute to flag text areas that have been initialized, and run the setup phase also after Turbolinks are loaded.
@michelegera
Copy link
Contributor

Good catch @sedubois.

I’ve changed the logic a little bit, and refactored the initialization code. Now the data attribute starts as false, and it’s set to true upon SimpleMDE initialization. This should ensure that text areas are initialized only once (the setup phase now runs both on DOM content loaded and after Turbolinks are loaded).

There might be a more elegant, Rails-way to handle this 😄 but this should take care of both scenarios effectively.

@sedubois
Copy link
Contributor Author

sedubois commented Mar 4, 2020

Great @michelegera, it all seems to work now 👍 Seem OK to merge for me.

@michelegera michelegera merged commit 6519311 into zooppa:master Mar 4, 2020
@sedubois sedubois deleted the patch-1 branch March 16, 2020 06:27
@sedubois
Copy link
Contributor Author

@michelegera would it be possible to get a release with this? 🙂

@michelegera
Copy link
Contributor

@sedubois Yes, absolutely. Sorry for the delay, a release should be out later today!

@michelegera
Copy link
Contributor

I’ve just released v0.3.0.

@sedubois
Copy link
Contributor Author

@michelegera I don't know how I had checked this exactly but actually a single editor loads on the page when I have several associations on the page with SimpleMarkdown fields. Also if I then keep navigating to another resource (which doesn't reload the full page as I'm using Sprockets), then no editor gets loaded at all. I have to reload the page for one editor to load.

Basically it looks like whatever I do, only one editor manages to load for every fresh page load. Would you have an idea?

I'm using administrate-field-simple_markdown (0.3.0).

@michelegera
Copy link
Contributor

@sedubois that’s weird, could possibly be related to the MutationObserver initialization. I tried on my local test repo, but was not able to reproduce the issue.

Would you be able to provide a repo of a simple app that exposes this problem?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Javascript/CSS doesn't load?
2 participants