Skip to content

Commit

Permalink
Merge pull request #351 from CodeYourFuture/js3-week1/prep
Browse files Browse the repository at this point in the history
Rewrite JS3 week 1 prep
  • Loading branch information
Dedekind561 authored Nov 9, 2023
2 parents 6cfa87d + 2a6a8ce commit 7485afd
Show file tree
Hide file tree
Showing 13 changed files with 398 additions and 35 deletions.
11 changes: 0 additions & 11 deletions content/js3/blocks/block1/index.md

This file was deleted.

11 changes: 0 additions & 11 deletions content/js3/blocks/block2/index.md

This file was deleted.

11 changes: 0 additions & 11 deletions content/js3/blocks/block3/index.md

This file was deleted.

81 changes: 81 additions & 0 deletions content/js3/blocks/components/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
+++
title = '🃏 Building a component'
headless = true
time = 30
facilitation = false
emoji= '🧩'
[objectives]
1='Implement components for a user interface'
+++

Recall our sub-goal:

> 🎯 Sub-goal: Build a film card component
We can render _any_ film object in the user interface with a general component. We've composed DOM elements to create a card; now we will build a **reusable component**. To do this, we wrap up our code inside a JavaScript function. JavaScript functions **reuse code**: so we can implement **reusable UI components** using functions.

Look at our code so far:

```js
const film = {
title: "Killing of Flower Moon",
director: "Martin Scoresese"
times: ["15:35"],
certificate: "15",
duration: 112
};

const filmCard = document.createElement("section");
filmCard.innerHTML = `
<p>${film.title}</p>
`;
console.log(filmCard);
```

We can wrap up some of this code to create our reusable film card component:

```js
function createFilmCard(film) {
const card = document.createElement("section");
card.innerHTML = `
<p>${film.title}</p>
`;
return card;
}

const film1 = {
title: "Killing of Flower Moon",
director: "Martin Scorsese"
times: ["15:35"],
certificate: "15",
duration: 112
};

const film2 = {
title: "Typist Artist Pirate King",
director: "Carol Morley"
times: ["15:00", "20:00"],
certificate: "12A",
duration: 108
};

document
.querySelector("ul")
.append(createFilmCard(film1),createFilmCard(film2)); // append the film cards to the DOM
```

{{<tabs>}}

{{<tab name="🔧 Implement">}}

Update the implementation of `createFilmCard` so it renders other film properties. Other film properties on this object are `director`, `times`, `certificate` and `duration`.

{{</tab>}}

{{<tab name="🧹 Refactor">}}

Refactor the `createFilmCard` function to use object destructuring in the parameters.

{{</tab>}}

{{</tabs>}}
51 changes: 51 additions & 0 deletions content/js3/blocks/composing-elements/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
+++
title = '🧱 Composing elements'
headless = true
time = 20
facilitation = false
emoji= '🧩'
[objectives]
1='Compose UI elements to some specification'
2='Append DOM elements to other nodes in the DOM tree'
+++

We can start by calling `createElement` to create and {{<tooltip title="compose DOM elements">}}To **compose DOM elements** means to **combine DOM elements** to form some part of the user interface.{{</tooltip>}}. For now, we'll only consider rendering the `title` property from the `film` object:

```js
const film = {
title: "Killing of Flower Moon",
director: "Martin Scoresese"
times: ["15:35"],
certificate: "15",
duration: 112
};

const filmCard = document.createElement("section");
filmCard.innerHTML = `
<h3>${film.title}</h3>
`;
console.log(filmCard);
```

If we open up the console tab, we should be able to see this element logged in the console. However, it won't yet appear in the browser.

### Appending elements

To display the film card, we need to append it to another element that is already in the DOM tree.

```js {linenos=table,hl_lines=["14"],linenostart=1}
const film = {
title: "Killing of Flower Moon",
director: "Martin Scoresese"
times: ["15:35"],
certificate: "15",
duration: 112
};

const filmCard = document.createElement("section");
filmCard.innerHTML = `
<p>${film.title}</p>
`;

document.querySelector("ul").append(section);
```
11 changes: 11 additions & 0 deletions content/js3/blocks/data-ui/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
+++
title = '💾 ➡️ 💻 Data to UI '
headless = true
time = 20
facilitation = false
emoji= '🧩'
[objectives]
1='Explain how data is rendered into a user interface'
+++

When we build user interfaces we often take data and {{<tooltip title="render">}}**rendering** is the process of building an interface from some code{{</tooltip>}} it in the user interface. We will model some real-life objects using a data structure. However, end users don't directly interact with a data structure. Instead, they'll interact with a rendering of this data structure through some user interface, typically a web browser. We're going to start with a data structure and explore how we can render it on the page.
Binary file added content/js3/blocks/now-showing/film-cards.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions content/js3/blocks/now-showing/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
+++
title = '📽️ Cinema listings'
headless = true
time = 20
facilitation = false
emoji= '🧩'
[objectives]
1='Define an acceptance criterion for building a web page'
2='Use a wireframe to make a basic design for the web page'
+++

Suppose you're building a user interface to display the films that are now showing on a film website. We need to render some cinema listings in the user interface. Let's define an acceptance criterion:

> _Given_ a list of film data
> _When_ the page first loads
> _Then_ it should display the list of films now showing, including the film title, times and film certificate
We can use a {{<tooltip title="wireframe">}}A wireframe is a basic outline of a web page used for design purposes{{</tooltip>}}to visualise how the user interface should look:

### Cinema listings wireframe 🖼️

![film-cards](film-cards.png)

The wireframe is built by reusing the same{{<tooltip title="UI component">}}A **UI component** is a reusable, self-contained piece of the UI. UI components are like lego blocks you can use to build websites. Most websites are made by "composing" components in this way.{{</tooltip>}}. In particular, each film object is rendered as a card component. To build this user interface, we will start with data in the form of an array of objects, each with similar properties. Here are some example film data:

```js
const films = [
{
title: "Killing of Flower Moon",
director: "Martin Scoresee"
times: ["15:35"],
certificate: "15",
duration: 112
},
{
title: "Typist Artist Pirate King",
directory: "Carol Morley"
times: ["15:00", "20:00"],
certificate: "12A",
duration: 108
},
.
.
.
];
```

Our task will be to build the film listings view from this list of data.
51 changes: 51 additions & 0 deletions content/js3/blocks/one-to-one/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
+++
title = 'One to one'
headless = true
time = 30
facilitation = false
emoji= '🧩'
[objectives]
1='Describe how to render a list of data'
+++

We can now render _any_ film data object in the UI. However, to fully solve this problem we must render a list of data. For each film object, we need to render a corresponding film object in the UI. In this case, there is a {{<tooltip title="one-to-one mapping">}}A **one-to-one mapping** associates every element in a set to exactly one element in another set{{</tooltip>}}between the data array and the UI components on the web page. Each item in the array matches a node in the UI. We can represent this diagrammatically by pairing up the data elements with their corresponding UI components:

```mermaid
---
title: One to one mapping between data and the UI components
---
flowchart LR
A[datum1] == createFilmCard(datum1) ==> B[UI component 1]
C[datum2] == createFilmCard(datum2) ==> D[UI component 2]
```

To create an array of card components, we can iterate through the film data using a `for...of` loop:

```js
const films = [
{
title: "Killing of Flower Moon",
director: "Martin Scoresee"
times: ["15:35"],
certificate: "15",
duration: 112
},
{
title: "Typist Artist Pirate King",
directory: "Carol Morley"
times: ["15:00", "20:00"],
certificate: "12A",
duration: 108
},
];

const filmCards = [];
for (const item of films) {
filmCards.push(createFilmCard(item));
}

document.querySelector("ul").append(...elements);
// invoke append using the spread operator
```

However, there are alternative methods for building this array of UI components.
27 changes: 27 additions & 0 deletions content/js3/blocks/single-datum/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
+++
title = '💽 Single datum'
headless = true
time = 30
facilitation = false
emoji= '🧩'
[objectives]
1='Define a sub-goal for rendering data in the user interface'
+++

> 🎯 Sub-goal: Build a film card component
To break down this problem, we'll render a single datum, before doing this for the whole list. Here's one film:

```js
const film = {
title: "Killing of Flower Moon",
director: "Martin Scoresese"
times: ["15:35"],
certificate: "15",
duration: 112
};
```

Starting with this object, we'll focus _only_ on building this section of the user interface:

![single-film-display](single-film-display.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7485afd

Please sign in to comment.