Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"
></script>
<script src="main.js" defer></script>
<link rel="stylesheet" href="style.css" />
<title>Chreddit</title>
</head>
<body>
<h1>Chreddit</h1>
<section class="posts container"></section>
<form action="" class="post-form container mt-3">
<input
class="post-name form-control mb-2"
type="text"
name="postName"
id=""
placeholder="Name"
/>
<input
class="post-message form-control mb-2"
type="text"
name="postMessage"
id=""
placeholder="Message"
/>
<button class="submitPostbtn btn btn-primary btn-lg" type="submit">
Submit Post
</button>
</form>
</body>
</html>
162 changes: 162 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
const posts = [];

const submitBtn = document.getElementsByClassName("submitPostbtn")[0];
const postsContainer = document.getElementsByClassName("posts")[0];

//builds posts and renders html accordingly
const renderPosts = () => {
// Clear all existing posts from the container
postsContainer.replaceChildren();

// Iterate through each post and create its UI elements
posts.forEach((post) => {
// Create DOM elements for the post card structure
const postCardDiv = document.createElement("div");
const cardHeaderDiv = document.createElement("div");
const cardBodyDiv = document.createElement("div");
const postP = document.createElement("p");
const removePostbtn = document.createElement("button");
const showCommentsbtn = document.createElement("button");
const commentsContainer = renderCommentsContainer(post);

// Add Bootstrap classes for styling
postCardDiv.classList.add("post", "card", "mb-4");
cardHeaderDiv.classList.add("card-header");
cardBodyDiv.classList.add("card-body");
postP.classList.add("card-text");
removePostbtn.classList.add("btn", "btn-danger", "mx-3");
showCommentsbtn.classList.add("btn", "btn-info", "btn-sm");

// Set the content for each element
cardHeaderDiv.textContent = `${post.name} posted...`;
postP.textContent = post.message;
removePostbtn.textContent = "Delete Post";
showCommentsbtn.textContent = "Show Comments";

// Add click handler for post deletion
removePostbtn.addEventListener("click", function (e) {
postsContainer.removeChild(e.target.parentNode.parentNode);
posts.splice(posts.indexOf(post), 1);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is mutating the array, better to use filter.

});

// Add click handler to toggle comments visibility
showCommentsbtn.addEventListener("click", function () {
if (commentsContainer.classList.contains("d-none")) {
commentsContainer.classList.remove("d-none");
} else {
commentsContainer.classList.add("d-none");
}
});

// create tree stucture to organize html correctly
postCardDiv.appendChild(cardHeaderDiv);
postCardDiv.appendChild(cardBodyDiv);
cardBodyDiv.append(postP);
cardHeaderDiv.appendChild(removePostbtn);
cardBodyDiv.appendChild(showCommentsbtn);
postCardDiv.appendChild(commentsContainer);
postsContainer.appendChild(postCardDiv);
});
};

//takes in a single post object and renders comments container div html element.
//returns the comments container
const renderCommentsContainer = (post) => {
//create dom elements for structure
const commentsContainer = document.createElement("div");
const commentsDiv = document.createElement("div");
const commentUl = document.createElement("ul");
const commentsForm = document.createElement("form");
const commentNameInput = document.createElement("input");
const commentMessageInput = document.createElement("input");
const commentSubmitbtn = document.createElement("button");

//add boostrap classes for styling
commentsContainer.classList.add(
"comments-container",
"ms-3",
"p-2",
"rounded"
);
commentsDiv.classList.add("card", "mb-4");
commentUl.classList.add("list-group", "list-group-flush");
commentsForm.classList.add("rounded", "p-2");
commentNameInput.classList.add("comment-name", "form-control", "mb-1");
commentMessageInput.classList.add("comment-message", "form-control", "mb-1");
commentNameInput.setAttribute("placeholder", "Comment Name");
commentMessageInput.setAttribute("placeholder", "Comment Message");
commentSubmitbtn.classList.add("btn", "btn-outline-primary");

//add text content
commentSubmitbtn.textContent = "Submit Comment";

//add submit event listener to comment submit button
commentSubmitbtn.addEventListener("click", function (e) {
e.preventDefault();
const commentName =
e.target.parentNode.getElementsByClassName("comment-name")[0].value;
const commentMesage =
e.target.parentNode.getElementsByClassName("comment-message")[0].value;
post.comments.push({ name: commentName, message: commentMesage });
renderCommentList(post.comments, commentUl);
e.target.parentNode.getElementsByClassName("comment-name")[0].value = "";
e.target.parentNode.getElementsByClassName("comment-message")[0].value = "";
});

commentsForm.appendChild(commentNameInput);
commentsForm.appendChild(commentMessageInput);
commentsForm.appendChild(commentSubmitbtn);
commentsDiv.appendChild(commentUl);

renderCommentList(post.comments, commentUl);

commentsContainer.appendChild(commentsDiv);
commentsContainer.appendChild(commentsForm);
return commentsContainer;
};

// renders list of comments, takes in array of comment objects as first argument, comment UL html element as second argument.
const renderCommentList = (comments, commentUl) => {
// Clear all existing comments from the comment list
commentUl.replaceChildren();
// Iterate through each comment and create its UI elements
comments.forEach((comment) => {
const commentLi = document.createElement("li");
const deleteCommentbtn = document.createElement("button");

// add bootstrap classes for styling
commentLi.classList.add("list-group-item");
deleteCommentbtn.classList.add(
"btn",
"btn-outline-danger",
"mx-2",
"btn-sm"
);

//set the content for elements
commentLi.innerHTML = `${comment.name} commented: ${comment.message}`;
deleteCommentbtn.textContent = "Remove Comment";

//add detete comment event listener to delete button
deleteCommentbtn.addEventListener("click", function (e) {
commentUl.removeChild(e.target.parentNode);
comments.splice(comments.indexOf(comment), 1);
});

// create tree stucture to organize html correctly
commentLi.appendChild(deleteCommentbtn);
commentUl.appendChild(commentLi);
});
};

//add submit event listener to post submit button
submitBtn.addEventListener("click", function (e) {
e.preventDefault();
const postInputName = document.getElementsByClassName("post-name")[0].value;
const postInputMessage =
document.getElementsByClassName("post-message")[0].value;
posts.push({ name: postInputName, message: postInputMessage, comments: [] });
document.getElementsByClassName("post-name")[0].value = "";
document.getElementsByClassName("post-message")[0].value = "";
renderPosts();
});
16 changes: 16 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.post {
background-color: #78d5d7;
}

.comments-container,
.comments-container li {
background-color: #bed8d4;
}

.comments-container form {
background-color: #f9faf7;
}

body {
background-color: #f9faf7;
}