1

I'm trying to use the government design system with angular but not having a great deal of success (GDS). I've gone down the route of using the pre-compiled files rather than npm and styling-wise things are working. But functionality-wise not so much.

I've included the javascript file in my index.html and am not getting any console errors

<!doctype html>
<html lang="en" class="govuk-template ">
<head>
  <meta charset="utf-8">
  <title>Explosives</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body class="govuk-template__body ">
  <script>
    document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');
  </script>
  <app-root></app-root>
  <script src="/assets/js/govuk-frontend-4.4.1.min.js"></script>
  <script>
    window.GOVUKFrontend.initAll()
  </script>
</body>
</html>

I've tried to use Tabs and Accordion components but they don't behave like they should. Accordion is showing the sections but not giving me any option to show or hide My Accordion when it should look like this GDS Accordion

And my Tabs Panel looks perfect My Tabs Panel But clicking the tabs only adds a hash to the url and nothing changes with the tabs when it should behave like this example. GDS Tabs

I was using this article as a guide. But it only got me so far (Stack Overflow)

I can only think the javascript file isn't being included properly but I'm at a loss as to what else I can try.

Debugging Steps

  1. create a new angular app using the Angular CLI
  2. download the following files from GDS
  • govuk-frontend-4.4.1.min.css
  • govuk-frontend-4.4.1.min.js
  1. add the files to the specific folders
  • src/assets/css
  • src/assets/js
  1. update angular.json to include these files
            "styles": [
              "src/styles.css",
              "src/assets/css/govuk-frontend-4.4.1.min.css"
            ],
            "scripts": [
              "src/assets/js/govuk-frontend-4.4.1.min.js"
            ]
  1. update index.html
<!doctype html>
<html lang="en" class="govuk-template ">
<head>
  <meta charset="utf-8">
  <title>Explosives</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body class="govuk-template__body ">
  <script>
    document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');
  </script>
  <app-root></app-root>
  <script src="/assets/js/govuk-frontend-4.4.1.min.js"></script>
  <script>
    window.GOVUKFrontend.initAll()
  </script>
</body>
</html>
  1. create a new component using the angular cli ng g c tabs
  2. update new component html
<div class="govuk-tabs" data-module="govuk-tabs">
    <h2 class="govuk-tabs__title">
      Contents
    </h2>
    <ul class="govuk-tabs__list">
      <li class="govuk-tabs__list-item govuk-tabs__list-item--selected">
        <a class="govuk-tabs__tab" href="#past-day">
          Past day
        </a>
      </li>
      <li class="govuk-tabs__list-item">
        <a class="govuk-tabs__tab" href="#past-week">
          Past week
        </a>
      </li>
      <li class="govuk-tabs__list-item">
        <a class="govuk-tabs__tab" href="#past-month">
          Past month
        </a>
      </li>
      <li class="govuk-tabs__list-item">
        <a class="govuk-tabs__tab" href="#past-year">
          Past year
        </a>
      </li>
    </ul>
    <div class="govuk-tabs__panel" id="past-day">
      <h2 class="govuk-heading-l">Past day</h2>
      <table class="govuk-table">
        <thead class="govuk-table__head">
          <tr class="govuk-table__row">
            <th scope="col" class="govuk-table__header">Case manager</th>
            <th scope="col" class="govuk-table__header">Cases opened</th>
            <th scope="col" class="govuk-table__header">Cases closed</th>
          </tr>
        </thead>
        <tbody class="govuk-table__body">
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">David Francis</td>
            <td class="govuk-table__cell">3</td>
            <td class="govuk-table__cell">0</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Paul Farmer</td>
            <td class="govuk-table__cell">1</td>
            <td class="govuk-table__cell">0</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Rita Patel</td>
            <td class="govuk-table__cell">2</td>
            <td class="govuk-table__cell">0</td>
          </tr>
        </tbody>
      </table>
    </div>
    <div class="govuk-tabs__panel govuk-tabs__panel--hidden" id="past-week">
      <h2 class="govuk-heading-l">Past week</h2>
      <table class="govuk-table">
        <thead class="govuk-table__head">
          <tr class="govuk-table__row">
            <th scope="col" class="govuk-table__header">Case manager</th>
            <th scope="col" class="govuk-table__header">Cases opened</th>
            <th scope="col" class="govuk-table__header">Cases closed</th>
          </tr>
        </thead>
        <tbody class="govuk-table__body">
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">David Francis</td>
            <td class="govuk-table__cell">24</td>
            <td class="govuk-table__cell">18</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Paul Farmer</td>
            <td class="govuk-table__cell">16</td>
            <td class="govuk-table__cell">20</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Rita Patel</td>
            <td class="govuk-table__cell">24</td>
            <td class="govuk-table__cell">27</td>
          </tr>
        </tbody>
      </table>
    </div>
    <div class="govuk-tabs__panel govuk-tabs__panel--hidden" id="past-month">
      <h2 class="govuk-heading-l">Past month</h2>
      <table class="govuk-table">
        <thead class="govuk-table__head">
          <tr class="govuk-table__row">
            <th scope="col" class="govuk-table__header">Case manager</th>
            <th scope="col" class="govuk-table__header">Cases opened</th>
            <th scope="col" class="govuk-table__header">Cases closed</th>
          </tr>
        </thead>
        <tbody class="govuk-table__body">
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">David Francis</td>
            <td class="govuk-table__cell">98</td>
            <td class="govuk-table__cell">95</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Paul Farmer</td>
            <td class="govuk-table__cell">122</td>
            <td class="govuk-table__cell">131</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Rita Patel</td>
            <td class="govuk-table__cell">126</td>
            <td class="govuk-table__cell">142</td>
          </tr>
        </tbody>
      </table>
    </div>
    <div class="govuk-tabs__panel govuk-tabs__panel--hidden" id="past-year">
      <h2 class="govuk-heading-l">Past year</h2>
      <table class="govuk-table">
        <thead class="govuk-table__head">
          <tr class="govuk-table__row">
            <th scope="col" class="govuk-table__header">Case manager</th>
            <th scope="col" class="govuk-table__header">Cases opened</th>
            <th scope="col" class="govuk-table__header">Cases closed</th>
          </tr>
        </thead>
        <tbody class="govuk-table__body">
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">David Francis</td>
            <td class="govuk-table__cell">1380</td>
            <td class="govuk-table__cell">1472</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Paul Farmer</td>
            <td class="govuk-table__cell">1129</td>
            <td class="govuk-table__cell">1083</td>
          </tr>
          <tr class="govuk-table__row">
            <td class="govuk-table__cell">Rita Patel</td>
            <td class="govuk-table__cell">1539</td>
            <td class="govuk-table__cell">1265</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  1. import the new component into the app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { TabsComponent } from './tabs/tabs.component';

@NgModule({
  declarations: [
    AppComponent,
    TabsComponent,
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. update app.component.html to include GDS code
<header class="govuk-header " role="banner" data-module="govuk-header">
  <div class="govuk-header__container govuk-width-container">
    <div class="govuk-header__logo">
      <a href="/" class="govuk-header__link govuk-header__link--homepage">
        <span class="govuk-header__logotype">
          <!--[if gt IE 8]><!-->
          <svg aria-hidden="true" focusable="false" class="govuk-header__logotype-crown" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 97" height="30" width="36">
            <path fill="currentColor" fill-rule="evenodd" d="M25 30.2c3.5 1.5 7.7-.2 9.1-3.7 1.5-3.6-.2-7.8-3.9-9.2-3.6-1.4-7.6.3-9.1 3.9-1.4 3.5.3 7.5 3.9 9zM9 39.5c3.6 1.5 7.8-.2 9.2-3.7 1.5-3.6-.2-7.8-3.9-9.1-3.6-1.5-7.6.2-9.1 3.8-1.4 3.5.3 7.5 3.8 9zM4.4 57.2c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.5-1.5-7.6.3-9.1 3.8-1.4 3.5.3 7.6 3.9 9.1zm38.3-21.4c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.6-1.5-7.6.3-9.1 3.8-1.3 3.6.4 7.7 3.9 9.1zm64.4-5.6c-3.6 1.5-7.8-.2-9.1-3.7-1.5-3.6.2-7.8 3.8-9.2 3.6-1.4 7.7.3 9.2 3.9 1.3 3.5-.4 7.5-3.9 9zm15.9 9.3c-3.6 1.5-7.7-.2-9.1-3.7-1.5-3.6.2-7.8 3.7-9.1 3.6-1.5 7.7.2 9.2 3.8 1.5 3.5-.3 7.5-3.8 9zm4.7 17.7c-3.6 1.5-7.8-.2-9.2-3.8-1.5-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.3 3.5-.4 7.6-3.9 9.1zM89.3 35.8c-3.6 1.5-7.8-.2-9.2-3.8-1.4-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.4 3.6-.3 7.7-3.9 9.1zM69.7 17.7l8.9 4.7V9.3l-8.9 2.8c-.2-.3-.5-.6-.9-.9L72.4 0H59.6l3.5 11.2c-.3.3-.6.5-.9.9l-8.8-2.8v13.1l8.8-4.7c.3.3.6.7.9.9l-5 15.4v.1c-.2.8-.4 1.6-.4 2.4 0 4.1 3.1 7.5 7 8.1h.2c.3 0 .7.1 1 .1.4 0 .7 0 1-.1h.2c4-.6 7.1-4.1 7.1-8.1 0-.8-.1-1.7-.4-2.4V34l-5.1-15.4c.4-.2.7-.6 1-.9zM66 92.8c16.9 0 32.8 1.1 47.1 3.2 4-16.9 8.9-26.7 14-33.5l-9.6-3.4c1 4.9 1.1 7.2 0 10.2-1.5-1.4-3-4.3-4.2-8.7L108.6 76c2.8-2 5-3.2 7.5-3.3-4.4 9.4-10 11.9-13.6 11.2-4.3-.8-6.3-4.6-5.6-7.9 1-4.7 5.7-5.9 8-.5 4.3-8.7-3-11.4-7.6-8.8 7.1-7.2 7.9-13.5 2.1-21.1-8 6.1-8.1 12.3-4.5 20.8-4.7-5.4-12.1-2.5-9.5 6.2 3.4-5.2 7.9-2 7.2 3.1-.6 4.3-6.4 7.8-13.5 7.2-10.3-.9-10.9-8-11.2-13.8 2.5-.5 7.1 1.8 11 7.3L80.2 60c-4.1 4.4-8 5.3-12.3 5.4 1.4-4.4 8-11.6 8-11.6H55.5s6.4 7.2 7.9 11.6c-4.2-.1-8-1-12.3-5.4l1.4 16.4c3.9-5.5 8.5-7.7 10.9-7.3-.3 5.8-.9 12.8-11.1 13.8-7.2.6-12.9-2.9-13.5-7.2-.7-5 3.8-8.3 7.1-3.1 2.7-8.7-4.6-11.6-9.4-6.2 3.7-8.5 3.6-14.7-4.6-20.8-5.8 7.6-5 13.9 2.2 21.1-4.7-2.6-11.9.1-7.7 8.8 2.3-5.5 7.1-4.2 8.1.5.7 3.3-1.3 7.1-5.7 7.9-3.5.7-9-1.8-13.5-11.2 2.5.1 4.7 1.3 7.5 3.3l-4.7-15.4c-1.2 4.4-2.7 7.2-4.3 8.7-1.1-3-.9-5.3 0-10.2l-9.5 3.4c5 6.9 9.9 16.7 14 33.5 14.8-2.1 30.8-3.2 47.7-3.2z"></path>
          </svg>
          <!--<![endif]-->
          <!--[if IE 8]>
        <img src="/assets/images/govuk-logotype-crown.png" class="govuk-header__logotype-crown-fallback-image" width="36" height="32">
        <![endif]-->
          <span class="govuk-header__logotype-text">
            GOV.UK
          </span>
        </span>
      </a>
    </div>
  </div>
</header>
<div class="govuk-width-container ">
  <main class="govuk-main-wrapper " id="main-content" role="main">
    <app-tabs></app-tabs>
  </main>
</div>
<footer class="govuk-footer " role="contentinfo">
  <div class="govuk-width-container ">
    <div class="govuk-footer__meta">
      <div class="govuk-footer__meta-item govuk-footer__meta-item--grow">
        <svg aria-hidden="true" focusable="false" class="govuk-footer__licence-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 483.2 195.7" height="17" width="41">
          <path fill="currentColor" d="M421.5 142.8V.1l-50.7 32.3v161.1h112.4v-50.7zm-122.3-9.6A47.12 47.12 0 0 1 221 97.8c0-26 21.1-47.1 47.1-47.1 16.7 0 31.4 8.7 39.7 21.8l42.7-27.2A97.63 97.63 0 0 0 268.1 0c-36.5 0-68.3 20.1-85.1 49.7A98 98 0 0 0 97.8 0C43.9 0 0 43.9 0 97.8s43.9 97.8 97.8 97.8c36.5 0 68.3-20.1 85.1-49.7a97.76 97.76 0 0 0 149.6 25.4l19.4 22.2h3v-87.8h-80l24.3 27.5zM97.8 145c-26 0-47.1-21.1-47.1-47.1s21.1-47.1 47.1-47.1 47.2 21 47.2 47S123.8 145 97.8 145" />
        </svg>
        <span class="govuk-footer__licence-description">
          All content is available under the
          <a class="govuk-footer__link" href="https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/" rel="license">Open Government Licence v3.0</a>, except where otherwise stated
        </span>
      </div>
      <div class="govuk-footer__meta-item">
        <a class="govuk-footer__link govuk-footer__copyright-logo" href="https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/">© Crown copyright</a>
      </div>
    </div>
  </div>
</footer>
  1. run the app using npm start

You'll see that the tab component isn't working as expected

jdez
  • 57
  • 1
  • 7
  • So you say instead of using the npm (which I would suggest you stick with the npm unless you have a real reason not to, as it makes maintenance etc easier) but did you include the files in question that you need in your "Scripts" declarations in your `angular.json` file for your build configurations to ensure the file(s) is even included in the project on build? – Chris W. Jan 19 '23 at 15:59
  • I have included the file in the scripts section of angular.json yeah. The file is currently located at `src/assets/js/govuk-frontend-4.4.1.min.js` – jdez Jan 19 '23 at 16:03
  • So when you build your project, and you inspect the source, do you see that file referenced in the html document somewhere to ensure it's beeing added and you have your file path correct? You'll probably have a 404 Not found error in your console if not. – Chris W. Jan 19 '23 at 16:05
  • ` – jdez Jan 19 '23 at 16:13
  • Well you include the scripts in your angular.json file so it bundles them up with the other bundles of your project when you do a build and can be handled with lazy loading etc. Or you can declare `inject: false` additionally when you declare the script file and it will NOT include it in the bundles and both retain the external file AND add the reference links to index html for you. You may also need to actually import that library you mention explicitly into your project via the .ts in some way. Like import * as any GovUkFrontend or something. – Chris W. Jan 19 '23 at 16:49
  • I have also tried using the `{ "input": ..., "inject":false, "bundleName": "govuk" }` and then replacing the src in index.html with just govuk.js. The file gets created and I still don't get any console errors, but it works the same as before. – jdez Jan 19 '23 at 16:59
  • Ya sorry dude but it's tough to troubleshoot without being able to look under the hood, know what I mean? If you can view the file through the path you're supplying like yoursite.com/ or `localhost:1234/the/file/path/to/file.js` and you can see the script there, and you have it referenced in your index and you see the reference is correct, I'd need more info since I'm not familiar with the package....but, their instructions seem straight forward enough on [their documentation](https://frontend.design-system.service.gov.uk/install-using-precompiled-files/#install-using-precompiled-files) – Chris W. Jan 19 '23 at 17:30
  • Appreciate the effort. It's a fiddly problem. And annoying it takes quite a few steps to duplicate as well. – jdez Jan 20 '23 at 09:58

1 Answers1

0

Figured out a solution, though may be a bit of a workaround. I removed the script tags from index.html, and instead am relying on the scripts array in angular.json to handle all the javascript.

I am now using the javascript file from the node_module folder; though it should work the same with the min.js file I had before.

Also created an extra js file, which would literally just run the initAll() method

// govuk-init.js
document.addEventListener("DOMContentLoaded", function(event) {
    window.GOVUKFrontend.initAll();
})
// angular.json
"scripts": [
  "node_modules/govuk-frontend/govuk/all.js",
  "src/assets/js/govuk-init.js"
]

This way I know the initAll method will definitely run after all the other code has been run, and it seems to function correctly now.

Thremulant
  • 566
  • 5
  • 15
jdez
  • 57
  • 1
  • 7