diff --git a/ui/package.json b/ui/package.json
index afe39ed..e06e9fe 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -2,7 +2,7 @@
"name": "web-ui-boilerplate",
"description": "UI boilerplate for websites/webapps using vanilla HTML/CSS/JavaScript, powered by Storybook, bundled by Parcel.",
"author": "basher",
- "version": "4.0.4",
+ "version": "4.0.5",
"license": "ISC",
"repository": {
"type": "git",
diff --git a/ui/src/javascript/utils/ajax-helpers.ts b/ui/src/javascript/utils/ajax-helpers.ts
index 1c5b8fa..194f4da 100644
--- a/ui/src/javascript/utils/ajax-helpers.ts
+++ b/ui/src/javascript/utils/ajax-helpers.ts
@@ -68,16 +68,18 @@ export const ajaxErrorHandler = (arg: AjaxError): void => {
* @param {HTMLElement} ajaxTrigger - element that triggers the Ajax request
* @param {string} eventType - event type that triggers the Ajax request
* @param {Function} ajaxCallback - callback function that handles the Ajax request
+ * * @param {string} ajaxUrl - URL of data to be fetched (e.g. HTML fragment or API endpoint)
* @returns {void}
*/
interface AjaxEvent {
ajaxTrigger: HTMLElement;
eventType: string;
- ajaxCallback: (ajaxContainer: HTMLElement) => void;
+ ajaxCallback: (ajaxContainer: HTMLElement, ajaxUrl: string) => void;
+ ajaxUrl: string;
}
export const ajaxEventHandler = (arg: AjaxEvent): void => {
- const { ajaxTrigger, eventType, ajaxCallback } = arg;
+ const { ajaxTrigger, eventType, ajaxCallback, ajaxUrl } = arg;
// Value of 'data-fetch-trigger' must match 'data-fetch-container' so that an Ajax trigger (e.g. button) loads content into the correct container.
const target = ajaxTrigger?.dataset.fetchTarget;
@@ -88,7 +90,7 @@ export const ajaxEventHandler = (arg: AjaxEvent): void => {
ajaxTrigger.addEventListener(eventType, () => {
if (ajaxContainer) {
ajaxContainer.classList.remove('ajax__error');
- ajaxCallback(ajaxContainer);
+ ajaxCallback(ajaxContainer, ajaxUrl);
}
});
};
diff --git a/ui/src/javascript/web-components/webui-fetch-html.ts b/ui/src/javascript/web-components/webui-fetch-html.ts
index bbba5fc..ced9ad5 100644
--- a/ui/src/javascript/web-components/webui-fetch-html.ts
+++ b/ui/src/javascript/web-components/webui-fetch-html.ts
@@ -6,26 +6,28 @@ import {
export default class WebUIFetchHtml extends HTMLElement {
private fetchTrigger: HTMLButtonElement | null;
+ private fetchUrl: string | undefined;
constructor() {
super();
this.fetchTrigger = this.querySelector('[data-fetch-target]');
+ this.fetchUrl = this.fetchTrigger?.dataset.fetchUrl;
- if (!this.fetchTrigger) return;
+ if (!this.fetchTrigger || !this.fetchUrl) return;
ajaxEventHandler({
ajaxTrigger: this.fetchTrigger,
eventType: 'click',
ajaxCallback: this.handleClick,
+ ajaxUrl: this.fetchUrl,
});
}
- private handleClick(ajaxContainer: HTMLElement): void {
+ private handleClick(ajaxContainer: HTMLElement, ajaxUrl: string): void {
const showAjaxLoader = true;
- // TODO: Add 'data-' attribute on button to specifiy HTML source to be fetched.
- fetch('ajax/ajax.html', {
+ fetch(ajaxUrl, {
method: 'GET',
signal: ajaxAbortHandler({
ajaxContainer,
diff --git a/ui/src/javascript/web-components/webui-predictive-search.ts b/ui/src/javascript/web-components/webui-predictive-search.ts
index a06dce9..fc9a8ce 100644
--- a/ui/src/javascript/web-components/webui-predictive-search.ts
+++ b/ui/src/javascript/web-components/webui-predictive-search.ts
@@ -9,38 +9,41 @@ import searchResults from '../templates/search-results';
export default class WebUIPredictiveSearch extends HTMLElement {
private searchForm: HTMLFormElement | null;
private searchInput: HTMLInputElement | null;
+ private fetchUrl: string | undefined;
constructor() {
super();
this.searchForm = this.querySelector('[role="search"]');
this.searchInput = this.querySelector('[type="search"]');
+ this.fetchUrl = this.searchInput?.dataset.fetchUrl;
- if (!this.searchForm || !this.searchInput) return;
+ if (!this.searchForm || !this.searchInput || !this.fetchUrl) return;
ajaxEventHandler({
ajaxTrigger: this.searchInput,
eventType: 'keyup',
ajaxCallback: this.handleKeyUp,
+ ajaxUrl: this.fetchUrl,
});
this.searchForm.addEventListener('submit', this);
}
- private handleKeyUp = (ajaxContainer: HTMLElement): void => {
+ private handleKeyUp = (
+ ajaxContainer: HTMLElement,
+ ajaxUrl: string,
+ ): void => {
const showAjaxLoader = true;
const query = this.searchInput?.value.toLowerCase();
- // API paths would normally be defined in a global config.
- const API_PATH = 'https://pokeapi.co/api/v2/pokemon?limit=1000';
-
if (!query) {
ajaxContainer.innerHTML = '';
return;
}
if (query && query?.length > 2) {
- fetch(API_PATH, {
+ fetch(ajaxUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
diff --git a/ui/stories/1. Storybook Intro/1-Introduction.mdx b/ui/stories/1. Storybook Intro/1-Introduction.mdx
index ef10c4a..f6e0af8 100644
--- a/ui/stories/1. Storybook Intro/1-Introduction.mdx
+++ b/ui/stories/1. Storybook Intro/1-Introduction.mdx
@@ -5,10 +5,10 @@ import { Meta } from '@storybook/blocks';
# Web UI Boilerplate Storybook
This is an accessible UI boilerplate and component library for websites & webapps.
-It comprises
-- global design system tokens - colours, typography, icons
-- fully functioning UI components and layouts, which can be optionally configured using Storybook's `controls` addon to demonstrate variations in behaviour & layout
-- useful utilities & helpers
+It comprises:
+- Global design system tokens - colours, typography, icons.
+- Fully functioning UI components and layouts, which can be optionally configured using Storybook's `controls` addon to demonstrate variations in behaviour & layout.
+- Useful utilities & helpers.
```
No external frameworks have been harmed in the making of this boilerplate!
diff --git a/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.js b/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.js
index 1cdd4c3..a880750 100644
--- a/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.js
+++ b/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.js
@@ -5,6 +5,7 @@ export const WebUIFetchHtmlHtml = () => `
diff --git a/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.mdx b/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.mdx
index fe78941..9718b1e 100644
--- a/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.mdx
+++ b/ui/stories/6. Web Components Or Custom Elements/WebUI Fetch Html/WebUIFetchHtml.mdx
@@ -23,6 +23,7 @@ Attribute | Behaviour
--- | ---
`data-fetch-target` | Required. On the button that triggers the Fetch request. The value must match `data-fetch-container`.
`data-fetch-container` | Required. On the ARIA live region. The value must match `data-fetch-target`.
+`data-fetch-url` | Required. URL of HTML fragment to be fetched.
## TODO
- Add `data-` attribute on button to specifiy HTML source to be fetched.
diff --git a/ui/stories/6. Web Components Or Custom Elements/WebUI Predictive Search/WebUIPredictiveSearch.js b/ui/stories/6. Web Components Or Custom Elements/WebUI Predictive Search/WebUIPredictiveSearch.js
index ec0d4b1..dae7255 100644
--- a/ui/stories/6. Web Components Or Custom Elements/WebUI Predictive Search/WebUIPredictiveSearch.js
+++ b/ui/stories/6. Web Components Or Custom Elements/WebUI Predictive Search/WebUIPredictiveSearch.js
@@ -10,6 +10,7 @@ export const WebUIPredictiveSearchHtml = () => `
placeholder="Search for a Pokemon"
required
data-fetch-target="search-results"
+ data-fetch-url="https://pokeapi.co/api/v2/pokemon?limit=1000"
/>