Search code examples
javascriptspring-bootthymeleaf

Thymeleaf - How to interact and reload Javascript?


Without page refresh, I am calling an ajax request that goes to the controller and brings a Thymeleaf fragment,

On button click, I request the controller using ajax to get the fragment. Every Time I click on the button same fragment gets called but with a different <p> tag innerHTML.

<div id="express" th:fragment="Display">
<p id="app">Include details about your goals</p>
</div>

For the first time, js works very well, split into an array and add span tag but the issue with the new content which is dynamically replaced. The issue is on the javascript side when the new fragments with different innerHTML inside of the <p> tag come the Javascript did not work. I need to refresh the page to re-run the js which I don't want to refresh.

here is the js

let comp = document.getElementById("app").innerHTML; 
let struct = comp.split(" "); 

document.getElementById("app").innerHTML = struct.reduce((acc, word, index) => {
  return `${acc} <span class="word">${word}</span>`;
}, "");

const handleClick = () => {
axios.post(url)
   .then(response => {
       console.log(response.data);
           $("#express").replaceWith($recievedHTML);
   })
   .catch(error => {
       console.log(error);
   });
}

Solution

  • Let's say you have your HTML page, which has your JS file or you have added your JS inside <script> tag directly. Something like ...

    <!DOCTYPE HTML>
    <html lang="en-US">
    <head>
        <script src="/path/lib/jquery/3.5.1/jquery.min-dc5e7f18c8d36ac1d3d4753a87c98d0a.js" type="text/javascript"></script>
        <script src="/path/js/your_file.min-cf4fcae72d4468307341eac1012bb6d8.js" type="text/javascript"></script>
    </head>
    <body>
    
        <div id="express" th:fragment="Display">
            <p id="app">Include details about your goals</p>
        </div>
    
    </body>
    </html>
    

    Javascript for this page may look like ...

    $(function() {
    
        function my_load_function() {
            // do your loading procedures here
            // for example I just copied your inline code...
            let comp = document.getElementById("app").innerHTML; 
            let struct = comp.split(" "); 
        
            document.getElementById("app").innerHTML = struct.reduce((acc, word, index) => {
            return `${acc} <span class="word">${word}</span>`;
            }, "");
        
        }
        
        function my_do_something_else_function() {
            // dosomething else over here
        }
        
        const handleClick = () => {
        axios.post(url)
           .then(response => {
               console.log(response.data);
               // what is '$recievedHTML'? should it be response.data?; 
               // ayway, you said replacement works;
               $("#express").replaceWith($recievedHTML);
               // after this call any function again
               my_load_function();
               my_do_something_else_function();
           })
           .catch(error => {
               console.log(error);
           });
        };
        
        // call your loading function first time
        my_load_function();
    
    });
    

    I have put my additional explanation in the comments of JS code. Please note, I just write it directly in SO and didn't even try to run, so there are maybe some typos.