Hide menu
Valid for: HT24

Assignment 4

The fourth and final assignment in this course consists of three exercises where you will be creating web components.

Submit your completed assignment before the deadline. Submission instructions can be found on the main assignment page.

Learning outcomes

After this lab assignment, you should have gained knowledge about the following:

  • How to create Web Components
  • How to dispatch synthetic events
  • How ARIA attributes are used

Assignment points

Exercises 1 and 2 have optional tasks.

  • 1 point: Complete all required tasks.
  • 2 points: Complete all required tasks and one optional task.

General requirements

Create a folder the assignment and a sub-folder for each exercise.

Exercise 1 - Your first Web Component

Required task

Create a Web Component (<info-message> that displays an informational message using slots for the title and message. In this exercise you will also be using the open source icon library Fork Awesome.

There are prepared files for this assignment: a4e1.zip

These zip-file contains

  • a4e1.html, the web page that uses two <info-message> web components
  • a4e1.css, the CSS file for a4e1.html and
  • infomessage.js, an empty file where you are supposed to define the web component

Visuals

Below is an image of how your web component should look like. It uses an icon from the Fork Awesome library (see below for information on how to use Fork Awesome icons).

Assignment 4, Exercise 1

HTML (a4e1.html)

Keep the original contents of the a4e1.html file. You only need to add the link to the Fork Awesome css (see below). The HTML uses the <info-message> web component that you need to define.

HTML Template for the web component

Use the following HTML as template for the web component, i.e. use is when you define your template in infomessage.js. Refer to the lecture slides for an outline for defining a custom element/web component.

<div class="infobox">
  <div class="heading">
    <div class="icon center">
      <i class="fa fa-info-circle fa-lg fa-inverse fa-fw" aria-hidden="true"></i>
    </div>
    <div class="title">
      <p><slot name="title">TITLE GOES HERE</slot></p>
    </div>
  </div>
  <div class="message">
    <slot name="message">MESSAGE</slot>
  </div>
</div>

Using Fork Awesome

You can either link to the Fork Awesome stylesheet via their CDN (Content Delivery Network), or download the library and link to the local file (fork-awesome.min.css).

If you use the CDN version use the code below. You will need to link to if both from your HTML Template and the main page (a4e1.html) for the icons to work.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css" integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">

If you download and use a local version, you must keep the folder structure intact (the css file refers to the folder ../fonts for the fonts).

The template HTML code above uses the fa-info-circle icon. You can read more about how to use Fork Awesome icons on their web site: Fork Awesome Examples.

Exercise 2 - Toggle button

Required task

Create a <toggle-button> Web Component that toggles on/off when clicked. The <toggle-button> should also fire an input event when its value changes. The current value should be accessible via its .value property.

There are prepared files for this assignment: a4e2.zip

The zip-file contains

  • a4e2.html, the page that uses four <toggle-button> elements
  • a4e2.css, the CSS for a4e2.html
  • a4e2.js, javascript that listens for input events from the <toggle-button> elements and displays their values
  • toggle-button.js, an empty file where you are supposed to define the <toggle-button> web component

Visuals

a4e1.html should look something like this when you have created the CSS for the toggle widget.

Below is an image of what it should look like after you have toggled widget 2 and 4.

ARIA attributes

The two relevant ARIA attributes for the <toggle-button> are the role and the aria-pressed attributes. The clickable web component HTML should have role="button" as it functions as a two state button. The attribute aria-pressed should be set as "false" if the button is in its “off”-state, and set to “true” when the button is in its “on”-state.

HTML (a4e2.html)

In a4e2.html you can see the toggle-button elements which are the custom elements you have to implement, e.g.

<toggle-button label="Toggle 1"></toggle-button>

HTML Template for the web component

Use the following as the template for your web component:

<div class="wrapper">
  <p>label text</p>
  <div class="toggle" aria-pressed="false"></div>
</div>

The label text should be replaced by the text in the label attribute of the custom element when the custom element is created. The value of the ARIA attribute aria-pressed should reflect the state of the <toggle-button> (see Behavior below).

Behavior

Implement the ability for toggling the color of the widget between white and green. When the widget is white, its value should be 0. I.e. console.log((toggleButton.value) should print out 0. The value when showing green should be 1.

This means your class should have an instance variable with the name value that stores the value of the button (0 or 1).

Also change the value of the attribute aria-pressed accordingly (more info: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role).

Fire input events

The web component should also fire input events when the user clicks it that bubble. See the lecture slides, and the following two pages for more info:

Optional task 1

Note: If you complete Optional task 1 you need to submit both the required and optional task. Make a copy of a4e2.html and name it a4e2-optional.html and copy toggle-button.js to toggle-button-optional.js and use that for the optional task.

For Optional task 1 allow the user to specify two images that are used to show the state of the <toggle-button>:

<toggle-button label="Toggle 1" pressed="green.png" not-pressed="red.png"></toggle-button>

Change the use of the custom elements in a4e2-optional.html to reflect the code above.

If you implement the optional task, red.png should be shown initially. When the user clicks on the widget, green.png should be shown. Clicking again switches the images.

You can use these image URL:s if you do not want to use your own images:

Exercise 3 - Accordion

Required task

Create an <accortion-component> web component that contains headings with expandable content.

There are prepared files for this assignment: a4e3.zip

The zip-file contains

  • a4e3.html, web page that uses the <accordion-component> web component
  • a4e3.css, the CSS for a4e3.html
  • accordion.js, an empty file where you are supposed to define the <accordion-component> web component

Visuals

a4e2.html should look something like this when you have created the CSS for the accordion widget.

Tip: You can use the CSS below to add different triangles when the accordian is opened and closed.

.accordion button::before {
  content: "▶︎ ";
}

.accordion button[aria-expanded="true"]::before {
  content: "▼︎ ";
}

ARIA attributes

  • Role The element containing the content of an accordion panel has role="region"
  • State When a button’s content div is visible, the value of the button’s aria-expanded attribute should be true. When its content div is not visible, the button’s aria-expanded value should be set to false.
  • Relationship You are not required to apply these attributes for the assignment.
    • aria-controls: this attribute is set on a button and and its value is the id of the content div it controls the visibility of
    • aria-labelledby: this attribute is set on a content div and its value is the id of the button it belongs to.
  • Misc An element with the hidden attribute will not be visible in the browser, nor will it be read by any assistive technologies. Because of this, the hidden attribute is often used when creating accessible UI components rather than just setting display: none. Just setting display: none will hide it from seeing users, but it may still be read by some assistive tools.

HTML (a4e3.html)

The idea here, is to let the user write only what is necessary from a content author’s perspective. Here is the HTML that is the user is required to write.

<accordion-component>
  <h2>Accordion 1 title</h2>
  <div><p>Content for Accordion 1<p></div>

  <h2>Accordion 2 title</h2>
  <div><p>Content for Accordion 2<p></div>

  <h2>Accordion 3 title</h2>
  <div><p>Content for Accordion 3<p></div>
</accordion-component>

HTML Template for the web component

Use the following HTML as the template for your web component:

<div class="accordion">
  <ul>
  </ul>
</div>

You will need to create elements using JavaScript to put the content of the web component into the appropriate elements in the shadow DOM. This is what the final shadow DOM should look like for the <accordion-component> example above.

<div class="accordion">
  <ul>
    <li>
       <button aria-expanded="false">Accordion 1 title</button>
       <div role="region" hidden=""><p>Content for Accordion 1</p></div>
    </li>
    <li>
      <button aria-expanded="false">Accordion 2 title</button>
      <div role="region" hidden=""><p>Content for Accordion 2</p></div>
    </li>
    <li>
      <button aria-expanded="false">Accordion 3 title</button>
      <div role="region" hidden=""><p>Content for Accordion 3</p></div>
    </li>
  </ul>
</div>

Important: Some methods and properties, e.g. element.children and document.getElementsByClassName() return a live HTMLCollection. “Live” means that any changes to the DOM will be immediately reflected in the HTMLCollection. If you intend to move any elements in the HTMLCollection to a new place in the DOM, do NOT do this from inside of a e.g. a for-loop where you are using indexes. Instead, copy the elements to an array and loop through the array: let myElements = Array.from(myHTMLCollection) and loop over the array.

If you try to loop over a live HTMLCollection of e.g. the children of a node and move any of the children to another place in the DOM, the HTMLCollection will shrink and you will have a smaller HTMLCollection than you initially had.

Note: You cannot change the tagName of a DOM node, e.g. you cannot change a h2 to a button. Instead you have to create a new button element, then copy the .innerHTML and optionally destroy the h2 element (use element.remove()).

Behavior

  • If an unexpanded accordion title is clicked, its content is revealed (remove the hidden attribute) and the value of the title’s aria-expanded attribute is set to "true".
  • If a expanded accordion title is clicked, its content is hidden (add the hidden attribute) and the value of the title’s aria-expanded attribute is set to "false".
  • There are no dependencies between accordions, i.e. any number of accordions may be opened or closed at the same time.

Optional Task 2

  • Animate the accordions opening and closing using anime.js

Page contact: Johan Falkenjack
Last update: 2022-12-02