Search code examples
javascriptcsstwitter-bootstrapwysiwygsummernote

Unable to display Summernote textarea on spring project


In my current spring project, I have this admin page with a code like that (simplified to be presented here):

<ul class="nav nav-tabs">
  <li class="nav-item">
    <a class="nav-link active" href="#">Active</a>
  </li>
</ul>

<div class="tab-pane active" id="listagem" role="tabpanel" aria-labelledby="listagem-tab">
    <button type="button" class="btn btn-secondary" onclick="update_data(this)">
        <i class="fas fa-edit"></i>
    </button>
    <button type="button" class="btn btn-secondary" onclick="delete_data(this)">
        <i class="fas fa-trash"></i>
    </button>
</div>

when the buttons are clicked, a new tab is added and the code below is added to the tab-pane:

<div id="form-container">
    <form class="form" id="form" method="post" action="#">
        ...
        <textarea rows="25" cols="80" class="summernote" id="descricao" name="descricao"></textarea>
        ...
    </form>
</div>

which should display a wysiwyg textarea when i open the page in thr browser. the code for summernote is added to the bottom of the admin page:

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/----------.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote-bs4.js"></script>
<script>
$(document).ready(function(){
  $('.summernote').summernote({height: 300});
});
</script>

<script th:src="@{/js/script-admin.js}"></script>

(the css file for summernote it's added on the top of the page, in the head section).

but when I actually run the project and open the page in the browser, it's displayed a simple textarea, without any summernote style. Anyone can give a hint of what is wrong here?

ps.: the code which handles reading the form page and add to the tab-pane is like this:

function insert_data() {
  if(document.getElementById('insert-tab').parentNode.style.display === 'none') {
    var url = document.getElementById('insert').dataset.url;

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        var myObj = this.responseText;

        parser = new DOMParser();
        var doc = parser.parseFromString(myObj, "text/html");
        var form_html = doc.getElementById('form-container');

        document.getElementById('insert').innerHTML = form_html.innerHTML;
        document.getElementById('tab-insert').removeAttribute('style');

        document.getElementById("listagem-tab").classList.remove('show');
        document.getElementById("listagem-tab").classList.remove('active');
        document.getElementById("listagem").classList.remove('show');
        document.getElementById("listagem").classList.remove('active');

        document.getElementById("insert-tab").classList.add('show');
        document.getElementById("insert-tab").classList.add('active');
        document.getElementById('insert').classList.add('show');
        document.getElementById('insert').classList.add('active');
      }
    };
    xmlhttp.open("GET", url, true);
    xmlhttp.send();
  }
}

Solution

  • Just for the record, I solve this issue by adding javascript code to my project to keep track of changes in the tab-pane div above, and calling $('.summernote').summernote(...) when a node with the class .summernote is added. that's my code for this:

    var tab_pane = document.getElementsByClassName("tab-pane");
    
    for (i = 0; i < tab_pane.length; i++) {
      // Select the node that will be observed for mutations
      var targetNode = tab_pane[i];
    
      // Options for the observer (which mutations to observe)
      var config = { attributes: true, characterData: true, childList: true, subtree: true, attributeOldValue: true, characterDataOldValue: true };
    
      // Callback function to execute when mutations are observed
      var callback = function(mutationsList, observer) {
          for(var mutation of mutationsList) {
            if (mutation.type == 'childList')
                detect_editor();
            if (mutation.type == 'subtree')
                detect_editor();
          }
      };
    
      // Create an observer instance linked to the callback function
      var observer = new MutationObserver(callback);
    
      // Start observing the target node for configured mutations
      observer.observe(targetNode, config);
    }
    
    function detect_editor() {
      var editor = document.getElementsByClassName("summernote");
      for (i = 0; i < editor.length; i++) {
        $(editor).summernote({height: 300});
      }
    }