> For the complete documentation index, see [llms.txt](https://developers.laws.africa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.laws.africa/tutorials/module-1-build-a-legislation-reader/adding-interactivity.md).

# Adding interactivity

Adding some basic interactivity using Law Widgets.

## In this section

* Add a searchable Table of Contents using Law Widgets
* Add interactivity with Law Widgets for defined terms and internal references

Now that we have a detail page showing the content of the documents, let's add some interactivity using Laws.Africa's [Law Widgets](https://github.com/laws-africa/law-widgets).

## Table of Contents

A searchable Table of Contents is important to make long legislative documents easier to navigate. There are two widgets you can use for the Table of Contents:

* [\<la-table-of-contents>](https://github.com/laws-africa/law-widgets/blob/main/core/src/components/table-of-contents/readme.md) - this is a basic Table of Contents tree.
* [\<la-table-of-contents-controller>](https://github.com/laws-africa/law-widgets/blob/main/core/src/components/table-of-contents-controller/readme.md) - this is a fully searchable and collapsible Table of Contents tree that builds on top of \<la-table-of-contents>.

We'll use la-table-of-contents-controller because it gives us rich functionality right out the box.

Let's divide our content section into two columns to make room for the Table of Contents in a sidebar on the left of the page.

{% code title="expression\_detail.html" %}

```html
<html>
<head>
  <title>{{ expression.title }}</title>
  <!-- add the law widgets javascript -->
  <script
    type="module"
    src="https://cdn.jsdelivr.net/npm/@lawsafrica/law-widgets@latest/dist/lawwidgets/lawwidgets.esm.js"
  ></script>
</head>
<body>
  <a href="{% url 'home' %}">Home</a>

  <h1>{{ expression.title }}</h1>

  <div style="display: flex">
    <aside style="flex: 1">
      <la-table-of-contents-controller
        items="{{ toc_json }}"
        style="position: sticky; top: 0; max-height: 100vh; overflow-y: auto;"
      ></la-table-of-contents-controller>
    </aside>

    <div style="flex: 3">
      <!-- use la-akoma-ntoso law widget to apply styles -->
      <la-akoma-ntoso frbr-expression-uri="{{ expression.frbr_uri }}">
        {{ expression.content|safe }}
      </la-akoma-ntoso>
    </div>
  </div>
</body>
```

{% endcode %}

We need to provide the `<la-table-of-contents-controller>` with the JSON Table of Contents data in the items attribute. This is the data that is provided by the Laws.Africa Content API.

Update the `views.py` to add turn the TOC information into JSON.

{% code title="views.py" %}

```python
import json

# ...

class ExpressionDetailView(DetailView):
    model = Expression
    slug_field = 'frbr_uri'
    slug_url_kwarg = 'frbr_uri'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['toc_json'] = json.dumps(self.object.toc_json['toc'])
        return context
```

{% endcode %}

The page now has an interactive table of contents.

## Popups for defined terms

We're going to use the [\<la-decorate-terms>](https://github.com/laws-africa/law-widgets/blob/main/core/src/components/decorate-terms/readme.md) Law Widget to add popups for defined terms that occur in a document.

<figure><img src="https://4163728571-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LrrJ5L0RJ3goKWzqKVC%2Fuploads%2Fq7oiMgvNEyHSQqwJ6DFb%2Fimage.png?alt=media&amp;token=021d5dd4-4e24-400c-be7f-34c917a8d162" alt=""><figcaption></figcaption></figure>

Modify `expression_detail.html` to include the new widget anywhere on the page:

<pre class="language-html" data-title="expression_detail.html"><code class="lang-html">...
<strong>&#x3C;la-decorate-terms popup-definitions link-terms>&#x3C;/la-decorate-terms>
</strong>&#x3C;la-akoma-ntoso ...>...&#x3C;/la-akoma-ntoso>
...
</code></pre>

This widget will add term definition popups and links in the first `<la-akoma-ntoso>` element on the page. If there is more than one, you can target it specifically by providing an **akoma-ntoso** attribute that uses a CSS selector to identify the target element: `<la-decorate-terms akoma-ntoso="#akn-doc">`.

You can control the behaviour by adding or removing these attributes. Try changing them and refreshing the page to see what changes.

* `popup-definitions` - controls whether definitions of terms are shown in popups
* `link-terms` - controls whether references to terms are shown as clickable links.

## Popups for internal references

We're going to use the [\<la-decorate-internal-refs>](https://github.com/laws-africa/law-widgets/blob/main/core/src/components/decorate-internal-refs/readme.md) widget to make internal references more interactive. The widget will show a purple bookmark at an internal reference, and show the content of the target element when the user hovers over the reference.

<figure><img src="https://4163728571-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LrrJ5L0RJ3goKWzqKVC%2Fuploads%2FycyOzwTyqqCngQOm1Oxm%2Fimage.png?alt=media&amp;token=2bf830cd-3c76-4152-bb3a-664c23aa67f5" alt=""><figcaption></figcaption></figure>

Modify `expression_detail.html` to include the new widget:

{% code title="expression\_detail.html" %}

```html
...
<la-decorate-internal-refs popups flag></la-decorate-internal-refs>
<la-akoma-ntoso ...>...</la-akoma-ntoso>
...
```

{% endcode %}

This widget will add interactivity to internal references in the first `<la-akoma-ntoso>` element on the page. Like with `<la-decorate-terms>` , you can use the **akoma-ntoso** attribute to target a specific `<la-akoma-ntoso>` element using a CSS selector, such as `<la-decorate-internal-refs akoma-ntoso="#akn-doc">`.

You can control the behaviour by adding or removing these attributes. Try changing them and refreshing the page to see what changes.

* `popups` - controls whether reference target elements are shown in popups
* `flag` - controls whether internal references are decorated with a purple bookmark icon


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developers.laws.africa/tutorials/module-1-build-a-legislation-reader/adding-interactivity.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
