├── .DS_Store ├── .vscode └── settings.json ├── Class-1 (Introduction to DOM) ├── 1.html ├── 2.html ├── 3.html ├── 4.html ├── index.html ├── notes.md └── script.js ├── Class-2 (Events) ├── 5.html ├── 6.html ├── 7.html ├── 8.html ├── notes.md └── test.html ├── Class-3 (Form Events) ├── index.html ├── index.js ├── notes.md ├── style.css └── test.md ├── Class-4 (Event Bubbling and Capturing) ├── index.html ├── notes.md └── optimized.html ├── Class-5 (Quiz App) ├── index.html ├── optimized.js ├── script.js └── style.css ├── Class-6(Date and Time) ├── countdown.html └── index.html ├── Class-7 (Kanban Board) ├── index.html ├── notesc1.md ├── notesc2.md ├── notesc3.md ├── script.js ├── style.css └── test.json ├── Class-8 (async Programming-1) ├── async1.js ├── f1.txt ├── f2.txt ├── f3.txt ├── fileHandling.js └── fileReadSerial.js ├── Class-9 (Async-2) ├── index.js └── promise.js ├── PracticeSheet └── sheet1.md ├── Small Projects ├── characterCount.html ├── drumkit.html ├── expense.html ├── starRating.html └── votingapp.html └── practiceSheetEndTerm.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrinal1224/Batch-1-Trimester-2/25a3ab942eb05f4fa7a6d11557fae14086c08f72/.DS_Store -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /Class-1 (Introduction to DOM)/1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | Document 10 | 11 | 12 | 13 | 14 | 15 | 16 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Class-1 (Introduction to DOM)/2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | Document 10 | 11 | 12 | 13 | 25 | 26 | 27 | 28 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Class-1 (Introduction to DOM)/3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 |

2 + 2 =22

11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Class-1 (Introduction to DOM)/4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | Document 11 | 45 | 46 | 47 | 48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Class-1 (Introduction to DOM)/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 |
11 |

I am heading 1

12 |
13 | 14 |
15 |
16 | Go to google 17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /Class-1 (Introduction to DOM)/notes.md: -------------------------------------------------------------------------------- 1 | # Introduction to Document Object Model 2 | 3 | 4 | 5 | 6 | ## Agenda 7 | 8 | **First of all today we will start with Introduction of DOM and then we will solve some fun problems to understand how you can put interactivity to your web pages by using DOM methods and Properties , Today we will target to complete the topics listed below-** 9 | 10 | 11 | - Selecting Elements (querySelector , querySelectorALL , getElementbyID etc) 12 | - Event Listeners 13 | - Creating appending and inserting Elements (createElement , appendChild , insertBefore) 14 | - NodeList and ClassList 15 | - the event object 16 | - getAttribute and setAttribute methods 17 | 18 | 19 | 20 | 21 | 22 | ## Introduction to the Document Object Model (DOM) 23 | 24 | ### Definition 25 | 26 | The Document Object Model (DOM) is a programming interface for web documents. It represents the page so that programs can change the document structure, style, and content. The DOM represents the document as a tree structure where each node is an object representing a part of the document. This model is constructed as a tree of Objects: 27 | 28 | - **Document:** The root node that represents the entire HTML document. 29 | - **Elements:** Represent each tag in the HTML document. These are the nodes that have children (inner elements or text). 30 | - **Attributes:** Define properties of elements, such as `class`, `id`, or `style`. 31 | - **Text:** The actual text within elements is also considered a node. 32 | 33 | ### Importance of DOM 34 | 35 | Understanding the DOM is crucial for web developers because it: 36 | 37 | - Provides a structured representation of the document. 38 | - Allows JavaScript to access and manipulate the content and structure of a webpage dynamically. 39 | - Enables the creation of rich, interactive web applications by providing methods to change the document content, structure, and styles. 40 | 41 | ### Example Explanation 42 | 43 | Let's analyze the given HTML document in the context of the DOM: 44 | 45 | ```htmlembedded 46 | 47 | 48 | 49 | 50 | 51 | Document 52 | 53 | 54 |
55 |

This is heading 2

56 |
57 |
58 |

This is heading 1

59 |

This is Paragraph

60 |
61 | 62 | 63 | ``` 64 | 65 | - **Document Node:** Represents the entire HTML document. 66 | - **HTML Element:** The root element that contains all other elements. 67 | - **Head and Body:** These are child nodes of the HTML element. The Head element contains meta-information about the document, while the Body element contains the document's content. 68 | - **Div Elements:** Each Div element acts as a container that groups other elements. There are two Div elements, each containing different content. 69 | - The first Div contains a Heading (`

`), which is "This is heading 2". 70 | - The second Div contains a Heading (`

`), "This is heading 1", and a Paragraph (`

`), "This is Paragraph". 71 | 72 | This structure shows how elements in the HTML document are represented as a tree in the DOM, with each tag corresponding to a node in the tree. By accessing these nodes via JavaScript, developers can dynamically change the content, style, or structure of the webpage. 73 | 74 | #### Output 75 | 76 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/258/original/upload_364afb8e43132cd223c90b39c021e52a.png?1695145205) 77 | 78 | 79 | #### DOM tree visualization of above example 80 | 81 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/259/original/upload_604c9f192818c3459c15d376d0569b83.png?1695145257) 82 | 83 | **Note:** 84 | * We will be uisng javascript to put the interactivity in our web apps or websites. 85 | * JavaScript is used to put interactivity in DOM elements. 86 | 87 | 88 | 89 | ### Manipulating the DOM with JavaScript 90 | 91 | JavaScript can be used to interact with the DOM to: 92 | 93 | - **Add, remove, or modify elements:** You can create new elements, delete existing ones, or change their properties. 94 | - **Change styles:** Modify the CSS of elements to change their appearance. 95 | - **Respond to events:** Set up event listeners to respond to user actions like clicks, keyboard input, or page loading. 96 | 97 | We will explore DOM and how we can put interactivity in our web pages by solving problems, that's a very fun way to learn DOM to do some actual tasks with your nodes 98 | 99 | 100 | 101 | So , let's start with a very basic task that we have a html button and whenever we click on that hello should be printed on the page 102 | 103 | #### Question 104 | 105 | On clicking the button append hello to the page. 106 | 107 | We will go step by step by taking into account each and everthing 108 | 109 | #### Solution 110 | 111 | **Step 1:** Selecting the html element 112 | 113 | To select or identify a particular html element we have methods. 114 | * getElementById - If you want to select an element based on ID 115 | * querySelector - If you want to select an element based on any selector like class id or a combination or a specific element 116 | 117 | 118 | 119 | **Code:** Using getElementById 120 | 121 | #### Using `getElementById` 122 | 123 | 124 | ```htmlembedded 125 | 126 | 127 | 128 | 129 | 130 | Document 131 | 132 | 133 | 134 | 135 | 143 | 144 | 145 | 146 | ``` 147 | 148 | 149 | - **Method Used**: `document.getElementById('btn-1')` 150 | - **Purpose**: Selects the first element with the specified ID. It's a straightforward and efficient way to select elements if they have a unique ID. 151 | - **Example Use**: In the provided code, this method selects a button with the ID `btn-1`. 152 | 153 | 154 | 155 | 156 | 157 | 158 | **Code:** Using querySelector by ID 159 | 160 | ```htmlembedded 161 | 162 | 163 | 164 | 165 | 166 | Document 167 | 168 | 169 | 170 | 171 | 179 | 180 | 181 | 182 | ``` 183 | 184 | #### Using `querySelector` by ID 185 | 186 | - **Method Used**: `document.querySelector('#btn-1')` 187 | - **Purpose**: Selects the first element that matches the specified CSS selector. In this case, it selects the element with the ID `btn-1`. `querySelector` is more versatile than `getElementById` because it can select elements based on classes, attributes, and more complex selectors. here you will just need to pass the exact identifier as well for id `#` for class `.` and so on 188 | - **Example Use**: The script uses this method to select a button by its ID in a similar manner to `getElementById`, showcasing an alternative approach. 189 | 190 | 191 | **Code:** Using querySelector by class 192 | 193 | ```htmlembedded 194 | 195 | 196 | 197 | 198 | 199 | Document 200 | 201 | 202 | 203 | 204 | 205 | 213 | 214 | 215 | 216 | ``` 217 | 218 | 219 | #### Using `querySelector` by Class 220 | 221 | - **Method Used**: `document.querySelector('.btn-1')` 222 | - **Purpose**: Selects the first element that matches the specified class. This is useful when you're working with CSS classes instead of IDs or need to select elements based on other attributes or complex selectors. 223 | - **Example Use**: This variant selects a button with the class `btn-1`, demonstrating how to use `querySelector` to select elements by class name. 224 | 225 | 226 | 227 | **Code:** Using querySelector by elements 228 | 229 | The document method querySelector() returns the first element within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned. 230 | 231 | ```htmlembedded 232 | 233 | 234 | 235 | 236 | 237 | Document 238 | 239 | 240 | 241 | 242 | 250 | 251 | 252 | 253 | ``` 254 | #### Using `querySelector` by Element 255 | 256 | - **Method Used**: `document.querySelector('button')` 257 | - **Purpose**: Selects the first ` 293 | 294 | 302 | 303 | 304 | ``` 305 | 306 | ### Adding an Event Listener to the Button 307 | ```javascript 308 | btn.addEventListener('click', function(){ 309 | console.log("button Clicked") 310 | }); 311 | ``` 312 | - `btn.addEventListener('click', ...)`: This method is called on the button element (`btn`). It listens for a "click" event, meaning it waits for the button to be clicked. When a click occurs, it executes the function provided as the second argument. 313 | - `function(){ ... }`: This is an anonymous function (a function without a name) that is executed when the button is clicked. 314 | - `console.log("button Clicked)`: Inside the function, this line is supposed to log the message "button Clicked" to the browser's console. This indicates that the button has been clicked. 315 | 316 | Show this whole thing in the Browser and the Browser's Console 317 | 318 | 319 | **Step 3:** CreateElement and AppendChild 320 | 321 | So now to append hello on the click of the button we first need to create a element in which `hello` will be placed then we need to attach that element in our DOM tree in a appropriate position to get it appended and visible , We can do this by using two methods to Create an element where Hello will go we can use `createElement` method and to attach that element to DOM we can use `appendChild` , let's see how they work and how to use them 322 | 323 | ```javascript 324 | 325 | 326 | 327 | 328 | 329 | Document 330 | 331 | 332 | 333 | 334 | 355 | 356 | 357 | 358 | ``` 359 | Let's break this down 360 | 361 | 362 | 1. **Creating a New `

` Element**: 363 | ```javascript 364 | let divElem = document.createElement('div') 365 | ``` 366 | - `document.createElement('div')` creates a new `
` element. This method takes one argument, the tag name of the element to be created. 367 | - The new `
` element is stored in the variable `divElem`. 368 | - This method (`createElement`) is crucial for dynamically adding new elements to the DOM (Document Object Model). 369 | 370 | 2. **Setting the Inner Text of the `
` Element**: 371 | ```javascript 372 | divElem.innerText = 'Hello' 373 | ``` 374 | - The `innerText` property of `divElem` is set to `'Hello'`. This means the text content of the newly created `
` will be "Hello". 375 | - `innerText` is used here to define what text the `
` element will display. 376 | 377 | 3. **Selecting the `` Element**: 378 | ```javascript 379 | let body = document.querySelector('body') 380 | ``` 381 | - `document.querySelector('body')` selects the `` element of the page. 382 | - The selected `` element is stored in the variable `body`. 383 | 384 | 4. **Appending the `
` to the ``**: 385 | ```javascript 386 | body.appendChild(divElem) 387 | ``` 388 | - `appendChild` is a method used to append a node as the last child of a node. In this case, `divElem` (the newly created `
` with the text "Hello") is appended to `body` (the `` element of the document). 389 | - After this method is executed, the new `
` will appear on the webpage as part of the document's body. Each click on the button will create and append a new `
` with "Hello" to the body. 390 | 391 | this JavaScript code listens for clicks on a button. Upon each click, it creates a new `
` element, sets its text content to "Hello", and appends this `
` to the body of the document, resulting in "Hello" being added to the page each time the button is clicked. The `createElement` and `appendChild` methods are fundamental here for dynamically adding elements to the DOM. 392 | 393 | **Output:** 394 | 395 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/267/original/upload_c04b7917d2c7dd94fad263612d3bae02.png?1695145825) 396 | 397 | 398 | **By Solving this simple problem You now know how to slelect elements based on diffrennt approcahes how to listen to events and respond to them by event listeners and how you can create and append element in the DOM tree** 399 | 400 | **take 5 mins here to clear any doubts and move to next question** 401 | 402 | 403 | 404 | ### Problem Statement 405 | 406 | You are given an HTML document containing an unordered list (`
    `) with list items (`
  • `) representing numbers 1 through 10. However, there is an element missing between the numbers 6 and 8. Your task is to identify the missing number in the sequence and insert it appropriately into the list to maintain the sequential order using JavaScript. 407 | 408 | **Ask learners how they may approcah this** 409 | 410 | 411 | Explain step by step that how to break down a problem and solve it step by step 412 | 413 | To achieve this, you should: 414 | 415 | 1. Identify the missing number in the list. 416 | 2. Create a new list item (`
  • `) with the missing number as its content. 417 | 3. Insert the new list item into the correct position in the list to maintain the sequential numbering 418 | 419 | Always without thinking of the methods , code or anything else only think about what should be done to achieve something and then you can read , google or research about what you can use to achieve the end results , Software Engineering works like this , so make habit of thinking of the solution in parts without focusing on the implementatiom first then step by step start implementing things 420 | 421 | 422 | Ok! enough Talk , now let's solve this 423 | 424 | #### Solution 425 | 426 | **Step 1:** creating node list 427 | 428 | Now as you can see the whole list , the number 7 is missing , so now to put 7 in between 6 and 8 we will need access to the whole list , that means I will need every list node in the same order and then I can identfy where the node is missing and can add that right? 429 | 430 | So to do that we can use the method `querySelectorAll` and can pass the element name inside it 431 | 432 | The `querySelectorAll` method is a powerful tool provided by the Document Object Model (DOM) Web API that allows you to select and manipulate elements on a webpage. It enables you to find all elements within the document that match a specified CSS selector(s). Here's a breakdown of its functionality: 433 | 434 | **Return Value**: `querySelectorAll` returns a `NodeList` of all elements within the document that match the specified group of selectors. A `NodeList` is a collection of DOM nodes that can be iterated over like an array but it is not an array it is a array like structure which is indexed and that's why it can be iterated over 435 | 436 | To Sum up , Node list is an array like structure which will have your elements stored in indexed form. 437 | 438 | ```javascript 439 | 440 | 441 | 442 | 443 | 444 | Document 445 | 446 | 447 |
      448 |
    • 1
    • 449 |
    • 2
    • 450 |
    • 3
    • 451 |
    • 4
    • 452 |
    • 5
    • 453 |
    • 6
    • 454 | 455 |
    • 8
    • 456 |
    • 9
    • 457 |
    • 10
    • 458 |
    459 | 460 | 467 | 468 | 469 | 470 | ``` 471 | 472 | **Output:** 473 | 474 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/271/original/upload_fc8a7cf791547f64129ac0eef13aa66e.png?1695146016) 475 | 476 | **Step 2:** adding element 477 | 478 | ```javascript 479 | 480 | 481 | 482 | 483 | 484 | Document 485 | 486 | 487 |
      488 |
    • 1
    • 489 |
    • 2
    • 490 |
    • 3
    • 491 |
    • 4
    • 492 |
    • 5
    • 493 |
    • 6
    • 494 | 495 |
    • 8
    • 496 |
    • 9
    • 497 |
    • 10
    • 498 |
    499 | 500 | 517 | 518 | 519 | 520 | ``` 521 | 522 | **Explanation of the code and all the methods step by step** 523 | 524 | 1. **Select the unordered list**: `let ourList = document.querySelector('ul');` 525 | - This line selects the first `
      ` element found in the document and stores it in the variable `ourList`. 526 | - `document.querySelector('ul')` uses the `querySelector` method to find the first element that matches the specified CSS selector ('ul' in this case). 527 | 528 | 2. **Log the unordered list to the console**: `console.log(ourList);` 529 | - This line prints the unordered list element (referenced by `ourList`) to the browser's console. It's a way to verify that the correct element has been selected. 530 | 531 | 3. **Select all list items**: `let allItems = document.querySelectorAll('li');` 532 | - This line selects all `
    • ` elements (list items) within the document and stores them in the `allItems` variable. 533 | - `document.querySelectorAll('li')` returns a NodeList containing all the `
    • ` elements found. This method is used to select multiple elements that match the given CSS selector. 534 | 535 | 4. **Log all list items to the console**: `console.log(allItems);` 536 | - This prints the NodeList of all list items (referenced by `allItems`) to the console, allowing you to see all the list items in the console for debugging or verification purposes. 537 | 538 | 5. **Identify the position of the list item that contains "8"**: `let indexThatHas8 = allItems[6];` 539 | - This line assigns the seventh `
    • ` element in the NodeList (which contains the number "8") to the variable `indexThatHas8`. Note that array indexing starts at 0, so `allItems[6]` refers to the seventh element in the list. 540 | 541 | 6. **Create a new list item with the text "7"**: 542 | - `let sevenElement = document.createElement('li')` 543 | - This line creates a new `
    • ` element but does not yet insert it into the document. The new element is stored in the variable `sevenElement`. 544 | - `sevenElement.innerText = '7'` 545 | - This sets the text content of the newly created `
    • ` element to "7". 546 | 547 | 7. **Insert the new list item before the one that contains "8"**: `ourList.insertBefore(sevenElement, indexThatHas8)` 548 | - This line inserts the newly created list item (`sevenElement`) into the unordered list (`ourList`) right before the list item that contains "8" (referenced by `indexThatHas8`). 549 | - The `insertBefore` method is used to insert a node before the reference node as a child of a specified parent node. Here, it ensures the list item "7" is added in the correct place to maintain numerical order. 550 | 551 | the JavaScript part of the code fixes the missing "7" in the list by dynamically creating a new `
    • ` element with the text "7" and inserting it into the correct position in the unordered list. 552 | 553 | **Output:** 554 | 555 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/273/original/upload_9cda233672dc980dc39259973628c350.png?1695146091) 556 | 557 | 558 | **By Solving this problem you have learnt about how querySelectorAll works , What is a NodeList and insertBefore Method works** 559 | 560 | 561 | #### Question 562 | 563 | Fix the mathmatical problem using JS 564 | 565 | - Problem Statement : Given a mathematical expression Fix the expression by using Javascript and taking help of the DOM 566 | 567 | (Pass this question as a fun question in the class ask students to solve this in break) 568 | 569 | #### Solution 570 | 571 | ```javascript 572 | 573 | 574 | 575 | 576 | 577 | Document 578 | 579 | 580 | 581 |

      2 + 2 = 22

      582 | 583 | 587 | 588 | 589 | 590 | 591 | ``` 592 | 593 | **Output:** 594 | 595 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/274/original/upload_7e599ac46343deed76441a6ec8a415e8.png?1695146150) 596 | 597 | 598 | 599 | 600 | **Before Moving to the Next Question Lets discuss about something known as `classList`** 601 | 602 | The `classList` property in the Document Object Model (DOM) is a read-only property that returns a live collection of the class attributes of the element. It provides a convenient way to access and manipulate the class names of an element. With `classList`, you can easily add, remove, and toggle CSS classes on an element, which is particularly useful for dynamically changing the appearance or behavior of elements in response to user interactions. 603 | 604 | Here are some of the most commonly used methods of `classList`: 605 | 606 | - `add(className)`: Adds a specified class to the element. If the class already exists in the element's class list, it will not add it again. 607 | 608 | - `remove(className)`: Removes a specified class from the element. If the class does not exist, it does nothing. 609 | 610 | - `contains(className)`: Checks if a specified class exists in the element's class list, returning `true` if it does and `false` otherwise. 611 | 612 | 613 | ### Small Example: 614 | 615 | Suppose you have an HTML element like this: 616 | 617 | ```html 618 |
      Hello, world!
      619 | ``` 620 | 621 | You can use the `classList` property to manipulate this element's classes in JavaScript: 622 | 623 | ```javascript 624 | // Get the element 625 | var div = document.getElementById('myDiv'); 626 | 627 | // Add a new class 628 | div.classList.add('highlight'); 629 | 630 | // Remove a class 631 | div.classList.remove('visible'); 632 | 633 | 634 | // Check if a class exists 635 | if (div.classList.contains('content')) { 636 | console.log('The div has a "content" class.'); 637 | } 638 | else{ 639 | console.log('The div does not has a "content" class.'); 640 | } 641 | ``` 642 | 643 | After running this script, the class attribute of the `div` element would be modified based on the operations performed. For example, if the `highlight` class didn't exist before, it would be added; the `visible` class would be removed; and the `hidden` class would be toggled, adding it if it wasn't there or removing it if it was. 644 | 645 | 646 | 647 | **Now Let's move forward with the next Problem** 648 | 649 | #### Question 650 | 651 | Write a script which fetches the data-color attribute of the card and double clicking on them and attahces the fetched class to that card and also changes the data-color attribute to "used" 652 | 653 | #### Solution 654 | 655 | ```javascript 656 | 657 | 658 | 659 | 660 | 661 | 662 | Document 663 | 697 | 698 | 699 | 700 |
      701 |
      702 |
      703 |
      704 |
      705 |
      706 |
      707 |
      708 |
      709 |
      710 | 735 | 736 | 737 | ``` 738 | 739 | 740 | ### HTML Brief 741 | 742 | - **DOCTYPE, html, head, meta tags, and title**: These lines define the basic structure of an HTML document, including setting the character set, compatibility, viewport settings for responsive design, and the title of the document. 743 | 744 | - **style tags**: Inside these tags, CSS is used to style elements on the page. Every element is set to `box-sizing: border-box;`. The body is styled to display its children in a flex layout, centered and with some padding at the top. Classes `.blue`, `.green`, and `.red` assign background colors and a box-shadow to elements. The `.card` class defines a bordered box with specified height, width, and margin. 745 | 746 | ### JavaScript 747 | 748 | - **let cardsNodeList = document.querySelectorAll('.card')**: This line selects all elements with the class "card" and stores them in `cardsNodeList`. `querySelectorAll` returns a NodeList, which is a collection of document nodes. 749 | 750 | - **console.log(cardsNodeList)**: This line logs the NodeList of card elements to the console, allowing you to see the elements selected by the previous command. 751 | 752 | - **for loop**: The loop iterates over each item in the `cardsNodeList`. The variable `i` is used as the index to access each element in the NodeList. 753 | 754 | - **cardsNodeList[i].addEventListener('dblclick', function(e))**: This line adds an event listener to each card element. The event listener listens for a 'dblclick' event (a double-click), and when such an event occurs, it executes the function provided as the second argument. The `e` parameter represents the event object that gets passed to the function when the event occurs. 755 | 756 | #### The `e` (Event) Object Explained: 757 | 758 | - **console.log(e)**: This logs the event object to the console. The event object `e` contains all the information about the event that occurred, including which element was clicked, the type of event, the position of the mouse, and more. 759 | 760 | - **e.currentTarget**: This property of the event object refers to the element to which the event listener was attached. In this context, `e.currentTarget` is the card that was double-clicked. 761 | 762 | - **e.currentTarget.getAttribute('data-color')**: This method gets the value of the `data-color` attribute from the clicked card. This value indicates the color class (blue, red, or green) that should be applied to the card. 763 | 764 | - **e.currentTarget.classList.add(classTobeAttached)**: This line adds the class (obtained from the `data-color` attribute) to the clicked card's class list, changing its appearance according to the CSS definitions for `.blue`, `.green`, or `.red`. 765 | 766 | - **e.currentTarget.setAttribute('data-color', 'used')**: Finally, this line changes the `data-color` attribute of the clicked card to "used", indicating that the card's color has been set and the attribute has been utilized. 767 | 768 | ### Summary: 769 | 770 | The JavaScript code dynamically adds event listeners to each card element, allowing them to respond to double-click events. Upon a double-click, the script reads the card's `data-color` attribute to determine which color class to apply, adds that class to the card, and then marks the `data-color` attribute as "used". The `e` object, representing the event, plays a crucial role in accessing the target element and its attributes. 771 | 772 | **Output:** 773 | 774 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/276/original/upload_108dfa145e3eef14525de6578e2be0f0.png?1695146343) 775 | 776 | 777 | We will be exploring more about the `event object (e)` and how it can be used further in solving diffrent problems 778 | 779 | 780 | So, with this class you now have a deep understanding about. 781 | 782 | 783 | - Selecting Elements (querySelector , querySelectorALL , getElementbyID etc) 784 | - Event Listeners 785 | - Creating appending and inserting Elements (createElement , appendChild , insertBefore) 786 | - NodeList and ClassList 787 | - the event object 788 | - getAttribute and setAttribute methods 789 | 790 | 791 | Let me know if the questions were fun!! in the next class we will have more questions and will explore more DOM property and methods 792 | 793 | Till then! Take care and Bye! 794 | 795 | **Start Doubt Session.** -------------------------------------------------------------------------------- /Class-1 (Introduction to DOM)/script.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrinal1224/Batch-1-Trimester-2/25a3ab942eb05f4fa7a6d11557fae14086c08f72/Class-1 (Introduction to DOM)/script.js -------------------------------------------------------------------------------- /Class-2 (Events)/5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | Document 11 | 61 | 62 | 63 | 64 |

      BOOK MY SHOW

      65 | 71 | 72 |
      73 |

      Action Movie - 1

      74 |

      Rs. 100

      75 |
      76 |
      77 |

      Action Movie - 2

      78 |

      Rs 200

      79 |
      80 |
      81 |

      Action Movie - 3

      82 |

      Rs. 150

      83 |
      84 |
      85 |

      Romance - 1

      86 |

      Rs 200

      87 |
      88 |
      89 |

      Romance - 2

      90 |

      Rs. 150

      91 |
      92 |
      93 |

      Romance - 3

      94 |

      Rs. 150

      95 |
      96 |
      97 |

      Action Movie-4

      98 |

      Rs 200

      99 |
      100 |
      101 |

      Comedy - 1

      102 |

      Rs. 100

      103 |
      104 |
      105 |

      Romance - 4

      106 |

      Rs. 100

      107 |
      108 |
      109 |

      Comedy - 2

      110 |

      Rs 200

      111 |
      112 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /Class-2 (Events)/7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
        12 |
      • 13 |

        Task - 1

        14 | 15 |
      • 16 |
      • 17 |

        Task - 2

        18 | 19 |
      • 20 |
      • 21 |

        Task - 3

        22 | 23 |
      • 24 |
      • 25 |

        Task - 4

        26 | 27 |
      • 28 |
      29 | 30 | 31 | 32 | 33 | 52 | 53 | -------------------------------------------------------------------------------- /Class-2 (Events)/8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
      11 | 12 |
      13 | 14 | 21 | 22 | -------------------------------------------------------------------------------- /Class-2 (Events)/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 19 | 20 | 21 | 22 |
      Hello
      23 | 24 | 25 | 26 | 34 | -------------------------------------------------------------------------------- /Class-3 (Form Events)/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Learning JavaScript 9 | 10 | 11 | 12 | 13 | 14 | 15 |
      16 |

      Customer Feedback

      17 | 22 |

      23 |
      24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Class-3 (Form Events)/index.js: -------------------------------------------------------------------------------- 1 | const myForm = document.querySelector('.feedback-form') 2 | console.log(myForm) 3 | const p = document.querySelector('p') 4 | 5 | let usernameRegex = /^[a-z0-9]{3,12}$/ 6 | let userFeedbackRegex = /^.{20,50}$/ 7 | 8 | myForm.addEventListener('submit' , function(e){ 9 | e.preventDefault() 10 | let usernameValue = myForm.username.value 11 | let feedbackValue = myForm.feedback.value 12 | 13 | let userNameValidation = usernameRegex.test(usernameValue) 14 | let feedbackValidation = userFeedbackRegex.test(feedbackValue) 15 | 16 | console.log(userNameValidation) 17 | console.log(feedbackValidation) 18 | 19 | 20 | if(userNameValidation && feedbackValidation){ 21 | p.innerText='All validated Successfully' 22 | } 23 | 24 | else{ 25 | p.innerText='Validation failed check Again' 26 | } 27 | }) 28 | 29 | 30 | // const str = 'test123AB' 31 | 32 | // let result = usernameRegex.test(str) 33 | 34 | 35 | // console.log(result) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Class-3 (Form Events)/notes.md: -------------------------------------------------------------------------------- 1 | ### **Forms and Form Events in Web Development** 2 | 3 | Forms are one of the most crucial components in web applications, allowing users to input data. Managing forms involves creating intuitive interfaces, handling events triggered by user interaction, and validating the data entered to ensure correctness and security. 4 | 5 | --- 6 | 7 | ### **Form Basics** 8 | A form in HTML is defined using the `
      ` tag. Forms can contain various input elements such as: 9 | - Text fields 10 | - Password fields 11 | - Radio buttons 12 | - Checkboxes 13 | - Dropdowns 14 | - File uploads 15 | - Buttons (Submit, Reset) 16 | 17 | #### Example: Simple HTML Form 18 | ```html 19 | 20 | 21 |

      22 | 23 | 24 |

      25 | 26 | 27 |

      28 | 29 | 30 |

      31 | 32 | 33 |

      34 | 35 | 36 |

      37 | 38 | 39 |
      40 | ``` 41 | 42 | --- 43 | 44 | ### **Form Events** 45 | 46 | Forms are interactive, and various events are triggered during user interaction. Common events include: 47 | 48 | 1. **`submit`**: Triggered when the form is submitted. 49 | 2. **`change`**: Triggered when the value of an input element changes. 50 | 3. **`input`**: Triggered when the user inputs text. 51 | 4. **`focus` and `blur`**: Triggered when an element gains or loses focus. 52 | 53 | #### Example: Handling Form Events with JavaScript 54 | ```javascript 55 | const form = document.getElementById('registrationForm'); 56 | 57 | form.addEventListener('submit', function (event) { 58 | event.preventDefault(); // Prevent form submission 59 | console.log("Form submitted successfully!"); 60 | }); 61 | 62 | const username = document.getElementById('username'); 63 | username.addEventListener('blur', function () { 64 | console.log("Username field lost focus"); 65 | }); 66 | ``` 67 | 68 | --- 69 | 70 | ### **Form Validation** 71 | 72 | 73 | #### Example: Client-Side Validation 74 | ```javascript 75 | function validateForm() { 76 | const username = document.getElementById('username').value; 77 | const email = document.getElementById('email').value; 78 | const password = document.getElementById('password').value; 79 | const dob = document.getElementById('dob').value; 80 | const zipcode = document.getElementById('zipcode').value; 81 | const phone = document.getElementById('phone').value; 82 | 83 | // Validate username 84 | const usernameRegex = /^[a-zA-Z0-9]{3,20}$/; 85 | if (!usernameRegex.test(username)) { 86 | alert("Username must be 3-20 characters long and contain only alphanumeric characters."); 87 | return false; 88 | } 89 | 90 | // Validate email 91 | const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 92 | if (!emailRegex.test(email)) { 93 | alert("Please enter a valid email address."); 94 | return false; 95 | } 96 | 97 | // Validate password 98 | const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/; 99 | if (!passwordRegex.test(password)) { 100 | alert("Password must be at least 8 characters long and contain both letters and numbers."); 101 | return false; 102 | } 103 | 104 | // Validate date of birth 105 | const dobRegex = /^\d{4}-\d{2}-\d{2}$/; 106 | if (!dobRegex.test(dob)) { 107 | alert("Please enter a valid date of birth in YYYY-MM-DD format."); 108 | return false; 109 | } 110 | 111 | // Validate zip code 112 | const zipcodeRegex = /^\d{5,6}$/; 113 | if (!zipcodeRegex.test(zipcode)) { 114 | alert("Zip code must be 5-6 digits."); 115 | return false; 116 | } 117 | 118 | // Validate Indian phone number 119 | const phoneRegex = /^(?:\+91|0)?[6-9]\d{9}$/; 120 | if (!phoneRegex.test(phone)) { 121 | alert("Phone number must start with +91 or 0 and contain 10 digits."); 122 | return false; 123 | } 124 | 125 | alert("Form submitted successfully!"); 126 | return true; 127 | } 128 | 129 | form.addEventListener('submit', function (event) { 130 | if (!validateForm()) { 131 | event.preventDefault(); // Prevent form submission if validation fails 132 | } 133 | }); 134 | ``` 135 | 136 | --- 137 | 138 | ### **Regex Patterns for Data Validation** 139 | 140 | 1. **Username**: `^[a-zA-Z0-9]{3,20}$` 141 | - Alphanumeric, 3-20 characters. 142 | 143 | 2. **Password**: `^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$` 144 | - At least 8 characters, includes letters and numbers. 145 | 146 | 3. **Email**: `^[^\s@]+@[^\s@]+\.[^\s@]+$` 147 | - Must contain `@` and a domain (e.g., example@domain.com). 148 | 149 | 4. **Date of Birth**: `^\d{4}-\d{2}-\d{2}$` 150 | - YYYY-MM-DD format. 151 | 152 | 5. **Zip Code**: `^\d{5,6}$` 153 | - 5-6 digits. 154 | 155 | 6. **Indian Phone Number**: `^(?:\+91|0)?[6-9]\d{9}$` 156 | - Starts with +91 or 0, 10 digits. 157 | 158 | --- 159 | 160 | ### **Advanced Form Features** 161 | 162 | 1. **Real-Time Validation** 163 | - Validate fields as users type. 164 | ```javascript 165 | const emailInput = document.getElementById('email'); 166 | emailInput.addEventListener('input', function () { 167 | const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 168 | if (!emailRegex.test(emailInput.value)) { 169 | emailInput.style.borderColor = "red"; 170 | } else { 171 | emailInput.style.borderColor = "green"; 172 | } 173 | }); 174 | ``` 175 | 176 | 2. **Error Highlighting** 177 | - Highlight invalid fields using CSS or JavaScript. 178 | 179 | 3. **Custom Validation Messages** 180 | ```javascript 181 | username.setCustomValidity("Username must be 3-20 alphanumeric characters."); 182 | ``` 183 | 184 | --- 185 | Regex (regular expressions) is a sequence of characters that define a search pattern, often used for validating strings. Let’s break down how each regex from the examples works: 186 | 187 | --- 188 | 189 | ### **1. Username Validation:** 190 | **Regex:** `^[a-zA-Z0-9]{3,20}$` 191 | 192 | #### Explanation: 193 | - `^`: Matches the beginning of the string. 194 | - `[a-zA-Z0-9]`: Allows lowercase (`a-z`), uppercase (`A-Z`), and numeric (`0-9`) characters. 195 | - `{3,20}`: Ensures the length is between **3 and 20 characters**. 196 | - `$`: Matches the end of the string. 197 | 198 | #### Use Case: 199 | - Valid usernames like: `user123`, `JohnDoe`. 200 | 201 | --- 202 | 203 | ### **2. Password Validation:** 204 | **Regex:** `^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$` 205 | 206 | #### Explanation: 207 | - `^`: Matches the beginning of the string. 208 | - `(?=.*[A-Za-z])`: Positive lookahead to ensure at least one letter (`A-Z` or `a-z`). 209 | - `(?=.*\d)`: Positive lookahead to ensure at least one digit (`0-9`). 210 | - `[A-Za-z\d]`: Allows only letters and digits. 211 | - `{8,}`: Ensures a minimum length of **8 characters**. 212 | - `$`: Matches the end of the string. 213 | 214 | #### Use Case: 215 | - Valid passwords like: `abc12345`, `Password1`. 216 | 217 | --- 218 | 219 | ### **3. Email Validation:** 220 | **Regex:** `^[^\s@]+@[^\s@]+\.[^\s@]+$` 221 | 222 | #### Explanation: 223 | - `^`: Matches the beginning of the string. 224 | - `[^\s@]+`: Matches one or more characters that are **not** whitespace (`\s`) or `@`. This ensures the email starts with valid characters before the `@`. 225 | - `@`: Matches the literal `@` symbol. 226 | - `[^\s@]+`: Matches one or more valid characters after the `@` but before the dot (`.`). 227 | - `\.`: Matches the literal `.` symbol. 228 | - `[^\s@]+`: Matches one or more valid characters after the dot (`.`), typically the domain. 229 | - `$`: Matches the end of the string. 230 | 231 | #### Use Case: 232 | - Valid emails like: `user@example.com`, `john.doe@gmail.com`. 233 | 234 | --- 235 | 236 | ### **4. Date of Birth Validation (YYYY-MM-DD):** 237 | **Regex:** `^\d{4}-\d{2}-\d{2}$` 238 | 239 | #### Explanation: 240 | - `^`: Matches the beginning of the string. 241 | - `\d{4}`: Matches exactly **4 digits** for the year (e.g., `1990`). 242 | - `-`: Matches the literal dash (`-`) separator. 243 | - `\d{2}`: Matches exactly **2 digits** for the month (e.g., `01` for January). 244 | - `-`: Matches the second dash (`-`) separator. 245 | - `\d{2}`: Matches exactly **2 digits** for the day (e.g., `15`). 246 | - `$`: Matches the end of the string. 247 | 248 | #### Use Case: 249 | - Valid dates like: `1990-01-15`, `2023-11-22`. 250 | 251 | --- 252 | 253 | ### **5. Zip Code Validation:** 254 | **Regex:** `^\d{5,6}$` 255 | 256 | #### Explanation: 257 | - `^`: Matches the beginning of the string. 258 | - `\d{5,6}`: Matches exactly **5 or 6 digits**. 259 | - `$`: Matches the end of the string. 260 | 261 | #### Use Case: 262 | - Valid zip codes like: `12345`, `560034`. 263 | 264 | --- 265 | 266 | ### **6. Indian Phone Number Validation:** 267 | **Regex:** `^(?:\+91|0)?[6-9]\d{9}$` 268 | 269 | #### Explanation: 270 | - `^`: Matches the beginning of the string. 271 | - `(?:\+91|0)?`: A non-capturing group that optionally matches either: 272 | - `+91`: The country code for India. 273 | - `0`: A leading zero. 274 | - `[6-9]`: Ensures the first digit of the phone number is between **6 and 9** (valid starting digits for Indian mobile numbers). 275 | - `\d{9}`: Matches exactly **9 digits** after the initial digit. 276 | - `$`: Matches the end of the string. 277 | 278 | #### Use Case: 279 | - Valid phone numbers like: `+918765432109`, `09123456789`, `9876543210`. 280 | 281 | --- 282 | 283 | ### **How Regex Work in Steps** 284 | 285 | 1. **Anchors (`^` and `$`):** 286 | - These define the start (`^`) and end (`$`) of the string, ensuring the entire string matches the pattern. 287 | 288 | 2. **Character Sets (`[]`):** 289 | - Define allowed characters. 290 | - Example: `[a-zA-Z0-9]` allows any letter (lowercase or uppercase) or digit. 291 | 292 | 3. **Quantifiers (`*`, `+`, `{}`):** 293 | - Define the number of times a pattern can occur. 294 | - Example: `{3,20}` allows a length between 3 and 20. 295 | 296 | 4. **Groups (`()`) and Non-Capturing Groups (`(?:)`):** 297 | - Group parts of the regex. 298 | - Non-capturing groups like `(?:)` are used when you don’t need the match stored for later. 299 | 300 | 5. **Lookaheads (`?=`):** 301 | - Ensure a pattern exists without consuming characters. 302 | - Example: `(?=.*\d)` ensures at least one digit exists. 303 | 304 | --- 305 | 306 | ### **Testing Regex** 307 | To test regex: 308 | 1. Use online tools like [regex101.com](https://regex101.com). 309 | 2. Input the regex pattern and test strings to see matches. 310 | 311 | Understanding regex takes practice. Break down patterns into small components, and test with different examples to grasp their functionality. -------------------------------------------------------------------------------- /Class-3 (Form Events)/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 3 | background-color: rgb(237, 242, 255); 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | height: 100vh; 14 | background: linear-gradient(135deg, #eef2f3, #8e9eab); 15 | } 16 | 17 | .container { 18 | width: 350px; 19 | margin: auto; 20 | background: #ffffff; 21 | border-radius: 10px; 22 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); 23 | padding: 20px; 24 | } 25 | 26 | h1 { 27 | text-align: center; 28 | color: #333333; 29 | font-size: 1.8em; 30 | margin-bottom: 20px; 31 | } 32 | 33 | form > * { 34 | display: block; 35 | margin: 15px auto; 36 | } 37 | 38 | input, 39 | textarea { 40 | width: 100%; 41 | border: solid 1px #ccc; 42 | border-radius: 5px; 43 | padding: 10px; 44 | font-size: 1em; 45 | transition: border-color 0.3s ease; 46 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); 47 | } 48 | 49 | input:focus, 50 | textarea:focus { 51 | outline: none; 52 | border-color: #0078d7; 53 | box-shadow: 0 0 5px rgba(0, 120, 215, 0.5); 54 | } 55 | 56 | textarea { 57 | resize: none; 58 | } 59 | 60 | #submit { 61 | padding: 10px; 62 | background: linear-gradient(90deg, #00c851, #007e33); 63 | color: #ffffff; 64 | border: none; 65 | border-radius: 5px; 66 | font-size: 1em; 67 | font-weight: bold; 68 | transition: background 0.3s ease, transform 0.2s ease; 69 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); 70 | } 71 | 72 | #submit:hover { 73 | cursor: pointer; 74 | background: linear-gradient(90deg, #007e33, #00561b); 75 | transform: translateY(-2px); 76 | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /Class-3 (Form Events)/test.md: -------------------------------------------------------------------------------- 1 | ### **Regex Pattern Creation Exercises** 2 | 3 | #### **Questions** 4 | 5 | 1. **Email Validation** 6 | - Create a regex pattern to validate email addresses. The email should: 7 | - Start with alphanumeric characters. 8 | - Contain a single "@" symbol. 9 | - Have a domain name with at least one dot (e.g., `example.com`). 10 | - Allow subdomains (e.g., `mail.example.com`). 11 | 12 | 2. **Phone Number Validation** 13 | - To validate Indian phone numbers, which typically: 14 | - Start with +91 (optional country code) or 0 (optional leading digit). 15 | - Have 10 digits, starting with a digit from 6 to 9. 16 | 17 | 3. **Password Strength Validation** 18 | - Create a regex pattern to validate passwords. A valid password must: 19 | - Be at least 8 characters long. 20 | - Contain at least one uppercase letter, one lowercase letter, one digit, and one special character (e.g., `@`, `#`, `!`, etc.). 21 | 22 | 4. **Username Validation** 23 | - Write a regex to validate usernames. A valid username: 24 | - Contains only alphanumeric characters and underscores (`_`). 25 | - Starts with a letter. 26 | - Is between 3 and 16 characters long. 27 | 28 | 5. **Date Validation** 29 | - Create a regex to validate dates in the format `DD/MM/YYYY`. The pattern should: 30 | - Allow valid day ranges (`01-31`). 31 | - Allow valid month ranges (`01-12`). 32 | - Accept any 4-digit year. 33 | 34 | 6. **URL Validation** 35 | - Write a regex to validate URLs. The URL should: 36 | - Start with `http://` or `https://`. 37 | - Include a domain name (e.g., `www.example.com`). 38 | - Allow optional query parameters and fragments (e.g., `?id=123#section`). 39 | 40 | 7. **Zip Code Validation** 41 | - Create a regex to validate U.S. ZIP codes. The ZIP code: 42 | - Should be 5 digits long (e.g., `12345`). 43 | - Can optionally include a hyphen and 4 more digits (e.g., `12345-6789`). 44 | 45 | --- 46 | 47 | -------------------------------------------------------------------------------- /Class-4 (Event Bubbling and Capturing)/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Event Propagation 7 | 8 | 9 | 23 | 24 |
      25 |
      26 |
      27 |
      28 |
      29 | 30 | 31 | 54 | 55 | -------------------------------------------------------------------------------- /Class-4 (Event Bubbling and Capturing)/notes.md: -------------------------------------------------------------------------------- 1 | ## **Notes on Event Propagation and Delegation** 2 | 3 | --- 4 | 5 | ### **Event Propagation: Bubbling and Capturing** 6 | 7 | --- 8 | 9 | #### **First Code Snippet (Event Bubbling and Capturing)** 10 | 11 | **HTML and CSS Explanation** 12 | - **HTML Structure**: 13 | - We have three nested `
      ` elements: `.grandParent`, `.parent`, and `.child`. 14 | - This nested structure demonstrates how events move through the DOM hierarchy. 15 | 16 | - **CSS**: 17 | - Basic styles applied to each `
      ` make them visible and easy to distinguish. The `.test` class adds a red background to further highlight elements. 18 | 19 | **JavaScript Explanation** 20 | ```javascript 21 | const child = document.querySelector('.child'); 22 | child.addEventListener('click', function () { 23 | console.log('Child element Clicked'); 24 | }, false); 25 | ``` 26 | - **Purpose**: Attaches an event listener to the `.child` element. 27 | - **Parameters**: 28 | - **Callback Function**: Logs a message when the `.child` element is clicked. 29 | - **`false`**: Indicates that the event will follow the **bubbling phase**. Bubbling means the event starts at the target and moves up the DOM tree. 30 | 31 | --- 32 | 33 | ```javascript 34 | const parent = document.querySelector('.parent'); 35 | parent.addEventListener('click', function (e) { 36 | console.log('Parent element Clicked'); 37 | e.stopPropagation(); 38 | }, true); 39 | ``` 40 | - **Purpose**: Attaches an event listener to the `.parent` element. 41 | - **Parameters**: 42 | - **`true`**: Specifies the **capturing phase**, where events are intercepted while moving down the DOM tree. 43 | - **`e.stopPropagation()`**: Prevents the event from propagating further. In this case, it stops the event from moving to `.grandParent`. 44 | 45 | --- 46 | 47 | ```javascript 48 | const grandParent = document.querySelector('.grandParent'); 49 | grandParent.addEventListener('click', function () { 50 | console.log('Grand Parent Clicked'); 51 | }, true); 52 | ``` 53 | - **Purpose**: Logs a message when `.grandParent` is clicked during the **capturing phase**. 54 | 55 | --- 56 | 57 | **How It Works** 58 | 1. **Capturing Phase**: 59 | - The event starts at the root of the DOM tree and travels down to the target. 60 | - Both `.grandParent` and `.parent` have `true` as the third parameter, so their event handlers are triggered during this phase. 61 | 62 | 2. **Target Phase**: 63 | - The event is executed on the target element, `.child`. 64 | 65 | 3. **Bubbling Phase**: 66 | - The event bubbles back up to `.parent` and `.grandParent`. However, `e.stopPropagation()` prevents further bubbling. 67 | 68 | --- 69 | 70 | #### **Key Concepts** 71 | 1. **Event Capturing**: 72 | - Intercept events as they travel down the DOM. 73 | - Use `true` in the `addEventListener` method. 74 | - Ideal for preemptively handling events. 75 | 76 | 2. **Event Bubbling**: 77 | - Capture events as they travel up the DOM after the target phase. 78 | - Use `false` or omit the third parameter. 79 | 80 | --- 81 | 82 | --- 83 | 84 | ### **Event Delegation** 85 | 86 | --- 87 | 88 | #### **Second Code Snippet (Optimized with Event Delegation)** 89 | 90 | **JavaScript Explanation** 91 | ```javascript 92 | const grandParentEle = document.querySelector(".grandParent"); 93 | 94 | grandParentEle.addEventListener("click", function (e) { 95 | if (e.target.classList.contains('child')) { 96 | console.log('Child Clicked'); 97 | } else if (e.target.classList.contains('parent')) { 98 | console.log('parent Clicked'); 99 | } else { 100 | console.log("grandParent Clicked"); 101 | } 102 | }); 103 | ``` 104 | 1. **Attach a Single Listener**: 105 | - Instead of adding separate listeners to `.child`, `.parent`, and `.grandParent`, we attach one listener to `.grandParent`. 106 | 107 | 2. **Use `e.target`**: 108 | - Identifies the actual clicked element (`.child`, `.parent`, or `.grandParent`). 109 | 110 | 3. **Class Matching**: 111 | - `e.target.classList.contains()` checks which element was clicked, ensuring the correct action is executed. 112 | 113 | --- 114 | 115 | **How Event Delegation Works** 116 | - The event listener on `.grandParent` handles clicks for all its descendants. 117 | - Events bubble up to `.grandParent`, enabling centralized management. 118 | - **Advantages**: 119 | - Reduces the number of event listeners. 120 | - Dynamically handles newly added child elements. 121 | 122 | --- 123 | 124 | ### **Applications of Event Delegation** 125 | 1. **Dynamic Content**: 126 | - Handle clicks on elements added to the DOM after page load. 127 | 2. **Performance Optimization**: 128 | - Reduce memory usage by avoiding multiple listeners. 129 | 3. **Simplified Maintenance**: 130 | - Centralize event handling logic for an entire DOM subtree. 131 | 132 | --- 133 | 134 | --- 135 | 136 | ### **Additional Examples** 137 | 138 | #### **Example 1: Capturing Phase Example** 139 | ```javascript 140 | document.querySelector('.container').addEventListener('click', (e) => { 141 | console.log('Container clicked in capturing phase'); 142 | }, true); 143 | ``` 144 | - Logs the message during the capturing phase before bubbling. 145 | 146 | --- 147 | 148 | #### **Example 2: Dynamic Button Clicks** 149 | ```javascript 150 | document.querySelector('.buttonContainer').addEventListener('click', (e) => { 151 | if (e.target.tagName === 'BUTTON') { 152 | console.log(`Button ${e.target.textContent} clicked`); 153 | } 154 | }); 155 | ``` 156 | - Handles clicks for buttons added dynamically to `.buttonContainer`. 157 | 158 | --- 159 | 160 | --- 161 | 162 | ### **Key Takeaways** 163 | 164 | 1. **Event Propagation**: 165 | - **Capturing Phase**: Top-down (root to target). 166 | - **Bubbling Phase**: Bottom-up (target to root). 167 | 168 | 2. **`e.stopPropagation()`**: Stops further propagation of the event. 169 | 170 | 3. **Event Delegation**: 171 | - Attach a single listener to handle events for multiple elements. 172 | - Uses event bubbling to determine the target. 173 | 174 | 4. **Use Cases**: 175 | - Dynamic content, reduced memory footprint, centralized logic. 176 | 177 | 5. **Optimization**: 178 | - Use delegation when working with repetitive or dynamically created elements. 179 | 180 | --- 181 | 182 | By using the concepts of bubbling, capturing, and delegation effectively, you can create efficient, maintainable event-handling solutions for complex web applications. -------------------------------------------------------------------------------- /Class-4 (Event Bubbling and Capturing)/optimized.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 22 | 23 | 24 | 25 |
      26 |
      27 |
      28 |
      29 |
      30 | 31 | 48 | 49 | -------------------------------------------------------------------------------- /Class-5 (Quiz App)/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SST Quiz App Daily Quiz To Test Your JavaScript Knowledge 8 | 9 | 10 | 11 | 12 | 13 |
      14 |
      15 |
      16 |

      SST Quiz

      17 |

      Daily Quiz To Test Your JavaScript Knowledge!

      18 |
      19 | 20 |
      21 |

      22 |

      23 | 24 |

      25 |
      26 | 27 |
      28 |
      29 |

      1. Inside which HTML element do we put the JavaScript?

      30 |
      31 | 32 | 33 |
      34 |
      35 | 36 | 37 |
      38 |
      39 | 40 | 41 |
      42 |
      43 | 44 | 45 |
      46 |
      47 | 48 |
      49 |

      2. Where is the correct place to insert a JavaScript file?

      50 |
      51 | 52 | 53 |
      54 |
      55 | 56 | 57 |
      58 |
      59 | 60 | 61 |
      62 |
      63 | 64 | 65 |
      66 |
      67 | 68 |
      69 |

      3. What is the correct syntax for referring to an external script called "index.js"?

      70 |
      71 | 72 | 73 |
      74 |
      75 | 76 | 77 |
      78 |
      79 | 80 | 81 |
      82 |
      83 | 84 | 85 |
      86 |
      87 | 88 |
      89 |

      4. How do you write "Hello World" in an alert box?

      90 |
      91 | 92 | 93 |
      94 |
      95 | 96 | 97 |
      98 |
      99 | 100 | 101 |
      102 |
      103 | 104 | 105 |
      106 |
      107 | 108 |
      109 |

      5. Which operator is used to assign a value to a variable?

      110 |
      111 | 112 | 113 |
      114 |
      115 | 116 | 117 |
      118 |
      119 | 120 | 121 |
      122 |
      123 | 124 | 125 |
      126 |
      127 |
      128 | 129 |
      130 |
      131 |
      132 |
      133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /Class-5 (Quiz App)/optimized.js: -------------------------------------------------------------------------------- 1 | const correctAns = ["D", "B", "C", "B", "D"]; 2 | let questions = document.querySelectorAll(".question"); 3 | const result = document.querySelector(".result"); 4 | 5 | const form = document.querySelector(".quiz-form"); 6 | form.addEventListener("submit", function (e) { 7 | e.preventDefault(); 8 | let score = 0; 9 | correctAns.forEach((answer, index) => { 10 | const userAnswer = form[`q${index + 1}`].value; // Access input value directly 11 | 12 | if (userAnswer === answer) { 13 | score += 1; 14 | questions[index].classList.add("correct"); 15 | } else { 16 | questions[index].classList.add("wrong"); 17 | } 18 | }); 19 | 20 | result.classList.remove("hide"); 21 | result.querySelector(".score").innerText = `You Scored ${score}/5`; 22 | }); -------------------------------------------------------------------------------- /Class-5 (Quiz App)/script.js: -------------------------------------------------------------------------------- 1 | let correctAns = ["D", "B", "C", "B", "D"]; 2 | 3 | const quizForm = document.querySelector(".quiz-form"); 4 | let questions = document.querySelectorAll('.question') 5 | const result = document.querySelector('.result') 6 | quizForm.addEventListener("submit", function (e) { 7 | e.preventDefault(); 8 | 9 | const userAns = [ 10 | quizForm.q1.value, 11 | quizForm.q2.value, 12 | quizForm.q3.value, 13 | quizForm.q4.value, 14 | quizForm.q5.value, 15 | ]; 16 | 17 | 18 | 19 | // ForEach 20 | 21 | let score = 0 22 | 23 | userAns.forEach(function(ans , index){ 24 | if(ans===correctAns[index]){ 25 | score = score+1 26 | questions[index].classList.add('correct') 27 | 28 | } 29 | else{ 30 | console.log('wrong') 31 | questions[index].classList.add('wrong') 32 | } 33 | }) 34 | 35 | result.classList.remove('hide') 36 | 37 | result.querySelector('.score').innerText = `Your Score is ${score}/5` 38 | 39 | }); 40 | -------------------------------------------------------------------------------- /Class-5 (Quiz App)/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-size: 16px; 6 | font-family: 'Poppins', sans-serif; 7 | text-decoration: none; 8 | list-style: none; 9 | } 10 | 11 | .quiz{ 12 | background-color: #0d479a; 13 | padding: 30px; 14 | } 15 | 16 | .heading{ 17 | margin: 10px auto 40px auto; 18 | } 19 | 20 | .heading .title{ 21 | font-size: 30px; 22 | color: #ffffff; 23 | font-weight: 500; 24 | text-align: center; 25 | } 26 | 27 | .heading .subtitle{ 28 | font-size: 20px; 29 | color: #ffffff; 30 | font-weight: 300; 31 | text-align: center; 32 | } 33 | 34 | .result{ 35 | text-align: center; 36 | min-width: 350px; 37 | max-width: 400px; 38 | margin: 20px auto; 39 | border-radius: 5px; 40 | background-color: #ffffff; 41 | box-shadow: var(--box-shadow); 42 | } 43 | 44 | .result p:first-child{ 45 | padding: 10px 20px; 46 | } 47 | 48 | .hide{ 49 | display: none; 50 | } 51 | 52 | .reload button{ 53 | background-color: #04AA6D; 54 | color: #ffffff; 55 | padding: 10px 20px; 56 | border-radius: 0px 0px 5px 5px; 57 | width: 100%; 58 | border: 0px; 59 | } 60 | 61 | .reload button:hover{ 62 | background-color: #03a369; 63 | cursor: pointer; 64 | } 65 | 66 | .quiz-form{ 67 | max-width: 1000px; 68 | margin: auto; 69 | } 70 | 71 | .question{ 72 | background-color: #ffffff; 73 | padding: 10px 20px; 74 | border-radius: 5px; 75 | margin: 20px 0px; 76 | box-shadow: var(--box-shadow); 77 | } 78 | 79 | .question > * { 80 | font-size: 18px; 81 | } 82 | 83 | .option { 84 | margin-left: 10px; 85 | } 86 | 87 | .correct{ 88 | background-color: green; 89 | } 90 | 91 | .wrong{ 92 | background-color: red; 93 | } 94 | 95 | .submit{ 96 | text-align: center; 97 | margin: 30px 0px; 98 | } 99 | 100 | .submit input { 101 | background-color: #04AA6D; 102 | padding: 5px 25px; 103 | color: #ffffff; 104 | font-size: 22px; 105 | border-radius: 5px; 106 | box-shadow: var(--box-shadow); 107 | border: 0px; 108 | } 109 | 110 | .submit input:hover{ 111 | background-color: #03a369; 112 | cursor: pointer; 113 | } -------------------------------------------------------------------------------- /Class-6(Date and Time)/countdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Count Down New Year 7 | 8 | 53 | 54 | 55 | 56 |
      57 |

      New Year Countdown

      58 |

      Time left until New Year

      59 | 60 |

      00:00:00:00

      61 |
      62 | 63 | 64 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /Class-6(Date and Time)/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Date and Time 7 | 8 | 9 | 10 | 11 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Class-7 (Kanban Board)/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Kanaban Board Class work 8 | 9 | 10 | 11 | 12 | 13 | 14 |
      15 |
      16 |
      17 |
      18 |
      19 |
      20 |
      21 | 22 | 23 |
      24 | 25 |
      26 | 27 |
      28 | 29 |
      30 | 31 |
      32 |
      33 |
      34 | 35 | 36 | 37 | 38 |
      39 | 47 | 48 | 49 | 50 | 51 | 52 |
      53 | 54 | 55 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Class-7 (Kanban Board)/notesc2.md: -------------------------------------------------------------------------------- 1 | # Full Stack LLD & Projects: JavaScript-8: Kanban Board-2(DOM Implementation & Manipulation) 2 | 3 | --- 4 | title: Agenda 5 | description: 6 | duration: 900 7 | card_type: cue_card 8 | --- 9 | 10 | **Agenda of this Lecture:** 11 | 12 | 13 | * Modal Popup with Toggle 14 | * Ticket Generation 15 | * Adding Task, colour, ID to generated ticket 16 | * Ticket Removal 17 | 18 | --- 19 | title: Pop up modal Generation 20 | description: 21 | duration: 900 22 | card_type: cue_card 23 | --- 24 | 25 | 1. Whenever the (+) button is clicked we need to open the modal pop up box so that we can enter our Task and whenerver we click on the button (+) again the pop up closes. 26 | 27 | How we will Implement this? 28 | 29 | 1. So to implement this we can use a very simple technique i.e we can set up a flag , 30 | 2. by deafault we will keep it to `false`, so nothing will happen but as soon as we click the (+) button we will change the flag to `true` , and when it is true we will open the modal pop up 31 | 3. Again when you click on this now the flag will again turn back to `false` and the pop up will close 32 | 33 | 34 | **Implementation** 35 | 36 | **create a script.js file and link it with project's html and start wrting JS code** 37 | 38 | 39 | 40 | ```javascript 41 | let addBtn = document.querySelector('.add-btn') 42 | let modalCont = document.querySelector('.modal-cont') 43 | let addTaskFlag = false 44 | 45 | addBtn.addEventListener('click' , function(){ 46 | // Display the model 47 | addTaskFlag = !addTaskFlag 48 | 49 | if(addTaskFlag == true){ 50 | modalCont.style.display = 'flex' 51 | } 52 | else{ 53 | modalCont.style.display = 'none' 54 | } 55 | 56 | }) 57 | ``` 58 | This code snippet is a simple JavaScript implementation for toggling the visibility of a modal container element on a web page when a button is clicked. Here's a step-by-step explanation of what each part of the code is doing: 59 | 60 | 1. `let addBtn = document.querySelector('.add-btn')`: This line selects the first HTML element with the class name `add-btn` and stores a reference to it in the variable `addBtn`. This element is intended to be a button that, when clicked, will trigger the display or hiding of the modal container. 61 | 62 | 2. `let modalCont = document.querySelector('.modal-cont')`: Similar to the first line, this selects the first HTML element with the class name `modal-cont` and stores a reference to it in the variable `modalCont`. This element is the modal container that will be shown or hidden. 63 | 64 | 3. `let addTaskFlag = false`: This line initializes a boolean flag named `addTaskFlag` to `false`. This flag will be used to keep track of the modal's visibility state—whether it is currently shown (`true`) or hidden (`false`). 65 | 66 | 4. `addBtn.addEventListener('click' , function(){ ... })`: This line adds an event listener to the `addBtn` element. The listener listens for `click` events, meaning it will execute the provided function every time the `addBtn` is clicked. 67 | 68 | Inside the event listener function: 69 | 70 | a. `addTaskFlag = !addTaskFlag`: This toggles the value of `addTaskFlag`. If it was `false`, it becomes `true`, and vice versa. This effectively changes the state of the modal's visibility each time the button is clicked. 71 | 72 | b. `if(addTaskFlag == true){`: This checks if `addTaskFlag` is `true`. If so, it means the modal should be displayed. 73 | 74 | - `modalCont.style.display = 'flex'`: This line changes the CSS `display` property of the `modalCont` element to `flex`, making it visible. Flexbox is a CSS layout model that allows items within a container to be laid out in a flexible, responsive manner. 75 | 76 | c. `else {`: If `addTaskFlag` is not `true` (i.e., it is `false`), this block will execute. 77 | 78 | - `modalCont.style.display = 'none'`: This sets the `display` property of `modalCont` to `none`, effectively hiding it from view. 79 | 80 | 81 | --- 82 | title: Ticket Generation 83 | description: 84 | duration: 900 85 | card_type: cue_card 86 | --- 87 | 88 | ### Explanation 89 | 90 | Now , let's try to generate a task ticket, which involves creating a function to dynamically generate new task tickets. 91 | 92 | In the file `script.js` we will add this function: 93 | 94 | ```javascript 95 | function createTicket() { 96 | // Create a new ticket container element 97 | let ticketCont = document.createElement('div'); 98 | } 99 | ``` 100 | 101 | Now we will add **class** to this particular div using the `setAttribute` : 102 | 103 | ```javascript 104 | function createTicket() { 105 | // Create a new ticket container element 106 | let ticketCont = document.createElement('div'); 107 | 108 | // Set the class attribute of the ticket container 109 | ticketCont.setAttribute('class', 'ticket-cont'); // 110 | } 111 | ``` 112 | 113 | Whenever this function is called, a new ticket will be created with class `ticket-cont`. 114 | 115 | As `ticketCont` contains 3 more divs inside, we will create them inside this function using `innerHTML` 116 | 117 | ```javascript 118 | function createTicket() { 119 | // Create a new ticket container element 120 | let ticketCont = document.createElement('div'); 121 | ticketCont.setAttribute('class', 'ticket-cont'); 122 | 123 | // Create the HTML content for the ticket container 124 | ticketCont.innerHTML = ` 125 |
      126 |
      12345/div> 127 |
      Random Task
      ` 128 | 129 | mainCont.appendChild(ticketCont) 130 | } 131 | ``` 132 | 133 | Here we have created function named `createTicket()` that dynamically generates a new HTML element structure representing a "ticket" and appends it to an existing element in the DOM (Document Object Model). Here's a step-by-step explanation: 134 | 135 | 1. **Define a New Ticket Container Element**: 136 | - `let ticketCont = document.createElement('div');` 137 | This line creates a new `
      ` element and stores it in the variable `ticketCont`. This `
      ` will serve as the container for the ticket content. 138 | 139 | 2. **Set a Class Attribute for the Ticket Container**: 140 | - `ticketCont.setAttribute('class', 'ticket-cont');` 141 | This line sets the `class` attribute of the `ticketCont` `
      ` to `'ticket-cont'`. This class can be used to apply specific CSS styles to the ticket container. 142 | 143 | 3. **Create the HTML Content for the Ticket Container**: 144 | - The `ticketCont.innerHTML = `...`` section assigns a string of HTML content to the `innerHTML` property of the `ticketCont` element. This HTML string includes the structure and content of the ticket, which is composed of three parts: 145 | - A `
      ` with a class of `"ticket-color"` which could be used to display a color indicator for the ticket. 146 | - A `
      ` with a class of `"ticket-id"` which contains a hardcoded ticket ID `12345`. There's a typo here: the closing tag should be `
      ` instead of `/div>`. 147 | - A `
      ` with a class of `"task-area"` which contains the text `Random Task`, representing the task or content of the ticket. 148 | 149 | 4. **Append the Ticket Container to the Main Container**: 150 | - `mainCont.appendChild(ticketCont)` 151 | This line adds the newly created `ticketCont` element as a child to an existing element in the DOM identified by the variable `mainCont`. The `mainCont` variable is presumed to reference an existing element on the page, acting as the main container for these tickets. This action effectively inserts the ticket into the webpage, making it visible to the user. 152 | 153 | the `createTicket()` function dynamically constructs a new ticket element with a specific structure and content, then adds this ticket to a parent container on the webpage. 154 | 155 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/613/original/upload_ed6901a16250a577c26b8e2795b1f89d.png?1695229185) 156 | 157 | 158 | --- 159 | title: Adding Event Listener to Generate Ticket 160 | description: 161 | duration: 900 162 | card_type: cue_card 163 | --- 164 | 165 | ### Explanation 166 | 167 | The `addEventListener` method is used to attach an event listener to a DOM element, allowing you to respond to specific events like clicks, key presses, mouse movements, etc. 168 | 169 | We add an event listener to the `modalCont` element for the 'keydown' event. This event occurs when a key on the keyboard is pressed and then released. 170 | 171 | ```javascript 172 | modalCont.addEventListener('keydown', function(e) { 173 | let key = e.key; 174 | 175 | if (key === 'Shift') { 176 | createTicket(); // Call the createTicket function to create a new ticket 177 | modalCont.style.display = 'none'; // Hide the modal 178 | textArea.value = ''; // Clear the textarea's content 179 | } 180 | }) 181 | ``` 182 | 183 | This code adds an event listener to an element referred to as `modalCont`, which listens for `keydown` events—these are triggered when a user presses a key while the element has focus. The functionality implemented in this listener performs specific actions when the `Shift` key is pressed. Here's a detailed breakdown: 184 | 185 | 1. **Add Event Listener**: 186 | - `modalCont.addEventListener('keydown', function(e) { ... })` 187 | This line attaches a `keydown` event listener to the `modalCont` element. Whenever a key is pressed down while this element is focused, the specified anonymous function will be called, receiving the event object `e` as its argument. 188 | 189 | 2. **Get the Pressed Key**: 190 | - `let key = e.key;` 191 | Within the event handler function, this line retrieves the `key` property from the event object `e`. The `key` property represents the value of the key that was pressed. 192 | 193 | 3. **Conditionally Execute Actions for the Shift Key**: 194 | - The `if (key === 'Shift') { ... }` block checks if the pressed key is the `Shift` key. If it is, the code block inside the `if` statement is executed, which involves three actions: 195 | - `createTicket();` 196 | This line calls the `createTicket()` function, which, as described previously, creates a new ticket element and adds it to the page. 197 | - `modalCont.style.display = 'none';` 198 | This line hides the `modalCont` element by setting its `display` style property to `'none'`. This is typically used to hide modal dialogs or similar components after completing an action. 199 | - `textArea.value = '';` 200 | This line clears the content of an element referred to by `textArea`. Presumably, `textArea` is a variable referencing a ` 530 | 531 |
      532 |
      533 |
      534 |
      535 |
      536 |
      537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 |
      546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | ``` 554 | 555 | 556 | ```css 557 | 558 | *{ 559 | box-sizing: border-box; 560 | } 561 | 562 | 563 | body{ 564 | margin: 0; 565 | padding: 0; 566 | } 567 | 568 | .toolbox-cont{ 569 | height: 5rem; 570 | background-color: #4b4b4b; 571 | display: flex; 572 | align-items: center; 573 | 574 | } 575 | 576 | .toolbox-cont > *{ 577 | margin-left: 4rem; 578 | } 579 | 580 | 581 | .toolbox-priority-cont{ 582 | height: 3.5rem; 583 | width: 18rem; 584 | background-color:#3d3d3d; 585 | display: flex; 586 | align-items: center; 587 | justify-content: space-evenly; 588 | 589 | } 590 | 591 | .toolbox-priority-cont>*:hover{ 592 | background-color: #485460; 593 | } 594 | 595 | 596 | 597 | .color{ 598 | height: 1.5rem; 599 | width: 3rem; 600 | } 601 | 602 | 603 | .lightpink{ 604 | background-color: lightpink; 605 | } 606 | 607 | 608 | .lightgreen{ 609 | background-color: lightgreen; 610 | } 611 | 612 | 613 | .lightblue{ 614 | background-color: lightblue; 615 | } 616 | 617 | .black{ 618 | background-color: black; 619 | } 620 | 621 | 622 | .action-btn-cont{ 623 | height: 3.5rem; 624 | width: 8rem; 625 | background-color:#3d3d3d ; 626 | display: flex; 627 | } 628 | 629 | 630 | .action-btn-cont>*{ 631 | display: flex; 632 | width: 50%; 633 | font-size: 2rem; 634 | color: white; 635 | justify-content: center; 636 | align-items: center; 637 | } 638 | 639 | 640 | .add-btn:hover{ 641 | background-color: #4BB543; 642 | } 643 | 644 | .remove-btn:hover{ 645 | background-color: #4BB543; 646 | } 647 | 648 | 649 | 650 | 651 | 652 | 653 | .main-cont{ 654 | display: flex; 655 | gap:2rem; 656 | justify-content: center; 657 | padding: 2rem; 658 | flex-wrap: wrap; 659 | } 660 | 661 | .ticket-cont{ 662 | height: 12rem; 663 | width: 15rem; 664 | background-color: coral; 665 | } 666 | 667 | .ticket-color{ 668 | height: 1rem; 669 | } 670 | 671 | .ticket-id{ 672 | background-color: yellow; 673 | height: 2rem; 674 | } 675 | 676 | .ticket-lock{ 677 | display: flex; 678 | 679 | justify-content: flex-end; 680 | margin-top: 90px; 681 | margin-right: 5px; 682 | font-size: 1.5rem; 683 | } 684 | 685 | .modal-cont{ 686 | height: 50vh; 687 | width: 45vw; 688 | display: flex; 689 | background-color: lightsalmon; 690 | position: absolute; 691 | top:30%; 692 | left: 27%; 693 | display: none; 694 | 695 | 696 | } 697 | 698 | 699 | 700 | .textArea-cont{ 701 | height: 100%; 702 | width: 75%; 703 | resize: none; 704 | outline: none; 705 | border: none; 706 | background-color: #dfe4ea; 707 | font-size: 2rem; 708 | color: black; 709 | } 710 | 711 | 712 | .priority-colors-container{ 713 | height: 100%; 714 | width: 25%; 715 | display: flex; 716 | flex-direction: column; 717 | background-color: #4b4b4b; 718 | align-items: center; 719 | justify-content: space-around; 720 | 721 | } 722 | 723 | 724 | .priority-color{ 725 | height: 3rem; 726 | width: 5rem; 727 | } 728 | 729 | 730 | .active{ 731 | border: 5px solid lightsalmon; 732 | } 733 | 734 | 735 | ``` 736 | 737 | ```js 738 | 739 | // Buttons and Flags 740 | let addBtn = document.querySelector('.add-btn') 741 | let addTaskFlag = false 742 | let removeBtn = document.querySelector('.remove-btn') 743 | let removeTaskFlag = false 744 | 745 | // Elements for Modal pop up box and ticket 746 | let modalCont = document.querySelector('.modal-cont') 747 | 748 | let textAreaCont = document.querySelector('.textArea-cont') 749 | 750 | //Elements for Tickets 751 | let mainCont = document.querySelector('.main-cont') 752 | 753 | // Elements for color Selection 754 | let allPriorityColors = document.querySelectorAll('.priority-color') 755 | let colors = ["lightpink", "lightgreen", "lightblue", "black"]; 756 | let modalPriorityColor = colors[colors.length - 1]; 757 | 758 | 759 | 760 | 761 | 762 | addBtn.addEventListener('click' , function(){ 763 | // Display the model 764 | addTaskFlag = !addTaskFlag 765 | 766 | if(addTaskFlag == true){ 767 | modalCont.style.display = 'flex' 768 | } 769 | else{ 770 | modalCont.style.display = 'none' 771 | } 772 | 773 | }) 774 | 775 | 776 | function createTicket(ticketColor, ticketID, ticketTask) { 777 | // Create a new ticket container element 778 | let ticketCont = document.createElement('div'); 779 | ticketCont.setAttribute('class', 'ticket-cont'); 780 | 781 | // Create the HTML content for the ticket container 782 | ticketCont.innerHTML = ` 783 |
      784 |
      ${ticketID}
      785 |
      ${ticketTask}
      786 | `; 787 | 788 | // Append the ticket container to the main container 789 | mainCont.appendChild(ticketCont); 790 | } 791 | 792 | //Selecting a color and setting it for the task 793 | allPriorityColors.forEach(function(colorElem) { 794 | colorElem.addEventListener('click', function() { 795 | // Remove 'active' class from all priority colors 796 | allPriorityColors.forEach(function(priorityColorElem) { 797 | priorityColorElem.classList.remove('active'); 798 | }); 799 | 800 | // Add 'active' class to the clicked colorElem 801 | colorElem.classList.add('active'); 802 | 803 | modalPriorityColor = colorElem.classList[0]; // Update modalPriorityColor 804 | }); 805 | }); 806 | 807 | // Event listener for 'Shift' key press in modalCont 808 | modalCont.addEventListener('keydown', function(e) { 809 | let key = e.key; 810 | 811 | if (key === 'Shift') { 812 | let taskContent = textAreaCont.value; // Get the content from the textarea 813 | let ticketID = shortid(); // Generate a unique ticket ID 814 | createTicket(modalPriorityColor, ticketID, taskContent); // Create a new ticket with the selected color, ticket ID, and task content 815 | modalCont.style.display = 'none'; // Hide the modal 816 | textAreaCont.value = ''; // Clear the textarea's content 817 | } 818 | }); 819 | 820 | 821 | 822 | 823 | 824 | ``` -------------------------------------------------------------------------------- /Class-7 (Kanban Board)/notesc3.md: -------------------------------------------------------------------------------- 1 | # Full Stack LLD & Projects: JavaScript-9: Kanban Board-3(Bussiness Logics & Local Storage) 2 | 3 | --- 4 | 5 | title: Agenda 6 | description: 7 | duration: 900 8 | card_type: cue_card 9 | 10 | --- 11 | 12 | **Agenda of this Lecture:** 13 | 14 | - Locking Mechanism 15 | - Changing the Priority color of the Task 16 | - Filtering out Task with using the priority color filter 17 | - Showing All Tasks on db click 18 | 19 | --- 20 | 21 | title: Locking Mechanism 22 | description: 23 | duration: 900 24 | card_type: cue_card 25 | 26 | --- 27 | 28 | ### Explanation 29 | 30 | Currently we have implemented Ticket geneartion and removal from the modal pop up with ID color and Task, Now we will be adding a lock so that a task can be edited of a ticket if it needs to be updated and we can lock it again 31 | 32 | Hence, we will be implementing the lock in this section 33 | 34 | We can use the **font-awesome** Icon libray again and get a lock icon for our tasks. 35 | 36 | ```javascript 37 | function createTicket(ticketColor, ticketID, ticketTask) { 38 | // Create a new ticket container element 39 | let ticketCont = document.createElement("div"); 40 | ticketCont.setAttribute("class", "ticket-cont"); 41 | 42 | // Create the HTML content for the ticket container 43 | ticketCont.innerHTML = ` 44 |
      45 |
      ${ticketID}
      46 |
      ${ticketTask}
      47 | // Lock Icon div added below 48 |
      49 | `; 50 | 51 | // Append the ticket container to the main container 52 | mainCont.appendChild(ticketCont); 53 | 54 | handleRemoval(ticketCont); 55 | } 56 | ``` 57 | 58 | - We have added an additional `div` element with the class `ticket-lock` to represent the lock icon for each ticket. 59 | 60 | - Inside the `ticket-lock` div, we are using Font Awesome's icon syntax to include the lock icon using the fa-lock class from the `fa-solid` style. 61 | 62 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/638/original/1.png?1695233411) 63 | 64 | Now we have added the lock, but we need to make it functional now: 65 | 66 | ```javascript 67 | let lockClose = "fa-lock"; 68 | let lockOpen = "fa-lock-open"; 69 | 70 | function handleLock(ticket) { 71 | let ticketLockElem = ticket.querySelector(".ticket-lock"); 72 | let ticketLockIcon = ticketLockElem.children[0]; 73 | 74 | ticketLockIcon.addEventListener("click", function () { 75 | console.log("Lock Selected"); // Added single quotes around the log message 76 | if (ticketLockIcon.classList.contains(lockClose)) { 77 | ticketLockIcon.classList.remove(lockClose); 78 | ticketLockIcon.classList.add(lockOpen); 79 | } else { 80 | ticketLockIcon.classList.remove(lockOpen); 81 | ticketLockIcon.classList.add(lockClose); 82 | } 83 | }); 84 | } 85 | ``` 86 | 87 | This code snippet is designed to toggle the lock status of a ticket in a web application, changing its visual representation by switching icons. 88 | 89 | point-by-point explanation of what each part of the code is doing: 90 | 91 | 1. **Variable Declarations:** 92 | 93 | - `let lockClose = 'fa-lock';` declares a variable `lockClose` and assigns it the string `'fa-lock'`. This string corresponds to a CSS class used to display a "locked" icon from the FontAwesome icon library 94 | - `let lockOpen = 'fa-lock-open';` declares another variable `lockOpen` and assigns it the string `'fa-lock-open'`. Similarly, this string is expected to represent a CSS class for an "unlocked" icon. 95 | 96 | 2. **Function Definition - `handleLock(ticket)`:** 97 | This section defines a function named `handleLock` that takes a single `ticket`. The function is designed to add interactive functionality to a lock icon within a ticket element in the DOM (Document Object Model). 98 | 99 | - **Finding the Ticket's Lock Element:** 100 | 101 | - `let ticketLockElem = ticket.querySelector('.ticket-lock');` uses the `querySelector` method on the `ticket` element to find the first child element with the class `.ticket-lock`. This child element is stored in the `ticketLockElem` variable. 102 | 103 | - `let ticketLockIcon = ticketLockElem.children[0];` accesses the first child element of `ticketLockElem` and assigns it to `ticketLockIcon`. This child the icon that visually represents the lock's current status (locked or unlocked). 104 | 105 | - **Adding an Event Listener to the Lock Icon:** 106 | 107 | - `ticketLockIcon.addEventListener('click', function() {...});` adds a click event listener to `ticketLockIcon`. When the icon is clicked, the anonymous function provided as the second argument to `addEventListener` is executed. 108 | 109 | - **Inside the Event Listener Function:** 110 | 111 | - `console.log('Lock Selected');` logs the message "Lock Selected" to the console whenever the lock icon is clicked. This serves as a simple way to confirm that the click event is being registered. 112 | 113 | - The `if` statement checks if `ticketLockIcon` currently has the class corresponding to a closed lock (`lockClose`): 114 | 115 | - If true (`ticketLockIcon.classList.contains(lockClose)`), it means the lock is currently shown as closed. The code then removes the `lockClose` class and adds the `lockOpen` class, visually changing the icon to an open lock. 116 | 117 | - If false, it implies the lock is shown as open. The code removes the `lockOpen` class and adds the `lockClose` class, changing the icon back to a closed lock. 118 | 119 | This code toggles the visual state of a lock icon on a ticket between an open and closed lock each time the icon is clicked, utilizing CSS classes to change the icon's appearance. The use of `classList.contains`, `classList.add`, and `classList.remove` allows for this dynamic change in class assignments, which in turn changes the icon displayed to the user based on the ticket's lock status. 120 | 121 | Now to make the content editable inside the task section whenever the lock is open, we will make the following changes: 122 | 123 | ```javascript 124 | let lockClose = "fa-lock"; 125 | let lockOpen = "fa-lock-open"; 126 | 127 | function handleLock(ticket) { 128 | let ticketLockElem = ticket.querySelector(".ticket-lock"); 129 | let ticketLockIcon = ticketLockElem.children[0]; 130 | 131 | let ticketTaskArea = ticket.querySelector(".task-area"); // Corrected selector 132 | 133 | ticketLockIcon.addEventListener("click", function () { 134 | console.log("Lock Selected"); 135 | if (ticketLockIcon.classList.contains(lockClose)) { 136 | ticketLockIcon.classList.remove(lockClose); 137 | ticketLockIcon.classList.add(lockOpen); 138 | ticketTaskArea.setAttribute("contenteditable", "true"); // Changed 'contenteditable', 'true' 139 | } else { 140 | ticketLockIcon.classList.remove(lockOpen); 141 | ticketLockIcon.classList.add(lockClose); 142 | ticketTaskArea.setAttribute("contenteditable", "false"); // Changed 'contenteditable', 'false' 143 | } 144 | }); 145 | } 146 | ``` 147 | 148 | Now let's add functionality related to a "task area" within a ticket, allowing it to become editable or non-editable based on the lock status: 149 | 150 | 1. **New Variable Declaration for the Ticket Task Area:** 151 | 152 | - `let ticketTaskArea = ticket.querySelector('.task-area');` is a new line of code that finds and assigns the first element within the `ticket` that matches the `.task-area` selector. 153 | 154 | - This element, stored in `ticketTaskArea`, represents an area within the ticket that contains task-related content that can be edited. 155 | 156 | 2. **Adjustments Within the Event Listener Function:** 157 | The functionality to make the task area editable or non-editable based on the lock status is introduced with the following lines inside the `if` statement's branches: 158 | 159 | - When the lock is opened (`if` branch): 160 | 161 | - `ticketTaskArea.setAttribute('contenteditable', 'true');` is a new line that sets the `contenteditable` attribute of the `ticketTaskArea` to `'true'`. This makes the task area editable, allowing users to modify its content directly in the browser. This change is applied when the lock icon is clicked and the lock is transitioning from closed to open. 162 | 163 | - When the lock is closed (`else` branch): 164 | - `ticketTaskArea.setAttribute('contenteditable', 'false');` replaces the task area's `contenteditable` attribute value with `'false'`. This action reverses the editability of the task area, making it non-editable to the user. This occurs when the lock icon is clicked and the lock transitions from open to closed. 165 | - This allows for a more interactive and secure way to manage content within each ticket, preventing unintended edits when the ticket is "locked". 166 | 167 | This is how we have implemented the Lock Mechanism for the ticket 168 | 169 | --- 170 | 171 | title: Changing the Priority color of the Task 172 | description: 173 | duration: 900 174 | card_type: cue_card 175 | 176 | --- 177 | 178 | ### Explanation 179 | 180 | Now , We have created the Ticket and have implemented the Lock Functionality. 181 | 182 | Now , Suppose you want to change the priority of the task as well , Suppose a ticket is in lightpink color and you want to change it to lightblue , lightgreen or black , (you just want to move a particlular task from one status to another) 183 | 184 | How will you do it? 185 | 186 | In this section we will handle the color of the tasks 187 | 188 | ```javascript 189 | function handleColor(ticket) { 190 | let ticketColorBand = ticket.querySelector(".ticket-color"); // Corrected selector 191 | ticketColorBand.addEventListener("click", function () { 192 | let currentColor = ticketColorBand.classList[0]; // Changed index to 0 193 | 194 | let currentColorIdx = colors.findIndex(function (color) { 195 | return currentColor === color; 196 | }); 197 | 198 | currentColorIdx++; // Increment the index 199 | 200 | let newTicketColorIdx = currentColorIdx % colors.length; // Corrected variable name 201 | let newTicketColor = colors[newTicketColorIdx]; // Corrected variable name 202 | 203 | ticketColorBand.classList.remove(currentColor); // Corrected spelling 204 | ticketColorBand.classList.add(newTicketColor); // Corrected spelling 205 | }); 206 | } 207 | ``` 208 | 209 | function `handleColor` is designed to change the color of a specific element within a "ticket" based on user interaction (a click). 210 | 211 | Here's a step-by-step explanation of what the code does: 212 | 213 | 1. **Function Definition (`handleColor`)**: The function `handleColor` is defined to take a single parameter, `ticket`, which is expected to be a DOM element that represents a ticket on the webpage. 214 | 215 | 2. **Selecting the `.ticket-color` Element**: Inside the function, `ticket.querySelector('.ticket-color')` is called to select the first element with the class `.ticket-color` that is a descendant of the `ticket` element. This element is stored in the variable `ticketColorBand`. 216 | 217 | 3. **Adding an Event Listener**: An event listener for the "click" event is added to `ticketColorBand`. This means that the function provided as the second argument to `addEventListener` will be executed whenever `ticketColorBand` is clicked. 218 | 219 | 4. **Inside the Click Event Listener Function**: 220 | 221 | - **Getting the Current Color**: The current color class of `ticketColorBand` is assumed to be stored in its first class, which is accessed with `ticketColorBand.classList[0]`. This current color is stored in the variable `currentColor`. 222 | 223 | - **Finding the Index of the Current Color**: The index of `currentColor` within the `colors` array is found using `colors.findIndex()`. This method takes a function that returns `true` for the element that matches the current color. The index of this color in the `colors` array is stored in `currentColorIdx`. 224 | 225 | - **Incrementing the Color Index**: The color index (`currentColorIdx`) is incremented by 1 to move to the next color in the `colors` array. If this increment makes the index equal to the length of the `colors` array, it will wrap around to 0 in the next step due to the modulo operation. 226 | 227 | - **Calculating the New Color Index**: The new color index is calculated using `currentColorIdx % colors.length`. This ensures that if the incremented index is beyond the last index of the `colors` array, it wraps around to the beginning (cyclic behavior). 228 | 229 | - **Getting the New Color**: The new color class to be applied is retrieved from the `colors` array using the new index (`newTicketColorIdx`) and stored in `newTicketColor`. 230 | 231 | - **Updating the Element’s Class**: The current color class is removed from `ticketColorBand` using `classList.remove(currentColor)`, and the new color class is added using `classList.add(newTicketColor)`. This changes the visual appearance of the `ticketColorBand` element to reflect the new color. 232 | 233 | In summary, this function allows a user to cycle through a predefined list of color classes for an element within a ticket by clicking on it, changing its visual appearance each time it's clicked. 234 | 235 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/639/original/2.png?1695233433) 236 | 237 | --- 238 | 239 | title: Filtering out Task with using the priority color filter 240 | description: 241 | duration: 900 242 | card_type: cue_card 243 | 244 | --- 245 | 246 | ### Explanation 247 | 248 | In this feature, we need to filter the task according to the priority color. 249 | 250 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/640/original/3.png?1695233456) 251 | 252 | ```javascript 253 | let toolboxColors = document.querySelectorAll(".color"); 254 | 255 | for (let i = 0; i < toolboxColors.length; i++) { 256 | toolboxColors[i].addEventListener("click", function () { 257 | let selectedToolboxColor = toolboxColors[i].classList[0]; 258 | 259 | let allTickets = document.querySelectorAll(".ticket-cont"); // Corrected selector 260 | for (let j = 0; j < allTickets.length; j++) { 261 | allTickets[j].remove(); // Removed square brackets and added j to index 262 | 263 | let filteredTickets = ticketsArr.filter(function (ticket) { 264 | return selectedToolboxColor === ticket.ticketColor; 265 | }); 266 | 267 | filteredTickets.forEach(function (filteredTicket) { 268 | createTicket( 269 | filteredTicket.ticketColor, 270 | filteredTicket.ticketTask, 271 | filteredTicket.ticketID 272 | ); 273 | }); 274 | } 275 | }); 276 | } 277 | ``` 278 | 279 | The code is designed to filter and display these tickets based on their color when a color from a toolbox is clicked. Here's a step-by-step breakdown: 280 | 281 | 1. **Select Elements by Class Name**: `let toolboxColors = document.querySelectorAll('.color');` 282 | 283 | - This line selects all elements with the class name `color` and stores them in the variable `toolboxColors`. These elements represent different color options in a toolbox UI component. 284 | 285 | 2. **Loop Over Color Options**: `for (let i = 0; i < toolboxColors.length; i++) { ... }` 286 | 287 | - This loop iterates over each element in `toolboxColors`. Each element represents a color option in the toolbox. 288 | 289 | 3. **Add Click Event Listeners to Each Color Option**: `toolboxColors[i].addEventListener('click', function() { ... });` 290 | 291 | - For each color option found in the toolbox, the code attaches a click event listener. When a color option is clicked, the function inside the event listener is executed. 292 | 293 | 4. **Get Selected Color**: `let selectedToolboxColor = toolboxColors[i].classList[0];` 294 | 295 | - Inside the event listener function, the code retrieves the first class name of the clicked color option and stores it in `selectedToolboxColor`. This assumes that the first class name of the color option element represents the color. 296 | 297 | 5. **Select All Ticket Elements**: `let allTickets = document.querySelectorAll('.ticket-cont');` 298 | 299 | - The code selects all elements with the class name `ticket-cont`, which represent individual ticket containers in the UI, and stores them in `allTickets`. 300 | 301 | 6. **Remove All Ticket Elements**: `for (let j = 0; j < allTickets.length; j++) { allTickets[j].remove(); }` 302 | 303 | - This loop iterates over each ticket container element in `allTickets` and removes it from the document. This effectively clears all displayed tickets. 304 | 305 | 7. **Filter Tickets Based on Selected Color**: 306 | - After removing all tickets, the code immediately filters `ticketsArr` (presumably an array of ticket objects available in the larger scope) to include only those tickets whose `ticketColor` matches the selected color (`selectedToolboxColor`). 307 | ```js 308 | let filteredTickets = ticketsArr.filter(function (ticket) { 309 | return selectedToolboxColor === ticket.ticketColor; 310 | }); 311 | ``` 312 | 8. **Create and Display Filtered Tickets**: `filteredTickets.forEach(function(filteredTicket) { ... });` 313 | - For each ticket in `filteredTickets`, the code calls a function `createTicket` with the ticket's color, task, and ID as arguments. The `createTicket` function (not shown in the snippet) presumably creates a new ticket element for each filtered ticket and adds it back to the UI, thus displaying only tickets that match the selected color. 314 | 315 | This code enables a user interface feature where clicking on a color in a toolbox filters and displays tickets of that color. 316 | 317 | Now, Here you will Notice an Issue! 318 | 319 | --- 320 | 321 | title: Issue of Repetition in Filtered Tasks 322 | description: This segment elaborates on the progress made in the previous session and outlines the challenge of duplicated entries arising during ticket filtering. 323 | duration: 1500 324 | card_type: cue_card 325 | 326 | --- 327 | 328 | A new issue has arisen. Upon initial usage, the filter buttons function as intended. Yet, upon subsequent clicks, a problem arises where duplicate tickets of the selected color are generated. 329 | 330 | **[Ask the leaners]** 331 | What might be the underlying cause of this problem? 332 | 333 | To address this issue, we're planning to implement a validation process using unique identifier to prevent the occurrence of duplicate tickets. 334 | 335 | This is the code that we have implemented till now for filtering tickets. 336 | 337 | We've executed the loop that iterates through the toolbox colors, covering every index. For each color dip, we've attached corresponding event listeners. When a click event occurs, our first step is to determine which color dip or filter was clicked – for instance, selecting black would mean retrieving tasks labeled with a black priority color. 338 | 339 | Following the color selection from the toolbox, we proceed to match that color with the colors associated with each ticket. We apply a filtering process to narrow down the array of tickets to only include those that match the selected color. The result is an array of filtered tickets, where each ticket object contains information like color values, task details, and IDs. 340 | 341 | At this juncture, we remove the default set of tickets and replace them with the newly filtered array. This is the approach we discussed in the previous session. However, an issue arises when we repeatedly select a color, leading to the duplication of arrays. 342 | 343 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/630/original/1.png?1695232771) 344 | 345 | #### Pseudocode 346 | 347 | ```javascript 348 | for (let i = 0; i < toolboxColors.length; i++) { 349 | toolboxColors[i].addEventListener("click", function () { 350 | let selectedToolBoxColor = toolboxColors[i].classList[0]; 351 | 352 | let filteredTickets = ticketsArr.filter(function (ticket) { 353 | return selectedToolBoxColor === ticket.ticketColor; 354 | }); 355 | 356 | let allTickets = document.querySelectorAll(".ticket-cont"); 357 | 358 | for (let i = 0; i < allTickets.length; i++) { 359 | allTickets[i].remove(); 360 | } 361 | 362 | filteredTickets.forEach(function (filteredTicket) { 363 | createTicket( 364 | filteredTicket.ticketColor, 365 | filteredTicket.ticketTask, 366 | filteredTicket.ticketId 367 | ); 368 | }); 369 | }); 370 | } 371 | ``` 372 | 373 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/641/original/4.png?1695233480) 374 | 375 | To tackle this issue, we're planning to implement a validation mechanism that utilizes unique identifier to ensure that duplicate tickets aren't generated. This way, the filtered ticket array will only consist of distinct tickets corresponding to the selected color. 376 | 377 | So, using the unique IDs associated with each ticket is a great way to prevent duplicates. This way, we can ensure that the same ticket isn't added to the filtered array more than once. 378 | 379 | ![](https://d2beiqkhq929f0.cloudfront.net/public_assets/assets/000/049/631/original/2.png?1695232789) 380 | 381 | **[Ask the learners]** In which part of the code should you integrate this ID-checking mechanism to effectively prevent duplicate tickets from being included in the filtered array? 382 | 383 | Within the createTicket method, we'll implement the following logic: if a ticket possesses an existing ID, it will be used; otherwise, a new unique ID will be generated during its initial creation. It's essential to note that the ticket will only be pushed to the array if it lacks an ID, ensuring avoidance of duplication. 384 | 385 | #### Pseudocode 386 | 387 | ```javascript 388 | function createTicket(ticketColor, ticketTask, ticketId) { 389 | // Adding an identifier 390 | let id = ticketId || shortid(); 391 | } 392 | ``` 393 | 394 | Prior to adding the ID to the array, we will perform a validation to ascertain its existence, and only if it indeed exists, will it be appended within the createTicket method. 395 | 396 | #### Pseudocode 397 | 398 | ```javascript 399 | function createTicket(ticketColor, ticketTask, ticketId) { 400 | // Adding an identifier 401 | let id = ticketId || shortid(); 402 | 403 | // Other code 404 | 405 | if (!ticketId) { 406 | ticketArr.push({ ticketColor, ticketTask, ticketId: id }); 407 | } 408 | } 409 | ``` 410 | 411 | 412 | 413 | Complete JS code for the class - 414 | 415 | ```js 416 | let addBtn = document.querySelector(".add-btn"); 417 | let removeBtn = document.querySelector(".remove-btn"); 418 | let modalCont = document.querySelector(".modal-cont"); 419 | let mainCont = document.querySelector(".main-cont"); 420 | let textAreaCont = document.querySelector(".textArea-cont"); 421 | let allPriorityColors = document.querySelectorAll(".priority-color"); 422 | 423 | let colors = ["lightpink", "lightgreen", "lightblue", "black"]; 424 | 425 | let toolboxColors = document.querySelectorAll(".color"); 426 | 427 | let lockClass = "fa-lock"; // closed lock 428 | let unlockClass = "fa-lock-open"; // open-lock 429 | 430 | let addTaskFlag = false; 431 | let removeTaskFlag = false; 432 | 433 | let modalPrioritycolor = colors[colors.length - 1]; 434 | 435 | let ticketsArr = []; 436 | 437 | 438 | // Making Tasks visibile according to colors (filtering) 439 | 440 | for (let i = 0; i < toolboxColors.length; i++) { 441 | toolboxColors[i].addEventListener("click", function () { 442 | let selectedToolBoxColor = toolboxColors[i].classList[0]; 443 | 444 | let filterdTickets = ticketsArr.filter(function (ticket) { 445 | return selectedToolBoxColor === ticket.ticketColor; 446 | }); 447 | 448 | let allTickets = document.querySelectorAll(".ticket-cont"); 449 | 450 | for (let i = 0; i < allTickets.length; i++) { 451 | allTickets[i].remove(); 452 | } 453 | 454 | filterdTickets.forEach(function (filterdTicket) { 455 | createTicket( 456 | filterdTicket.ticketColor, 457 | filterdTicket.ticketTask, 458 | filterdTicket.ticketID 459 | ); 460 | }); 461 | }); 462 | } 463 | 464 | // Selecting color for your task 465 | allPriorityColors.forEach(function (colorElem) { 466 | colorElem.addEventListener("click", function () { 467 | allPriorityColors.forEach(function (priorityColorElem) { 468 | priorityColorElem.classList.remove("active"); 469 | }); 470 | colorElem.classList.add("active"); 471 | modalPrioritycolor = colorElem.classList[0]; // lightpink 472 | }); 473 | }); 474 | addBtn.addEventListener("click", function () { 475 | // Display the model 476 | addTaskFlag = !addTaskFlag; 477 | 478 | if (addTaskFlag == true) { 479 | modalCont.style.display = "flex"; 480 | } else { 481 | modalCont.style.display = "none"; 482 | } 483 | }); 484 | removeBtn.addEventListener("click", function () { 485 | removeTaskFlag = !removeTaskFlag; 486 | if (removeTaskFlag == true) { 487 | alert("delete button has been activated"); 488 | removeBtn.style.color = "red"; 489 | } else { 490 | removeBtn.style.color = "white"; 491 | } 492 | }); 493 | modalCont.addEventListener("keydown", function (e) { 494 | let key = e.key; 495 | if (key === "Shift") { 496 | createTicket(modalPrioritycolor, textAreaCont.value, shortid()); // ticket generation 497 | modalCont.style.display = "none"; 498 | console.log(textAreaCont.value); 499 | textAreaCont.value = ""; 500 | } 501 | }); 502 | 503 | 504 | function createTicket(ticketColor, ticketTask, ticketID) { 505 | let ticketCont = document.createElement("div"); 506 | ticketCont.setAttribute("class", "ticket-cont"); 507 | ticketCont.innerHTML = `
      508 |
      ${ticketID}
      509 |
      ${ticketTask}
      510 |
      511 | 512 |
      513 | `; 514 | 515 | mainCont.appendChild(ticketCont); 516 | 517 | ticketsArr.push({ ticketColor, ticketTask, ticketID }); 518 | 519 | console.log(ticketsArr); 520 | 521 | handleRemoval(ticketCont); 522 | 523 | handleLock(ticketCont); 524 | handleColor(ticketCont); 525 | } 526 | 527 | function handleRemoval(ticket) { 528 | ticket.addEventListener("click", function () { 529 | if (!removeTaskFlag) return; 530 | else { 531 | ticket.remove(); 532 | } 533 | }); 534 | } 535 | 536 | function handleLock(ticket) { 537 | let ticketLockElem = ticket.querySelector(".ticket-lock"); 538 | let ticketLockIcon = ticketLockElem.children[0]; 539 | let ticketTaskArea = ticket.querySelector(".task-area"); 540 | ticketLockIcon.addEventListener("click", function () { 541 | if (ticketLockIcon.classList.contains(lockClass)) { 542 | ticketLockIcon.classList.remove(lockClass); 543 | ticketLockIcon.classList.add(unlockClass); 544 | ticketTaskArea.setAttribute("contenteditable", "true"); 545 | } else { 546 | ticketLockIcon.classList.remove(unlockClass); 547 | ticketLockIcon.classList.add(lockClass); 548 | ticketTaskArea.setAttribute("contenteditable", "false"); 549 | } 550 | }); 551 | } 552 | 553 | 554 | // Handle color function 555 | function handleColor(ticket) { 556 | let ticketColorBand = ticket.querySelector(".ticket-color"); 557 | ticketColorBand.addEventListener("click", function () { 558 | let currentColor = ticketColorBand.classList[1]; 559 | let currentColorIdx = colors.findIndex(function (color) { 560 | return currentColor === color; 561 | }); 562 | currentColorIdx++; 563 | let newTicketColorIdx = currentColorIdx % colors.length; 564 | let newTicketColor = colors[newTicketColorIdx]; 565 | ticketColorBand.classList.remove(currentColor); 566 | ticketColorBand.classList.add(newTicketColor); 567 | }); 568 | } 569 | ``` -------------------------------------------------------------------------------- /Class-7 (Kanban Board)/script.js: -------------------------------------------------------------------------------- 1 | const addBtn = document.querySelector(".add-btn"); 2 | const removeBtn = document.querySelector(".remove-btn"); 3 | const modalCont = document.querySelector(".modal-cont"); 4 | const taskArea = document.querySelector(".textArea-cont"); 5 | const mainCont = document.querySelector(".main-cont"); 6 | const allpriorityColors = document.querySelectorAll(".priority-color"); 7 | 8 | let ticketsArr = JSON.parse(localStorage.getItem("apptickets")) || []; 9 | 10 | function init() { 11 | if (localStorage.getItem("apptickets")) { 12 | ticketsArr.forEach(function (ticket) { 13 | createTicket(ticket.color, ticket.task, ticket.id); 14 | }); 15 | } 16 | } 17 | 18 | init(); 19 | 20 | // if the ticketArr is Empty , if the ticketsArr is not Empty 21 | 22 | console.log(ticketsArr); 23 | 24 | let toolBoxColors = document.querySelectorAll(".color"); 25 | 26 | // priority colors array 27 | let colors = ["lightpink", "lightgreen", "lightblue", "black"]; 28 | 29 | // console.log(allpriorityColors) 30 | 31 | let addBtnFlag = false; 32 | let removeBtnFlag = false; 33 | let modalColorForTicket = "lightpink"; 34 | 35 | // Lock Classes 36 | 37 | let lockClose = "fa-lock"; 38 | let lockOpen = "fa-lock-open"; 39 | 40 | // Modal pop up Event 41 | 42 | addBtn.addEventListener("click", function () { 43 | addBtnFlag = !addBtnFlag; 44 | if (addBtnFlag === true) { 45 | modalCont.style.display = "flex"; 46 | } else { 47 | modalCont.style.display = "none"; 48 | } 49 | }); 50 | 51 | // Delete button activation and deactivation 52 | removeBtn.addEventListener("click", function () { 53 | removeBtnFlag = !removeBtnFlag; 54 | 55 | if (removeBtnFlag) { 56 | alert("Delete button Activated"); 57 | removeBtn.style.color = "red"; 58 | } else { 59 | removeBtn.style.color = "white"; 60 | } 61 | }); 62 | 63 | function handleRemoval(ticket) { 64 | ticket.addEventListener("click", function () { 65 | if (removeBtnFlag == true) { 66 | ticket.remove(); 67 | } 68 | }); 69 | } 70 | 71 | // change priority color of tickets 72 | function handleColor(ticket) { 73 | let ticketColorBand = ticket.querySelector(".ticket-color"); 74 | 75 | const id = ticket.querySelector('.ticket-id').innerText 76 | 77 | 78 | ticketColorBand.addEventListener("click", function () { 79 | let ticketIdx = getIdx(id) 80 | console.log(ticketIdx) 81 | 82 | let currentColor = ticketColorBand.style.backgroundColor; 83 | 84 | let currentColorIdx = colors.findIndex(function (color) { 85 | return color === currentColor; 86 | }); 87 | 88 | currentColorIdx++; 89 | 90 | let newColorIdx = currentColorIdx % colors.length; 91 | // 1 // 2 // 3 // 4->0 92 | let newColor = colors[newColorIdx]; 93 | 94 | ticketColorBand.style.backgroundColor = newColor; 95 | ticketsArr[ticketIdx].color = newColor 96 | updateLocalStorage() 97 | }); 98 | } 99 | 100 | // handle Lock for content edit 101 | 102 | function handleLock(ticket) { 103 | let ticketLockCont = ticket.querySelector(".ticket-lock"); 104 | let ticketLockIcon = ticketLockCont.children[0]; 105 | let ticketTaskArea = ticket.querySelector(".task-area"); 106 | 107 | ticketLockIcon.addEventListener("click", function () { 108 | // get the idx with the help of id 109 | if (ticketLockIcon.classList.contains(lockClose)) { 110 | ticketLockIcon.classList.remove(lockClose); 111 | ticketLockIcon.classList.add(lockOpen); 112 | 113 | ticketTaskArea.setAttribute("contenteditable", "true"); 114 | 115 | } else { 116 | ticketLockIcon.classList.remove(lockOpen); 117 | ticketLockIcon.classList.add(lockClose); 118 | // should not be editing the task 119 | ticketTaskArea.setAttribute("contenteditable", "false"); 120 | } 121 | }); 122 | } 123 | 124 | // Filter out task according to selected Color 125 | 126 | // Create a ticket 127 | 128 | function createTicket(ticketColor, ticketTask, ticketId) { 129 | let ticketCont = document.createElement("div"); 130 | ticketCont.setAttribute("class", "ticket-cont"); 131 | ticketCont.innerHTML = ` 132 |
      133 |
      ${ticketId}
      134 |
      ${ticketTask}
      135 |
      136 | 137 |
      `; 138 | 139 | mainCont.appendChild(ticketCont); 140 | 141 | handleRemoval(ticketCont); 142 | handleColor(ticketCont); 143 | handleLock(ticketCont); 144 | } 145 | 146 | // add a task 147 | 148 | modalCont.addEventListener("keydown", function (e) { 149 | if (e.key === "Shift") { 150 | const task = taskArea.value; 151 | const id = shortid(); 152 | console.log(task + " -> " + id); 153 | createTicket(modalColorForTicket, task, id); 154 | modalCont.style.display = "none"; 155 | taskArea.value = ""; 156 | addBtnFlag = false; 157 | ticketsArr.push({ color: modalColorForTicket, task: task, id: id }); 158 | updateLocalStorage(); 159 | } 160 | }); 161 | 162 | // moving the active class on priority color boxes 163 | 164 | allpriorityColors.forEach(function (colorElem) { 165 | colorElem.addEventListener("click", function () { 166 | allpriorityColors.forEach(function (priorityColor) { 167 | priorityColor.classList.remove("active"); 168 | }); 169 | 170 | colorElem.classList.add("active"); 171 | modalColorForTicket = colorElem.classList[0]; 172 | }); 173 | }); 174 | 175 | toolBoxColors.forEach(function (color) { 176 | color.addEventListener("click", function () { 177 | const allTickets = document.querySelectorAll(".ticket-cont"); 178 | 179 | let selectedColor = color.classList[0]; 180 | 181 | allTickets.forEach(function (ticket) { 182 | let ticketColorBand = ticket.querySelector(".ticket-color"); 183 | if (ticketColorBand.style.backgroundColor === selectedColor) { 184 | ticket.style.display = "block"; 185 | } else { 186 | ticket.style.display = "none"; 187 | } 188 | }); 189 | }); 190 | }); 191 | 192 | function updateLocalStorage() { 193 | localStorage.setItem("apptickets", JSON.stringify(ticketsArr)); 194 | } 195 | // Lolv-jd2dy 196 | function getIdx(id) 197 | { 198 | let ticketIdx = ticketsArr.findIndex(function (ticketContaiers) { 199 | return ticketContaiers.id ==id 200 | }); 201 | 202 | return ticketIdx 203 | } 204 | -------------------------------------------------------------------------------- /Class-7 (Kanban Board)/style.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | .toolbox-cont{ 8 | display: flex; 9 | height:5rem ; 10 | background-color: #4b4b4b; 11 | align-items: center; 12 | 13 | 14 | } 15 | 16 | .toolbox-priority-cont{ 17 | display: flex; 18 | height:3.5rem ; 19 | width: 18rem; 20 | background-color: #3b3b3b; 21 | margin-left: 4rem; 22 | justify-content: space-evenly; 23 | align-items: center; 24 | 25 | 26 | } 27 | 28 | .color{ 29 | height: 1.5rem; 30 | width: 3rem; 31 | 32 | } 33 | 34 | .lightpink{ 35 | background-color: lightpink; 36 | } 37 | 38 | 39 | .lightgreen{ 40 | background-color: lightgreen; 41 | } 42 | 43 | .lightblue{ 44 | background-color: lightblue; 45 | } 46 | 47 | .black{ 48 | background-color: black; 49 | } 50 | 51 | /* Action buttons */ 52 | 53 | 54 | .action-btn-cont{ 55 | display: flex; 56 | height:3.5rem ; 57 | width: 8rem; 58 | background-color:#3b3b3b ; 59 | margin-left: 3rem; 60 | justify-content: space-around; 61 | align-items: center; 62 | 63 | } 64 | 65 | .action-btn-cont>*{ 66 | width: 50%; 67 | font-size: 2rem; 68 | color: white; 69 | text-align: center; 70 | } 71 | 72 | /* Ticket Design */ 73 | 74 | .main-cont{ 75 | display: flex; 76 | justify-content: center; 77 | margin-top: 2rem; 78 | gap : 2rem; 79 | flex-wrap: wrap; 80 | 81 | } 82 | 83 | .ticket-cont{ 84 | height: 12rem; 85 | width: 15rem; 86 | background-color: coral; 87 | } 88 | 89 | .ticket-color{ 90 | background-color: lightpink; 91 | height: 1.5rem; 92 | } 93 | 94 | .ticket-id{ 95 | background-color: yellow; 96 | height:1.8rem ; 97 | } 98 | 99 | .ticket-lock{ 100 | display: flex; 101 | justify-content: end; 102 | margin-top: 6rem; 103 | font-size: 1.4rem; 104 | } 105 | 106 | 107 | /* modal pop up design */ 108 | 109 | 110 | .modal-cont{ 111 | display: none; 112 | height: 50vh; 113 | width: 45vw; 114 | background-color: gray; 115 | position: absolute; 116 | top : 30%; 117 | left : 27% 118 | } 119 | 120 | 121 | .textArea-cont{ 122 | width: 70%; 123 | height: 100%; 124 | resize: none; 125 | background-color: lightgray; 126 | font-size: 2rem; 127 | border: none; 128 | outline: none; 129 | } 130 | 131 | .priority-color{ 132 | height: 3rem; 133 | width: 5rem; 134 | 135 | } 136 | 137 | 138 | .priority-colors-container{ 139 | width: 30%; 140 | display: flex; 141 | flex-direction: column; 142 | align-items: center; 143 | justify-content: space-evenly; 144 | 145 | } 146 | 147 | 148 | .active{ 149 | border: 3px solid red; 150 | } 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /Class-7 (Kanban Board)/test.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "color": "lightpink", "task": "task 1", "id": "-bbzZh9WtK" }, 3 | { "color": "lightgreen", "task": "task 2", "id": "N3pUqpLY7t" }, 4 | { "color": "lightblue", "task": "task 3", "id": "AognSFvAlY" } 5 | ] 6 | -------------------------------------------------------------------------------- /Class-8 (async Programming-1)/async1.js: -------------------------------------------------------------------------------- 1 | console.log("Start"); 2 | 3 | function test1() { 4 | console.log("I am test 1"); 5 | } 6 | 7 | function test3() { 8 | console.log("I am test 3"); 9 | } 10 | 11 | // test1() 12 | 13 | setTimeout(test1, 2000); 14 | setTimeout(test3, 2000); 15 | 16 | function test2() { 17 | console.log("I am test 2"); 18 | } 19 | 20 | console.log("End"); 21 | 22 | test2(); 23 | -------------------------------------------------------------------------------- /Class-8 (async Programming-1)/f1.txt: -------------------------------------------------------------------------------- 1 | I am f1 data -------------------------------------------------------------------------------- /Class-8 (async Programming-1)/f2.txt: -------------------------------------------------------------------------------- 1 | I am f2 data -------------------------------------------------------------------------------- /Class-8 (async Programming-1)/f3.txt: -------------------------------------------------------------------------------- 1 | I am f3 data -------------------------------------------------------------------------------- /Class-8 (async Programming-1)/fileHandling.js: -------------------------------------------------------------------------------- 1 | const fileSystem = require('fs') 2 | 3 | // read a file 4 | 5 | console.log('start') 6 | 7 | // This is synchronous 8 | 9 | // const data= fileSystem.readFileSync('f1.txt') 10 | 11 | // console.log("This is file Data -> " + data) 12 | 13 | // Asynchronously 14 | 15 | fileSystem.readFile('f1.txt' , function(err , data){ 16 | if(err){ 17 | console.log(err) 18 | } 19 | else{ 20 | console.log("This is file1 -> "+ data) 21 | } 22 | }) 23 | 24 | fileSystem.readFile('f2.txt' , function(err , data){ 25 | if(err){ 26 | console.log(err) 27 | } 28 | else{ 29 | console.log("This is file2 -> "+ data) 30 | } 31 | }) 32 | 33 | 34 | fileSystem.readFile('f3.txt' , function(err , data){ 35 | if(err){ 36 | console.log(err) 37 | } 38 | else{ 39 | console.log("This is file3 -> "+ data) 40 | } 41 | }) 42 | 43 | 44 | 45 | 46 | console.log("end") 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Class-8 (async Programming-1)/fileReadSerial.js: -------------------------------------------------------------------------------- 1 | const fileSystem = require("fs"); 2 | 3 | // read a file 4 | 5 | console.log("start"); 6 | 7 | // Asynchronously but serial 8 | 9 | fileSystem.readFile("f1.txt", cb1); 10 | 11 | 12 | 13 | function cb1(err, data) { 14 | if (err) { 15 | console.log(err); 16 | } else { 17 | console.log("This is file1 -> " + data); 18 | 19 | fileSystem.readFile("f2.txt", cb2); 20 | } 21 | } 22 | function cb2(err, data) { 23 | if (err) { 24 | console.log(err); 25 | } else { 26 | console.log("This is file2 -> " + data); 27 | fileSystem.readFile("f3.txt", cb3); 28 | } 29 | } 30 | 31 | function cb3(err, data) { 32 | if (err) { 33 | console.log(err); 34 | } else { 35 | console.log("This is file3 -> " + data); 36 | 37 | } 38 | } 39 | 40 | console.log("end"); 41 | -------------------------------------------------------------------------------- /Class-9 (Async-2)/index.js: -------------------------------------------------------------------------------- 1 | // function prepareIngredients(callback) { 2 | // setTimeout(function () { 3 | // console.log("Ingredients Prepared"); 4 | // callback(); 5 | // }, 2000); 6 | // } 7 | 8 | // function cookDish(callback) { 9 | // setTimeout(function () { 10 | // console.log("Dish cooked"); 11 | // callback(); 12 | // }, 1000); 13 | // } 14 | 15 | // function serveDish(callback) { 16 | // setTimeout(function () { 17 | // console.log("Dish Served"); 18 | // callback(); 19 | // }, 500); 20 | // } 21 | 22 | // function cleanUp(callback) { 23 | // setTimeout(function () { 24 | // console.log("Table cleaned"); 25 | // callback() 26 | // }, 200); 27 | // } 28 | 29 | function prepareIngredients() { 30 | return new Promise(function (resolve) { 31 | setTimeout(function () { 32 | resolve("Ingredients Prepared"); 33 | }, 2000); 34 | 35 | }); 36 | } 37 | 38 | function cookdish() { 39 | return new Promise(function (resolve, reject) { 40 | setTimeout(function () { 41 | resolve("Dish Prepared"); 42 | }, 2000); 43 | 44 | 45 | }); 46 | } 47 | 48 | function serveDish() { 49 | return new Promise(function (resolve, reject) { 50 | setTimeout(function () { 51 | resolve("Dish Served"); 52 | }, 2000); 53 | 54 | 55 | }); 56 | } 57 | 58 | function cleanUp() { 59 | return new Promise(function (resolve, reject) { 60 | setTimeout(function () { 61 | resolve("Table Cleaned"); 62 | }, 2000); 63 | 64 | 65 | }); 66 | } 67 | 68 | function provideFeedback(callback) { 69 | setTimeout(function () { 70 | console.log("Table cleaned"); 71 | callback(); 72 | }, 1500); 73 | } 74 | 75 | function leaveTable() { 76 | setTimeout(function () { 77 | console.log("Table cleaned"); 78 | }, 1000); 79 | } 80 | 81 | // prepareIngredients(function () { 82 | // cookDish(function () { 83 | // serveDish(function () { 84 | // cleanUp(function () { 85 | // provideFeedback(function () { 86 | // leaveTable(); 87 | // }); 88 | // }); 89 | // }); 90 | // }); 91 | // }); 92 | 93 | // Promise Chaining 94 | 95 | prepareIngredients().then(function(ingredients){ 96 | console.log(ingredients) 97 | return cookdish() 98 | }).then(function(cooked){ 99 | console.log(cooked) 100 | return serveDish() 101 | }).then(function(dishServed){ 102 | console.log(dishServed) 103 | return cleanUp() 104 | }).then(function(cleaned){ 105 | console.log(cleaned) 106 | }).catch(function(err){ 107 | console.log(err) 108 | }).finally(function(){ 109 | console.log('process done') 110 | }) 111 | -------------------------------------------------------------------------------- /Class-9 (Async-2)/promise.js: -------------------------------------------------------------------------------- 1 | const p1 = function () { 2 | return new Promise(function (resolve, reject) { 3 | setTimeout(function () { 4 | let isHeads = Math.random() >0; 5 | if (isHeads) { 6 | resolve("Heads , Won the Toss 1"); 7 | } else { 8 | reject("Tails , Lost the Toss 1"); 9 | } 10 | }, 2000); 11 | }); 12 | }; 13 | 14 | const p2 = function () { 15 | return new Promise(function (resolve, reject) { 16 | setTimeout(function () { 17 | let isHeads = Math.random() > 0; 18 | if (isHeads) { 19 | resolve("Heads , Won the Toss 2"); 20 | } else { 21 | reject("Tails , Lost the Toss 2"); 22 | } 23 | }, 2000); 24 | }); 25 | }; 26 | const p3 = function () { 27 | return new Promise(function (resolve, reject) { 28 | setTimeout(function () { 29 | let isHeads = Math.random() > 0; 30 | if (isHeads) { 31 | resolve("Heads , Won the Toss 3"); 32 | } else { 33 | reject("Tails , Lost the Toss 3"); 34 | } 35 | }, 2000); 36 | }); 37 | }; 38 | 39 | p1().then(function (resolveData) { 40 | console.log(resolveData); 41 | return p2() 42 | }).then(function(resolveDataP2){ 43 | console.log(resolveDataP2) 44 | return p3() 45 | }).then(function(resolveDataP3){ 46 | console.log(resolveDataP3) 47 | }).catch(function (rejectData) { 48 | console.log("Catch-> " + rejectData); 49 | }) 50 | .finally(function () { 51 | console.log("promise settled"); 52 | }); 53 | -------------------------------------------------------------------------------- /PracticeSheet/sheet1.md: -------------------------------------------------------------------------------- 1 | **DOM Manipulation Practice Sheet** 2 | 3 | --- 4 | 5 | ### **Section 1: Easy (10 Questions)** 6 | These questions are designed to build a strong foundation in DOM manipulation. 7 | 8 | 1. **Selecting Elements** 9 | - Write a function to select an element with the ID `header-title` and change its text content to "Welcome to the DOM Practice!" 10 | 11 | 2. **Change Background Color** 12 | - Select all `
    • ` elements on the page and change their background color to light blue. 13 | 14 | 3. **Add New Element** 15 | - Write a function that creates a new `

      ` element with the text "This is a new paragraph" and appends it to the ``. 16 | 17 | 4. **Modify Styles** 18 | - Select the first `

      ` tag on the page and set its font size to `36px`. 19 | 20 | 5. **Change Image Source** 21 | - Change the `src` of an image with the ID `profile-pic` to a new URL: `https://via.placeholder.com/150`. 22 | 23 | 6. **Change Text Color** 24 | - Write a function to change the text color of all `

      ` elements on the page to `#FF5733` (orange). 25 | 26 | 7. **Event Listener** 27 | - Write an event listener for a button with the ID `click-me`, so that when it is clicked, it logs "Button Clicked!" to the console. 28 | 29 | 8. **Form Input Value** 30 | - Write a function that logs the current value of an input field with the ID `user-name` whenever the input is changed. 31 | 32 | 9. **Toggle Class** 33 | - Write a function that toggles the class `highlight` on an element with the class `box` when a button with the ID `toggle-btn` is clicked. 34 | 35 | 10. **Remove Element** 36 | - Write a function to remove an element with the ID `delete-me` from the DOM. 37 | 38 | --- 39 | 40 | ### **Section 2: Medium (10 Questions)** 41 | These questions are designed to deepen your understanding of manipulating the DOM dynamically. 42 | 43 | 1. **Create a List** 44 | - Write a function that dynamically creates an unordered list (`

        `) with 5 items (`
      • `) labeled "Item 1", "Item 2", ..., "Item 5" and appends it to a container with the ID `list-container`. 45 | 46 | 2. **Update Multiple Elements** 47 | - Write a function to change the text of all elements with the class `update-text` to "Updated Successfully!". 48 | 49 | 3. **Event Delegation** 50 | - Add an event listener to a parent `
          ` with the ID `parent-list` so that any time a child `
        • ` is clicked, it logs "List item clicked!" to the console. 51 | 52 | 4. **Show/Hide Element** 53 | - Write a function that hides an element with the ID `popup-box` when a button with the ID `close-popup` is clicked. 54 | 55 | 5. **Dynamic Table Creation** 56 | - Write a function that creates a 3x3 table and appends it to an element with the ID `table-container`. 57 | 58 | 6. **Disable Button** 59 | - Write a function that disables a button with the ID `submit-btn` after it is clicked once. 60 | 61 | 7. **Text Input Event** 62 | - Write a function that updates the text of an `

          ` with the ID `dynamic-title` as the user types into an input with the ID `title-input`. 63 | 64 | 8. **Remove All Children** 65 | - Write a function to remove all child elements from an element with the ID `content-area`. 66 | 67 | 9. **Dynamic Countdown** 68 | - Create a countdown timer that displays the time left (in seconds) inside an element with the ID `countdown` and counts down from 10 to 0, updating every second. 69 | 70 | 10. **Add Class to Multiple Elements** 71 | - Write a function that adds the class `error-message` to all `

          ` tags inside a div with the class `error-container`. 72 | 73 | --- 74 | 75 | ### **Section 3: Hard (10 Questions)** 76 | These questions challenge you to combine multiple DOM techniques in creative ways. 77 | 78 | 1. **Dynamic To-Do List** 79 | - Create a simple to-do list. It should have an input field where users can type new tasks, a button to add the task, and each task should have a "Delete" button to remove the task from the list. 80 | 81 | 2. **Modal Window** 82 | - Write a function to create a simple modal pop-up. When a button with the ID `open-modal` is clicked, the modal should appear with a close button to dismiss it. 83 | 84 | 3. **Drag and Drop** 85 | - Implement a simple drag-and-drop feature where users can drag items from one list with the ID `list-1` and drop them into another list with the ID `list-2`. 86 | 87 | 4. **Image Gallery** 88 | - Create an image gallery with thumbnails. When a thumbnail is clicked, it should display a larger version of the image in a "main" image container. 89 | 90 | 5. **Typing Game** 91 | - Create a typing speed game. Display a random word on the screen, and as the user types into an input field, show if the typed word matches the displayed word in real time. 92 | 93 | 6. **Form Validation** 94 | - Create a registration form with fields for "Username", "Email", and "Password". Validate that none of the fields are empty before submission, and show error messages if any are empty. 95 | 96 | 7. **Real-time Character Counter** 97 | - Write a function to count the characters in a text area with the ID `message-box` and display the count in an element with the ID `char-count`. Update it as the user types. 98 | 99 | 8. **Random Background Color** 100 | - Write a function that changes the background color of an element with the ID `color-box` to a random color every 2 seconds. 101 | 102 | 9. **Multi-step Form** 103 | - Create a multi-step form with 3 steps. When the user clicks "Next", the next form section is displayed, and the previous section is hidden. 104 | 105 | 10. **Dynamic Quiz App** 106 | - Create a quiz app that shows one question at a time, with multiple-choice answers. When the user selects an answer and clicks "Next", it shows the next question. Display the final score at the end. 107 | 108 | --- -------------------------------------------------------------------------------- /Small Projects/characterCount.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Character Counter 7 | 71 | 72 | 73 | 74 |

          75 |

          Character Counter

          76 | 77 |
          78 | 0 / 100 characters 79 |
          80 |
          81 | 82 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /Small Projects/drumkit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Simple Drum Kit 7 | 76 | 77 | 78 | 79 |
          80 |

          Simple Drum Kit

          81 |
          82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
          92 | 93 |
          94 | 95 | 96 |
          97 |
          98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /Small Projects/expense.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Simple Expense Tracker 7 | 104 | 105 | 106 | 107 |
          108 |

          Expense Tracker

          109 |
          110 | 111 | 112 |
          113 |
          114 | 115 | 116 |
          117 | 118 | 119 |
            120 | 121 |
            Total: RS.0
            122 |
            123 | 124 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /Small Projects/starRating.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Star Rating Component 8 | 32 | 33 | 34 |
            35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |

            Rating: 0/5

            45 |
            46 | 76 | 77 | -------------------------------------------------------------------------------- /Small Projects/votingapp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Live Poll Voting App 7 | 93 | 94 | 95 | 96 |
            97 |

            What is your favorite programming language?

            98 | 99 | 100 | 101 | 102 | 103 | 104 |
            105 |

            Live Results

            106 |
            107 |
            0%
            108 |
            109 |
            110 |
            0%
            111 |
            112 |
            113 |
            0%
            114 |
            115 |
            116 |
            0%
            117 |
            118 |
            119 |
            120 | 121 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /practiceSheetEndTerm.md: -------------------------------------------------------------------------------- 1 | ### **Practice Sheet: Asynchronous Programming in JavaScript** 2 | 3 | #### **Part 1: Conceptual Questions** 4 | 1. What is asynchronous programming, and why is it important in JavaScript? 5 | 2. Explain the difference between synchronous and asynchronous code execution. 6 | 3. What is a callback function? Provide an example. 7 | 4. What are some of the common problems associated with using callbacks extensively? 8 | 5. What is a Promise in JavaScript? How does it improve code readability over callbacks? 9 | 6. Explain the different states of a Promise and what they represent. 10 | 7. How does the `.then()` method work with Promises? 11 | 8. What is the purpose of the `.catch()` method in Promises? 12 | 9. How does `async/await` simplify working with Promises? 13 | 10. Can `async/await` be used without Promises? Why or why not? 14 | 15 | --- 16 | 17 | #### **Part 2: Coding Exercises** 18 | 19 | 1. Write a function `fetchData(callback)` that simulates fetching data from an API. Use `setTimeout` to delay the execution for 2 seconds. The function should return either data or an error message via the callback. 20 | 21 | 2. Convert the following callback-based function into one that uses Promises: 22 | ```javascript 23 | function getUserData(callback) { 24 | setTimeout(() => { 25 | callback(null, { name: "John", age: 25 }); 26 | }, 1000); 27 | } 28 | ``` 29 | 30 | 3. Write a Promise-based function `getTemperature(city)` that resolves with a simulated temperature for the given city after 2 seconds. 31 | 32 | 4. Given the following code snippet, fix it using `.catch()` to handle the error: 33 | ```javascript 34 | fetchWeatherData() 35 | .then(data => console.log(data)) 36 | .then(() => console.log("Done")); 37 | ``` 38 | 39 | 5. Use `async/await` to refactor the following code: 40 | ```javascript 41 | function fetchUser() { 42 | return new Promise(resolve => { 43 | setTimeout(() => resolve({ name: "Alice" }), 1000); 44 | }); 45 | } 46 | fetchUser().then(user => console.log(user)); 47 | ``` 48 | 49 | 6. Create an `async` function that fetches user data and weather data sequentially using the following mock functions: 50 | ```javascript 51 | function getUser() { 52 | return new Promise(resolve => setTimeout(() => resolve("User data"), 1000)); 53 | } 54 | function getWeather() { 55 | return new Promise(resolve => setTimeout(() => resolve("Weather data"), 1000)); 56 | } 57 | ``` 58 | 59 | 7. Handle multiple Promises using `Promise.all` to fetch details of three users simultaneously. 60 | 61 | 8. Rewrite the following code to handle errors gracefully using `try...catch`: 62 | ```javascript 63 | async function fetchUserData() { 64 | let response = await fetch("/user"); 65 | let data = await response.json(); 66 | console.log(data); 67 | } 68 | ``` 69 | 70 | 9. Write an `async` function that throws an error intentionally and handles it using `try...catch`. 71 | 72 | 10. Create a chain of Promises that simulates a series of dependent asynchronous operations: 73 | - Fetch user profile 74 | - Fetch user settings based on profile 75 | - Fetch recommendations based on settings 76 | 77 | --- 78 | 79 | #### **Part 3: Debugging and Logical Thinking** 80 | 81 | 1. What happens if you forget to use `await` inside an `async` function? Provide an example. 82 | 2. Identify the issue with the following code and correct it: 83 | ```javascript 84 | async function fetchData() { 85 | setTimeout(() => { 86 | return "Data"; 87 | }, 1000); 88 | } 89 | let data = fetchData(); 90 | console.log(data); 91 | ``` 92 | 93 | 3. Why does the following code result in a rejected Promise, and how can you fix it? 94 | ```javascript 95 | function fetchItems() { 96 | return new Promise((resolve, reject) => { 97 | setTimeout(() => reject("Error fetching items"), 2000); 98 | }); 99 | } 100 | fetchItems().then(items => console.log(items)); 101 | ``` 102 | 103 | 4. Rewrite the following function to use `Promise.allSettled`: 104 | ```javascript 105 | const promise1 = Promise.resolve("Data 1"); 106 | const promise2 = Promise.reject("Error in Data 2"); 107 | const promise3 = Promise.resolve("Data 3"); 108 | Promise.all([promise1, promise2, promise3]).then(results => console.log(results)); 109 | ``` 110 | 111 | 5. Consider the following code. Will it work as intended? Explain why or why not: 112 | ```javascript 113 | async function processData() { 114 | const data = fetch("/data"); 115 | console.log(await data.json()); 116 | } 117 | processData(); 118 | ``` 119 | 120 | 6. Write an `async` function that demonstrates the usage of `Promise.race` with two Promises: one that resolves quickly and another that takes longer. 121 | 122 | 7. What is the difference between `Promise.all` and `Promise.race`? Provide an example for each. 123 | 124 | --- 125 | 126 | #### **Challenge Question** 127 | 1. Create a small program that simulates a "Retry Mechanism" using Promises. The function should attempt to fetch data from a mocked API up to 3 times if it encounters an error. 128 | 129 | --- 130 | 131 | --------------------------------------------------------------------------------