From c253d321476b2bcaea30793b785a8cf345bba6d2 Mon Sep 17 00:00:00 2001 From: Zaira <33151350+zairahira@users.noreply.github.com> Date: Tue, 24 Sep 2024 18:44:16 +0500 Subject: [PATCH] feat(curriculum): add favourite icon toggler lab (#55885) Co-authored-by: Jessica Wilkins <67210629+jdwilkin4@users.noreply.github.com> Co-authored-by: Tom <20648924+moT01@users.noreply.github.com> --- client/i18n/locales/english/intro.json | 7 +- .../lab-favorite-icon-toggler/index.md | 9 + .../_meta/lab-favorite-icon-toggler/meta.json | 11 + .../66bf6bacf178eac7b96d4f5e.md | 216 ++++++++++++++++++ 4 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 client/src/pages/learn/front-end-development/lab-favorite-icon-toggler/index.md create mode 100644 curriculum/challenges/_meta/lab-favorite-icon-toggler/meta.json create mode 100644 curriculum/challenges/english/25-front-end-development/lab-favorite-icon-toggler/66bf6bacf178eac7b96d4f5e.md diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json index 8d9b4b05cc7..7c0485a8ad4 100644 --- a/client/i18n/locales/english/intro.json +++ b/client/i18n/locales/english/intro.json @@ -2212,7 +2212,12 @@ }, "esfh": { "title": "188", "intro": [] }, "gibb": { "title": "189", "intro": [] }, - "whrm": { "title": "190", "intro": [] }, + "lab-favorite-icon-toggler": { + "title": "Build a Favorite Icon Toggler", + "intro": [ + "In this lab, you will build a favorite icon toggler by utilizing JavaScript click events." + ] + }, "fhxc": { "title": "191", "intro": [] }, "quiz-dom-manipulation-and-click-event-with-javascript": { "title": "DOM Manipulation and Click Events with JavaScript Quiz", diff --git a/client/src/pages/learn/front-end-development/lab-favorite-icon-toggler/index.md b/client/src/pages/learn/front-end-development/lab-favorite-icon-toggler/index.md new file mode 100644 index 00000000000..22ff9267e53 --- /dev/null +++ b/client/src/pages/learn/front-end-development/lab-favorite-icon-toggler/index.md @@ -0,0 +1,9 @@ +--- +title: Introduction to the Build a Favorite Icon Toggler +block: lab-favorite-icon-toggler +superBlock: front-end-development +--- + +## Introduction to the Build a Favorite Icon Toggler + +In this lab, you will build a favorite icon toggler by utilizing JavaScript click events. diff --git a/curriculum/challenges/_meta/lab-favorite-icon-toggler/meta.json b/curriculum/challenges/_meta/lab-favorite-icon-toggler/meta.json new file mode 100644 index 00000000000..1c93cecbc81 --- /dev/null +++ b/curriculum/challenges/_meta/lab-favorite-icon-toggler/meta.json @@ -0,0 +1,11 @@ +{ + "name": "Build a Favorite Icon Toggler", + "isUpcomingChange": true, + "usesMultifileEditor": true, + "blockType": "lab", + "dashedName": "lab-favorite-icon-toggler", + "order": 190, + "superBlock": "front-end-development", + "challengeOrder": [{ "id": "66bf6bacf178eac7b96d4f5e", "title": "Build a Favorite Icon Toggler" }], + "helpCategory": "JavaScript" +} diff --git a/curriculum/challenges/english/25-front-end-development/lab-favorite-icon-toggler/66bf6bacf178eac7b96d4f5e.md b/curriculum/challenges/english/25-front-end-development/lab-favorite-icon-toggler/66bf6bacf178eac7b96d4f5e.md new file mode 100644 index 00000000000..3f383e2845d --- /dev/null +++ b/curriculum/challenges/english/25-front-end-development/lab-favorite-icon-toggler/66bf6bacf178eac7b96d4f5e.md @@ -0,0 +1,216 @@ +--- +id: 66bf6bacf178eac7b96d4f5e +title: Build a Favorite Icon Toggler +challengeType: 14 +dashedName: build-a-favorite-icon-toggler +demoType: onClick +--- + +# --description-- + +In this lab you will use JavaScript click events to toggle the appearance of a favorite icon. When the heart icon is clicked, the appearance of the heart changes from empty to filled, and vice versa. + +**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab. **Do not copy this demo project**. + +**User Stories:** + +1. You should have an unordered list with three items. +2. The unordered list should have the class `item-list`. +3. The three list items should contain the item name followed by a `span` element with the class `favorite-icon`. +4. The `span` element should contain the code `♡` initially to represent an empty heart. +5. When a span element containing a heart is clicked, you should add the `filled` class to the clicked `span` if it's not already present, and remove it, if it is. +6. When a `span` element containing a heart is clicked, the heart symbol should toggle between `♡` (empty heart) and `❤` (filled heart), depending on its current state. + +# --hints-- + +You should have an unordered list. + +```js +assert.exists(document.querySelector('ul')); +``` + +Your unordered list should have 3 items. + +```js +assert.lengthOf(document.querySelectorAll('ul li'), 3); +``` + +Your unordered list should have the class `item-list`. + +```js +assert.exists(document.querySelector('ul.item-list')); +``` + +Your individual list items should contain the item name. + +```js +assert.exists(document.querySelector('ul li').textContent); + +``` + +Your individual list item should contain a `span` element with the class `favorite-icon` + +```js +assert.exists(document.querySelector('ul li span.favorite-icon')); +``` + +Initially, the `span` elements should contain the code `♡` to represent an empty heart. + +```js +const inputs = document.querySelectorAll('ul li span.favorite-icon'); +assert(inputs.length) + +for (let input of inputs) { + assert.strictEqual(input.innerHTML.charCodeAt(0), 9825); +} +``` + +When the `span` element is clicked, and it contains the class `filled`, you should remove the class `filled` from the `span` element and change the innerHTML of the `span` element to `♡`. + +```js +const spanElements = document.querySelectorAll('.favorite-icon'); +assert(spanElements.length); + +spanElements.forEach(span => span.classList.add('filled')); + +spanElements.forEach(span => { + span.dispatchEvent(new Event('click')); + span.dispatchEvent(new Event('change')); + assert.isFalse(span.classList.contains('filled')); + assert.equal(span.innerHTML.charCodeAt(0), 9825); +}); +``` + +When the `span` element is clicked, and it doesn't contain the class `filled`, you should add the class `filled` to the `span` element and change the `innerHTML` of the `span` element to `❤`. + +```js +const spanElements = document.querySelectorAll('.favorite-icon'); +assert(spanElements.length); + +spanElements.forEach(span => span.classList.remove('filled')); + +spanElements.forEach(span => { + span.dispatchEvent(new Event('click')); + span.dispatchEvent(new Event('change')); + assert.isTrue(span.classList.contains('filled')); + assert.equal(span.innerHTML.charCodeAt(0), 10084); +}); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + + + + + + + + +``` + +```css + +``` + +```js + +``` + +# --solutions-- + +```html + + + + + + + Favorite Icon Toggle + + + + +

Art Supplies

+ + + + + + +``` + +```css +body { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + font-family: Arial, sans-serif; +} + +h1 { + margin-bottom: 20px; +} + +.item-list { + list-style-type: none; + padding: 0; +} + +.item-list li { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px; + border-bottom: 1px solid #ddd; + width: 200px; +} + +.favorite-icon { + font-size: 20px; + cursor: pointer; +} +``` + +```js +document.addEventListener("DOMContentLoaded", () => { + const favoriteIcons = document.querySelectorAll(".favorite-icon"); + + favoriteIcons.forEach((icon) => { + icon.addEventListener("click", () => { + if (icon.classList.contains("filled")) { + icon.classList.remove("filled"); + icon.innerHTML = "♡"; // Empty heart + } else { + icon.classList.add("filled"); + icon.innerHTML = "❤"; // Filled black heart + } + }); + }); +}); +```