# Dictionary App

[JS](/web/js.md) ⟩ [Project](/web/js/proj.md) ⟩ Dictionary&#x20;

{% tabs %}
{% tab title="📗 參考" %}

* [x] MakeUseOf ⟩ [Build a Simple Dictionary Application Using JavaScript](https://www.makeuseof.com/build-dictionary-app-using-javascript/)
* [ ] JS.info ⟩ [fetch](https://javascript.info/fetch)
  {% endtab %}

{% tab title="📘 手冊" %}

{% endtab %}

{% tab title="⬆️ 需要" %}

* [Layout System](/web/css/layout/system.md#versions)
  {% endtab %}
  {% endtabs %}

{% tabs %}
{% tab title="csb" %}
{% embed url="<https://codesandbox.io/embed/strange-night-r2glc?fontsize=14&hidenavigation=1&theme=dark>" %}
Dictionary App
{% endembed %}
{% endtab %}

{% tab title="js" %}

```javascript
import { $, $all, log } from './layout/helpers.mjs';

// ------------ event listeners ------------

async function getData() {

  const baseURL = 'https://api.dictionaryapi.dev/api/v2/entries/en/';
  const term = $('.word').value.toLowerCase().trim();
  const url = `${baseURL}${term}`;

  try {
    const response = await fetch(url);
    const data = await response.json();
    displayData(data);
  } catch (error) {
    log(error);
  }
}

$('form').onsubmit = async function (e) {
  e.preventDefault();
  await getData();
};

// click "search" button
$('.search').onclick = async () => {
  await getData();
};

/*
  structure of API response
  -------------------------
  data
   └ 0 (object)
     ├ word: "sheep"
     ├ phonetic: "ʃiːp"
     ├ origin: "Old English scēp, ..."
     ├ meanings (array)
     │     └ 0 (object)
     │       ├ partOfSpeech: "noun" 
     │       └ definitions (array)
     │             ├ 0: {definition: "...", synonyms: [...], antonyms: [...]}
     │             ├ 1: {definition: "...", synonyms: [...], antonyms: [...]}
     │             └ 2: {definition: "...", synonyms: [...], antonyms: [...]}
     │       
     └ phonetics (array)
           └ 0:  {audio: "...", text: "..."}
*/

//
const displayData = (data) => {
  log(data);

  // if main hidden, unhide it.
  const hiddenMain = $('.hidden');
  if (hiddenMain) hiddenMain.classList.remove('hidden');

  // add 'sink' style to every h3
  $all('.app h3').forEach((h3) => h3.classList.add('sink'));

  // part of speech
  $(
    '.term',
  ).innerHTML = `${data[0].word} <span class="sink">${data[0].meanings[0].partOfSpeech}</span>`;

  // definitions
  $('.list').innerHTML = data[0].meanings[0].definitions
    .map((def) => `<li>${def.definition}</li>`)
    .join('');

  // audio
  $(
    '.audio',
  ).innerHTML = `<audio src="${data[0].phonetics[0].audio}" controls>`;
};

```

{% endtab %}

{% tab title="css" %}

```css
@import './layout/layout.css';

/* ---------- page ---------- */

html {
  background: darkkhaki;
}

body {
  max-width: 600px;
  margin: 0.5rem auto;
}

/* ---------- individual elements ---------- */

header {
  gap: 0.5rem;
}

form {
  /* search bar */
  gap: 6px;
}

form * {
  height: 2rem;
  padding: 0 0.5rem;
}

.hs2 {
  /* term */
  align-items: center;
  gap: 1ch;
}

.app {
  gap: 1.5rem;

  margin: 1rem;
  padding: 1rem;
  border: 1px solid black;
  border-radius: 0.5rem;

  background: #eee;
}

main {
  gap: 1rem;

  max-width: 60ch; /* measure */
  border-top: 1px dotted black;
  padding-top: 1.5rem;
}

.term span {
  background: tomato;
  color: white;
}

.list {
  margin-left: 2rem;
}

.sink {
  align-self: flex-start;

  /* display: inline; */
  font-size: calc(1rem - 2px);
  font-weight: bold;

  background: hsl(225 80% 75%);
  /* color: white; */
  padding: 0 6px;
  border: 1px solid black;
  border-radius: 4px;
  box-shadow: 2px 2px 4px rgb(0 0 0 / 0.3) inset;
}

```

{% endtab %}

{% tab title="html" %}

```html
<!-- Dictionary app container -->
<div class="app vcenter">

  <header class="vcenter">
    
    <!-- title -->
    <h2 class="">Dictionary</h2>
    
    <!-- <input> & <button> -->
    <form class="hstack hs1">
      <input class="word" placeholder="Enter the word" />
      <input type="submit" class="search" value="Search" />
    </form>
    
  </header>

  <main class="hidden vstack">

    <!-- part of speech -->
    <div id="partOfSpeechDiv" class="hstack hs2">
      <h3>Term</h3>
      <p class="term"></p>
    </div>
    
    <!-- definitions -->
    <div class="vstack">
      <h3>Meanings</h3>
      <ul class="list"></ul>
    </div>
    
    <!-- audio -->
    <div class="vstack">
      <h3>Audio</h3>
      <div class="audio"></div>
    </div>

  </main>
</div>
```

{% endtab %}

{% tab title="⬆️ 需要" %}

* CSS ⟩ [Layout System](/web/css/layout/system.md#versions)
  {% endtab %}

{% tab title="💾 程式" %}

* codepen ⟩ [dictionary app](https://codepen.io/lochiwei/pen/qBXBKZo?editors=1000)
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lochiwei.gitbook.io/web/js/proj/dictionary-app.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
