` 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 | 
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 `
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | A
83 | S
84 | D
85 | F
86 | G
87 | H
88 | J
89 | K
90 | L
91 |
92 |
93 |
94 | Start Recording
95 | Replay
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 | Expense Name
111 |
112 |
113 |
114 | Amount
115 |
116 |
117 |
Add Expense
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 |
JavaScript
100 |
Python
101 |
Java
102 |
C#
103 |
104 |
105 |
Live Results
106 |
109 |
112 |
115 |
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 |
--------------------------------------------------------------------------------