Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Call a component only when it's JS is rendered

Avatar

Level 5

I have implemented a component whose HTML should only render when the JS is executed. The JS is triggered when a button is clicked and then it calls a servlet. The servlet in response returns some values which will be needed in the component's HTML. But the problem is the html of the component renders without the JS execution. It does not show any values but markup is present on the page. Next time, when I click on the button, then the actual execution starts. I want that the HTML of the component should only be rendered when the servlet returns the values after the JS execution.

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Yup, this is fairly simple to implement. Since yo said you never want to render HTML (not even display:none), and only render HTML elements to the DOM after the request is a success, here, you can try my approach below:

Here's what I would do.
Take your target HTML elements that you have in your sightly, and wrap them around with the <script> tag. Using JavaScript templating literals, store it into a JavaScript variable name window.example. Include an HTML-id tag on the component, so that you know where to JavaScript renders HTML elements. 


In your button code, after when the Ajax returns success, you can use the global JavaScript variable window.example to inject HTML into the DOM.

I actually took the time to write you the exact scripts you need. To test this, you have two options:
Option A: just find any AEM component, replace the Sightly HTL and proceed; push code to AEM and test the page

Option B: create a new component and include all the code that I have provided into the Sightly HTL; push code to AEM and test the page

How this works. 

You click on the button on the screen, and after 500 milliseconds, you should be able to see the component's code, JavaScript injected into the dom. 

 

 

 

 

<!--/* The component to inject HTML into */-->
<div id="cmp-badge"></div>

<!--/* The button that you speak of */-->
<button id="example-button">Click Me</button>

<!--/* inline JavaScript Block */-->
<script>
// Using Sightly HTL, build the HTML you want to inject into the cmp-badge element
window.example = `
<div class="cmp-badge">
  <h1>The page name is: ${currentPage.path @ context='unsafe'}</h1>
</div>
`;
// add event listener to the example-button
document.getElementById("example-button").addEventListener("click", function() {
  // some fake API being called and returns success after 500 milliseconds
  setTimeout(function() {
    // add Sightly HTL into the cmp-badge element
    document.getElementById("cmp-badge").innerHTML += window.example;
  }, 500);
});
</script>

 

 

 

View solution in original post

2 Replies

Avatar

Community Advisor

I think what you need is the component to show only when the script is done with a certain execution. I would suggest, instead of manipulating DOM for this, what you can do is:

  • Just add a .hide class to your component by default.
  • Now, when your JS excetcution is complete ( I'm guessing by this you mean a function is your JS which recieves data from the back-end), You can simply remove that hide class from your component.
  • You would need to write CSS for the hide class as display:none.

Through this, you would only need to add 3 lines of code and achieve what you're trying to.

Avatar

Correct answer by
Community Advisor

Yup, this is fairly simple to implement. Since yo said you never want to render HTML (not even display:none), and only render HTML elements to the DOM after the request is a success, here, you can try my approach below:

Here's what I would do.
Take your target HTML elements that you have in your sightly, and wrap them around with the <script> tag. Using JavaScript templating literals, store it into a JavaScript variable name window.example. Include an HTML-id tag on the component, so that you know where to JavaScript renders HTML elements. 


In your button code, after when the Ajax returns success, you can use the global JavaScript variable window.example to inject HTML into the DOM.

I actually took the time to write you the exact scripts you need. To test this, you have two options:
Option A: just find any AEM component, replace the Sightly HTL and proceed; push code to AEM and test the page

Option B: create a new component and include all the code that I have provided into the Sightly HTL; push code to AEM and test the page

How this works. 

You click on the button on the screen, and after 500 milliseconds, you should be able to see the component's code, JavaScript injected into the dom. 

 

 

 

 

<!--/* The component to inject HTML into */-->
<div id="cmp-badge"></div>

<!--/* The button that you speak of */-->
<button id="example-button">Click Me</button>

<!--/* inline JavaScript Block */-->
<script>
// Using Sightly HTL, build the HTML you want to inject into the cmp-badge element
window.example = `
<div class="cmp-badge">
  <h1>The page name is: ${currentPage.path @ context='unsafe'}</h1>
</div>
`;
// add event listener to the example-button
document.getElementById("example-button").addEventListener("click", function() {
  // some fake API being called and returns success after 500 milliseconds
  setTimeout(function() {
    // add Sightly HTL into the cmp-badge element
    document.getElementById("cmp-badge").innerHTML += window.example;
  }, 500);
});
</script>