Skip to content

Commit a791601

Browse files
Merge pull request #519 from aadibhoyar/main
Adding a new project "Trello Board Clone"
2 parents f11bc46 + dcd0d92 commit a791601

File tree

7 files changed

+492
-0
lines changed

7 files changed

+492
-0
lines changed

Trello Board Clone/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Trello Board Clone
2+
3+
Trello is a user-friendly project management tool that uses boards and lists to help individuals and teams organize tasks and workflows.
4+
5+
6+
## Used Technologies
7+
8+
- HTML5
9+
- CSS3
10+
- JavaScript
11+
12+
13+
## Steps to Use:
14+
15+
1. Download or clone the repository:
16+
```
17+
git clone https://github.com/Ayushparikh-code/Web-dev-mini-projects.git
18+
```
19+
2. Go to the directory
20+
21+
3. Run the `index.html` file
22+
23+
## Screenshots:
24+
<img src="https://github.com/aadityabhoyar/Web-dev-mini-projects/blob/main/Trello%20Board%20Clone/ScreenShots/Screenshot%20(81).png">
25+
<img src="https://github.com/aadityabhoyar/Web-dev-mini-projects/blob/main/Trello%20Board%20Clone/ScreenShots/Screenshot%20(82).png">
26+
<img src="https://github.com/aadityabhoyar/Web-dev-mini-projects/blob/main/Trello%20Board%20Clone/ScreenShots/Screenshot%20(83).png">
22.8 KB
Loading
26.2 KB
Loading
33.8 KB
Loading

Trello Board Clone/index.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<html>
2+
3+
<head>
4+
<link rel="stylesheet" href="style.css">
5+
</link>
6+
</head>
7+
8+
9+
<body>
10+
11+
<div id="addTodoListDiv">
12+
<input id="addTodoListInput" class="comment">
13+
<button id="addTodoListButton" class="btn-save">Add new list</button>
14+
</div>
15+
16+
<div id="root"></div>
17+
18+
</body>
19+
20+
<script src="script.js"></script>
21+
22+
</html>

Trello Board Clone/script.js

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
let root = document.getElementById("root");
2+
3+
4+
class List {
5+
constructor(place, title = "To-Do") {
6+
this.place = place;
7+
this.title = title;
8+
this.cardArray = [];
9+
this.render();
10+
}
11+
12+
addToDo() {
13+
let text = this.input.value;
14+
if (text.trim() !== "") {
15+
this.cardArray.push(new Card(text, this.div, this));
16+
this.input.value = "";
17+
}
18+
}
19+
20+
render() {
21+
this.createListElement();
22+
this.place.append(this.listElement);
23+
}
24+
25+
createListElement() {
26+
this.listElement = document.createElement('div');
27+
this.listElement.classList.add("todoList");
28+
29+
this.h2 = document.createElement('h2');
30+
this.h2.innerText = this.title;
31+
32+
this.input = document.createElement('input');
33+
this.input.classList.add("comment");
34+
35+
this.button = document.createElement('button');
36+
this.button.innerText = 'Add';
37+
this.button.classList.add("btn-save");
38+
this.button.addEventListener('click', this.addToDo.bind(this));
39+
40+
this.div = document.createElement('div');
41+
42+
this.listElement.append(this.h2, this.input, this.button, this.div);
43+
}
44+
}
45+
46+
class ToDo extends List {
47+
constructor(place, title) {
48+
super(place, title);
49+
}
50+
}
51+
52+
class Doing extends List {
53+
constructor(place, title) {
54+
super(place, title);
55+
}
56+
}
57+
58+
class Done extends List {
59+
constructor(place, title) {
60+
super(place, title);
61+
}
62+
}
63+
64+
65+
class Card {
66+
constructor(text, place, list) {
67+
this.text = text;
68+
this.place = place;
69+
this.list = list;
70+
this.state = {
71+
description: "Click to write a description...",
72+
comments: []
73+
};
74+
this.render();
75+
}
76+
77+
render() {
78+
this.card = document.createElement('div');
79+
this.card.classList.add("card");
80+
81+
this.p = document.createElement('p');
82+
this.p.innerText = this.text;
83+
84+
this.deleteButton = document.createElement('button');
85+
this.deleteButton.innerText = "X";
86+
this.deleteButton.addEventListener('click', () => {
87+
this.deleteCard();
88+
});
89+
90+
this.card.append(this.p, this.deleteButton);
91+
this.place.append(this.card);
92+
this.card.addEventListener('click', this.showMenu.bind(this));
93+
}
94+
95+
deleteCard() {
96+
this.card.remove();
97+
let index = this.list.cardArray.indexOf(this);
98+
if (index !== -1) {
99+
this.list.cardArray.splice(index, 1);
100+
}
101+
}
102+
103+
showMenu() {
104+
105+
//Create elements
106+
this.menu = document.createElement("div");
107+
this.menuContainer = document.createElement("div");
108+
this.menuTitle = document.createElement("div");
109+
this.menuDescription = document.createElement("div");
110+
this.commentsInput = document.createElement("input");
111+
this.commentsButton = document.createElement('button');
112+
this.menuComments = document.createElement("div");
113+
114+
115+
//Add class names
116+
this.menu.className = "menu";
117+
this.menuContainer.className = "menuContainer";
118+
this.menuTitle.className = "menuTitle";
119+
this.menuDescription.className = "menuDescription";
120+
this.menuComments.className = "menuComments";
121+
this.commentsInput.className = "commentsInput comment";
122+
this.commentsButton.className = "commentsButton btn-save";
123+
124+
//Add inner Text
125+
this.commentsButton.innerText = "Add";
126+
this.commentsInput.placeholder = "Write a comment...";
127+
128+
//Event listeners
129+
this.menuContainer.addEventListener('click', (e) => {
130+
console.log(e.target);
131+
if (e.target.classList.contains("menuContainer")) {
132+
this.menuContainer.remove();
133+
}
134+
});
135+
136+
this.commentsButton.addEventListener('click', () => {
137+
if (this.commentsInput.value != "") {
138+
this.state.comments.push(this.commentsInput.value);
139+
this.renderComments();
140+
this.commentsInput.value = "";
141+
}
142+
})
143+
144+
//Append
145+
this.menu.append(this.menuTitle);
146+
this.menu.append(this.menuDescription);
147+
this.menu.append(this.commentsInput);
148+
this.menu.append(this.commentsButton);
149+
this.menu.append(this.menuComments);
150+
this.menuContainer.append(this.menu);
151+
root.append(this.menuContainer);
152+
153+
this.editableDescription = new EditableText(this.state.description, this.menuDescription, this, "description", "textarea");
154+
this.editableTitle = new EditableText(this.state.text, this.menuTitle, this, "text", "input");
155+
156+
this.renderComments();
157+
}
158+
159+
renderComments() {
160+
161+
let currentCommentsDOM = Array.from(this.menuComments.childNodes);
162+
163+
currentCommentsDOM.forEach(commentDOM => {
164+
commentDOM.remove();
165+
});
166+
167+
this.state.comments.forEach(comment => {
168+
new Comment(comment, this.menuComments, this);
169+
});
170+
}
171+
}
172+
173+
class EditableText {
174+
constructor(text, place, card, property, typeOfInput) {
175+
this.text = text;
176+
this.place = place;
177+
this.card = card;
178+
this.property = property;
179+
this.typeOfInput = typeOfInput;
180+
this.render();
181+
}
182+
183+
render() {
184+
this.div = document.createElement("div");
185+
this.p = document.createElement("p");
186+
187+
this.p.innerText = this.text;
188+
189+
this.p.addEventListener('click', () => {
190+
this.showEditableTextArea.call(this);
191+
});
192+
193+
this.div.append(this.p);
194+
this.place.append(this.div);
195+
}
196+
197+
showEditableTextArea() {
198+
let oldText = this.text;
199+
200+
this.input = document.createElement(this.typeOfInput);
201+
this.saveButton = document.createElement("button");
202+
203+
this.p.remove();
204+
this.input.value = oldText;
205+
this.saveButton.innerText = "Save";
206+
this.saveButton.className = "btn-save";
207+
this.input.classList.add("comment");
208+
209+
this.saveButton.addEventListener('click', () => {
210+
this.text = this.input.value;
211+
this.card.state[this.property] = this.input.value;
212+
if (this.property == "text") {
213+
this.card.p.innerText = this.input.value;
214+
}
215+
this.div.remove();
216+
this.render();
217+
});
218+
219+
function clickSaveButton(event, object) {
220+
// Number 13 is the "Enter" key on the keyboard
221+
if (event.keyCode === 13) {
222+
// Cancel the default action, if needed
223+
event.preventDefault();
224+
// Trigger the button element with a click
225+
object.saveButton.click();
226+
}
227+
}
228+
229+
this.input.addEventListener("keyup", (e) => {
230+
if (this.typeOfInput == "input") {
231+
clickSaveButton(e, this);
232+
}
233+
});
234+
235+
this.div.append(this.input);
236+
237+
if (this.typeOfInput == "textarea") {
238+
this.div.append(this.saveButton);
239+
}
240+
241+
this.input.select();
242+
}
243+
244+
}
245+
246+
class Comment {
247+
constructor(text, place, card) {
248+
this.text = text;
249+
this.place = place;
250+
this.card = card;
251+
this.render();
252+
}
253+
254+
render() {
255+
this.div = document.createElement('div');
256+
this.div.className = "comment";
257+
this.div.innerText = this.text;
258+
259+
this.place.append(this.div);
260+
}
261+
}
262+
263+
264+
265+
//-------------main------------
266+
267+
let addTodoListInput = document.getElementById("addTodoListInput");
268+
let addTodoListButton = document.getElementById("addTodoListButton");
269+
270+
addTodoListButton.addEventListener('click', () => {
271+
if (addTodoListInput.value.trim() !== "") {
272+
new ToDo(root, addTodoListInput.value); // Use user-provided title
273+
addTodoListInput.value = "";
274+
}
275+
});
276+
277+
let todoList1 = new ToDo(root); // Default title "To-Do"
278+
let todoList2 = new Doing(root, "Doing"); // Custom title "In Progress"
279+
let todoList3 = new Done(root, "Done"); // Custom title "Completed"

0 commit comments

Comments
 (0)