The thought process involved in the creation of APEX Template Components

The thought process involved in the creation of APEX Template Components

Whilst the demonstration is similar to Philipp's Progress Bar Template Component blog, I want to use this blog to focus on the thought process involved in the creation of a Template Component.

To emphasize this I've selected a Progress Bar that is on 3 lines of HTML so I can have more time mostly writing about the decisions involved in the process.

Let's start

  1. First. find a UI component that you'd think would be good for APEX. For example, the W3Schools Progress Bar see picture here

  2. The key things I'm seeing here are

    • It looks pretty simple, a couple of <DIV>s to produce a progress bar

    • The classes, specifically the ones that start with w3 are contained in a single CSS file which is imported into the page.

    • I don't think I like that <BR> in there 🙂

    • It's showing multiple progress bars because the HTML is just repeated with different classes and values

  3. The last point is important to how APEX developers should implement this new template component. I have to ask myself some questions

    Should I allow developers to have a single...

    • ...Progress Bar in an Interactive Report column?

    • ....region that shows a single Progress Bar?

If the answer to any of the above bullet points is Yes, then your Template Component is a SINGLE

Regardless of how you answered the above, move on to the next question.

Should I allow developers to create a Region that shows multiple Progress Bars?

If the answer is Yes, then your Template Component is (also) a MULTIPLE

  1. In regards to the W3Schools Progress Bar, my thoughts are: I think it would look
    quite nice in an Interactive Report Column. I also think it would look quite nice to show multiple Progress bars in a Region.... Therefore my Template Component is both a SINGLE and a MULTIPLE. Let's get to work.

  2. In APEX go to Shared Components > Plug-ins > Create > From Scratch > Next

  3. Chose a Name and an Internal Name (like a backward URL)

  4. Next tick both the SINGLE and MULTIPLE because we decided that beforehand

  5. This shows 3 HTML boxes REPORT BODY, REPORT ROW and PARTIAL

  6. Notice I listed them in a different order than the order that's displayed? That's because I truly believe APEX is listing them in the wrong order.

    I know this because it first evaluates the REPORT BODY, then as you can see by #APEX$ROWS#, it evaluates the REPORT ROW. Then as you can see by #APEX$PARTIAL#, it evaluates the PARTIAL

Now, do you see how APEX displays it in the wrong order?

  1. Through this understanding, we determine that our Progress Bar resides within the Report Row's <LI>, which happens to be our PARTIAL... so the PARTIAL is where we are going to embed the code

  2. What I do next is to remove lines 3, 5 & 6 of the PARTIAL - Its just placeholder text and I do this without thinking twice about it.

  3. Now I insert my HTML between the {else/} and {endif/} commands - which are coincidentally, Template Directives. Feel free to read about these in the Universal Theme Application.

    {if APEX$IS_LAZY_LOADING/}
      <div></div>
    {else/}
      <div class="w3-light-grey">
        <div class="w3-container w3-green w3-center" style="width:25%">25%</div>
      </div>
    {endif/}
    
  4. But before we save, we can do better, by adding some placeholders for the colours and percentages.

    {if APEX$IS_LAZY_LOADING/}
      <div></div>
    {else/}
      <div class="w3-light-grey">
        <div class="w3-container w3-#COLOUR# w3-center" style="width:#PERCENT#%">#PERCENT#%</div>
      </div>
    {endif/}
    

    Once you change the above go ahead and click Create Plug-in

  5. The page reloads, scroll down a bit and you see that Custom Attributes have been lifted out of the PARTIAL and created as part of the plugin.

  6. Let's not forget about the CSS... click Files > Create File

  7. Create a file called progress-bar.css and add the following and Save

    @import url("https://www.w3schools.com/w3css/4/w3.css")
    

    Note: For speed, this is directly lifted from the W3Shools demo. Read the end of this article for alternatives

  8. Click on W3Schools Progress Bar in the Breadcrumb to return

  9. Scroll down to the files section and our CSS has been saved and minified.

  10. Our CSS won't be loaded unless we tell the plug-in to load it. Therefore, Copy the Reference of the Minified file to clipboard

    #PLUGIN_FILES#progress-bar#MIN#.css
    
  11. ... and paste it in the File URLs to Load > Cascading Style Sheets section

  12. We are now done with the Template Component, let's go to Page Designer and try it out as a MULTIPLE

  13. Create a Region named Progress Bar with a Type of W3Schools Progress Bar.

  14. For the SQL Source use this (ignore the JSON, I'm just using it for convenience).

    Actually don't ignore it... here is a tip for you, if you want some generated data like this... first ask ChatGPT to provide it in a JSON array, then ask it to give you an Oracle SQL statement to select all rows from it. BINGO - super fast data generation!

    WITH json_data AS (
      SELECT '[
        { "COLOUR": "green", "PERCENT": 35 },
        { "COLOUR": "blue", "PERCENT": 72 },
        { "COLOUR": "red", "PERCENT": 50 }
      ]' AS json_array
      FROM dual
    )
    SELECT
      j.colour,
      j.percent
    FROM
      json_data jd,
      JSON_TABLE(jd.json_array, '$[*]'
        COLUMNS (
          colour VARCHAR2(10) PATH '$.COLOUR',
          percent NUMBER PATH '$.PERCENT'
        )
      ) j
    
  15. Switch to Attributes and assign the Columns to the Placeholders like this

  16. Run the Page and...

  17. Well, it looks ok, but we have to edit the Plug-In again to remove those bullet points. What I usually do is change the <UL> to a <DIV> and <LI> to a <SPAN> like this.

  18. Run again and it's looking a bit condensed, we can sort this out with the APEX Layout Class margin-bottom-sm

  19. Edit the plugin again and add the Class to the PARTIAL and give it a run

    {if APEX$IS_LAZY_LOADING/}
      <div></div>
    {else/}
      <div class="w3-light-grey margin-bottom-sm">
        <div class="w3-container w3-#COLOUR# w3-center" style="width:#PERCENT#%">#PERCENT#%</div>
      </div>
    {endif/}
    
  20. Now we are cooking

    What's important here is that by using an APEX Class, we are starting to adapt the UI Component to APEX. The more APEX classes you use, the more aligned to the Universal Theme it's becoming.

  21. Now let's see it as a SINGLE in an Interactive Report

  22. Create an Interactive Report on the following SQL

    WITH json_data AS (
      SELECT '[
        { "COLOUR": "green", "PERCENT": 35 },
        { "COLOUR": "blue", "PERCENT": 72 },
        { "COLOUR": "red", "PERCENT": 50 }
      ]' AS json_array
      FROM dual
    )
    SELECT
      j.colour || ' ' || j.percent ||'%' Description,
      j.colour,
      j.percent,
      NULL progress_bar
    FROM
      json_data jd,
      JSON_TABLE(jd.json_array, '$[*]'
        COLUMNS (
          colour VARCHAR2(10) PATH '$.COLOUR',
          percent NUMBER PATH '$.PERCENT'
        )
      ) j
    

    This is the same SQL with new DESCRIPTION and PROGRESS_BAR columns

  23. Set COLOUR and PERCENT to be of Type Hidden Column

  24. Set PROGRESS BAR to be

    • Type: W3Schools Progress Bar

    • Colour: COLOUR

    • Percent: PERCENT

  25. Run the page and...

    ... its great when things work the first time

Retrospect

It was important to describe the thought process in both

  • The adaptation of a UI Component, which is not APEX aware, to something that now natively slots into the Universal Theme.

  • SINGLE versus MULTIPLE

Whilst this was achieved in about 30 steps, it's incredibly simple and built in the quickest way possible.

Given another 30 steps, I would...

  • Use more APEX color classes to not limit it to three, but use Theme Colors instead, or allow developers to specify a HEX color code

  • Use my own CSS file rather than linking to a third-party site. This is just asking for trouble

  • Ensure any supplied CSS classes do not clash with APEX classes or those of my application. In the above example, I think classes starting with w3 are somewhat safe.

  • A bunch of testing. i.e. what happens when I have percentages of -35, 3.14, 741... how will these even render?

  • Thoroughly test it in Lazy Loading mode. Luckily this one works fine, but I've had issues with this on others.

  • Add a spinner for Lazy Loading. Tip for you, in the Universal Theme application, go to Icons, find one of the circle-x-8 icons, then add a 5x and Spin Animation, and you have your Lazy Loading spinner right there in the HTML section!

  • Add lots of help text to both the Plug-in & Placeholders

  • Add an Identification class to the Div in the Report Body

  • Add an About URL and Version Number

  • Check if works in other themes (APEX color variables work great here)

Publishing

The apex.world site is great for sharing Template Components. You just need to

  1. Upload your work to a GitHub Repository with a set of files similar to my Cards List UI Template Component

  2. Make a Release on GitHub

  3. Create an apexplugin.json using my example

  4. Thoroughly explain how to use your Template Component in the README.md file. Tip: Use the Markdown Preview feature in VSCode

  5. in apex.world sign in to your account, click Plug-ins, Click Add Plug-in

  6. Paste in your GitHub Project URL and Click Add Plug-in

Final Thoughts

I also create APEX Plugins, and Template Components, for sure are way easier to build and a whole lot of fun. I hope you now feel inspired in some way to create and share your own Template Component Plugins.

What's the picture? It's one-arch, Harrogate, 5 am. Visit Yorkshire