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
Binary file added assets/img/DoubleR-LOGO.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous" ></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" href="scss/styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="module" src="js/apps.js" defer></script>
<title>Blog with Api</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#" aria-label="Logo doubleR">
<img src="assets/img/DoubleR-LOGO.jpg" alt="Logo doubleR">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" aria-current="page" href="#">FAQ</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Blogs
</a>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</body>
</html>
109 changes: 109 additions & 0 deletions js/Modal/modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
class Modal{

constructor(title, body, edit, posts){
$("<div></div>").addClass("modal fade show").attr("tabindex", "-1").attr("style", "display: block;").css("background-color", "rgba(0,0,0,0.3)")
.append($("<div></div>").addClass("modal-dialog modal-dialog-centered mw-100")
.append($("<div></div>").addClass("modal-content")
.append($("<div></div>").addClass("modal-body d-flex flex-column")
.append($("<h3></h3>").addClass("modal-title").text(title))
.append($("<img></img>").addClass("img-close rounded-circle").attr("src", "./assets/img/close.png"))
.append($("<pre></pre>").text(body))
.append($("<h5></h5>").addClass("modal-title").text("User"))
)
.append($("<div></div>").addClass("modal-footer d-flex align-items-start flex-column")
.append($("<h3></h3>").addClass("modal-title").text("Comments"))
.append($("<button></button>").addClass("btn btn-dark").text("Load Comments"))
)
)
)
.appendTo("body");

posts.then(function(post){

fetch("https://jsonplaceholder.typicode.com/users/" + post.userId,
{
method: "GET",
})
.then(function(res) {
return res.json();
})
.then(function (user) {
$("<span></span>").text(user.name).appendTo(".modal-body");
$("<span></span>").text(user.email).appendTo(".modal-body");
})

fetch("https://jsonplaceholder.typicode.com/posts/" + post.id + "/comments",
{
method: "GET",
})
.then(function(res) {
return res.json();
})
.then(function (comments) {
comments.forEach(comment => {
//Load comments
$(".btn-dark").on("click", function(){
if($(".modal-footer").children().first().children().length <= 1){
posts.then(function(){
$(".modal-footer").children().first().append($("<h5></h5>").text(comment.name));
$(".modal-footer").children().first().append($("<p></p>").text(comment.body));
});
$(".btn-dark").remove();
}
});
});
})
});

//Close button
$("img").on("click", function(){ $(".modal").remove(); });
$(".modal").on("click", function(e){ if(e.target.classList.contains("fade")) $(".modal").remove(); });

//Only when is edit modal
if(edit){
$(".modal-body").find("h3").remove();
$(".modal-body").find("pre").remove();
$(".modal-footer").children().remove();
$("<div></div>").append($("<input></input>").addClass("form-control").attr("placeholder", title)).addClass("form-group col-sm-8").prependTo(".modal-body");
$("<div></div>").append($("<textarea></textarea>").addClass("form-control").attr("placeholder", body)).addClass("form-group col-sm-10").insertAfter(".img-close");
$(".modal-footer").append($("<button></button>").addClass("btn btn-primary save-button").text("Save"));

//Save event
$(".save-button").on("click", function(){
const title = $("input").val();
const body = $("textarea").val();
if(String(title).trim() != " " && String(title).trim() != "" && String(body).trim() != " " && String(body).trim() != ""){
posts.then(function(post){
//Edit post
fetch("https://jsonplaceholder.typicode.com/posts/" + post.id,
{
method: "PATCH",
headers: {
"Content-type": "application/json; charset=UTF-8",
},
body: JSON.stringify({
title: title,
body: $("textarea").val(),
}),
})
.then(function (response) {
return response.json();
})
.then(function (json) {
//Refresh data
const row = $("tbody").find("scope").prevObject[(post.id - 1)];
$(row).find("#postTitle")[0].textContent = json.title;
$(row).find("#postBody")[0].textContent = json.body;
$(".modal").remove();
});

});
}
});
}

}

}

export default Modal;
122 changes: 122 additions & 0 deletions js/apps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import Modal from "./Modal/modal.js";

// Getting the API
fetch("https://jsonplaceholder.typicode.com/posts",
{
method: "GET",
})
.then(function(res) {
return res.json();
})
.then(function (json) {
let postTitle = document.querySelectorAll("#postTitle")
let postBody = document.querySelectorAll("#postBody")
for (let i = 0; i < postTitle.length; i++) {
const titleApi = json[i];
postTitle[i].textContent = titleApi["title"]
postBody[i].textContent = titleApi["body"]
}
})

//Generate main page
var bodyVar = document.body
var divBlogs = document.createElement("div")
divBlogs.className = "container"
var theadHtml = document.createElement("thead")
theadHtml.innerHTML = "<tr><th scope='col'></th><th scope='col'>Blog Name</th><th scope='col'>Blog body</th></tr>"
var tableHtml = document.createElement("table")
tableHtml.className = "table table-hover"
divBlogs.appendChild(tableHtml)
tableHtml.appendChild(theadHtml)
for (let i = 1; i<7; i++) {
var tbodyHtml = document.createElement("tbody")
tbodyHtml.innerHTML = "<tr class='h-50 mainRow'><th id='number' scope='row'>"+ i +"</th><td id='postTitle'></td><td id='postBody'></td><td><svg style='cursor:pointer' xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-pencil-square edit' viewBox='0 0 16 16'><path class='edit' d='M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z'/><path class='edit' fill-rule='evenodd' d='M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z'/></svg></td><td><svg style='cursor:pointer' xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-x-circle delete' viewBox='0 0 16 16'><path class='delete' d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/><path class='delete' d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z'/></svg></td></tr>"
tableHtml.appendChild(tbodyHtml)
}
bodyVar.appendChild(divBlogs)


//Add Event Listeners
function openModal(e) {
e.stopPropagation();

if(e.target instanceof SVGElement){
//Edit
if(e.target.classList.contains("edit")){
if(e.target instanceof SVGPathElement) {
new Modal(e.target.parentNode.parentNode.parentNode.children[1].textContent, e.target.parentNode.parentNode.parentNode.children[2].textContent, true,
fetchPosts(e.target.parentNode.parentNode.parentNode.children[0].textContent));
}
else new Modal(e.target.parentNode.parentNode.children[1].textContent, e.target.parentNode.parentNode.children[2].textContent, true,
fetchPosts(e.target.parentNode.parentNode.children[0].textContent));
}
//Delete
if(e.target.classList.contains("delete")){
if(e.target instanceof SVGPathElement) {
fetch("https://jsonplaceholder.typicode.com/posts/" + e.target.parentNode.parentNode.parentNode.children[0].textContent,{
method: "DELETE",
})
$(e.target.parentNode.parentNode.parentNode).remove();
}
else {
fetch("https://jsonplaceholder.typicode.com/posts/" + e.target.parentNode.parentNode.children[0].textContent,{
method: "DELETE",
})
$(e.target.parentNode.parentNode).remove();
}
}

//View Modal
} else {
new Modal(e.target.parentNode.children[1].textContent, e.target.parentNode.children[2].textContent, false,
fetchPosts(e.target.parentNode.children[0].textContent));
}
}

async function fetchPosts(id){
const res = await fetch("https://jsonplaceholder.typicode.com/posts/" + id,
{
method: "GET",
});
const json = await res.json();
return json;
}

var mainRow = document.getElementsByClassName("mainRow")
for (let i = 0; i < mainRow.length; i++) {
mainRow[i].addEventListener("click", openModal)
}

$(window).on("scroll", function() {
if(Math.trunc($(window).scrollTop() + 2) >= $(document).height() - $(window).height()) {
fetch("https://jsonplaceholder.typicode.com/posts",
{
method: "GET",
})
.then(function(res) {
return res.json();
})
.then(function (json) {
let postTitle = document.querySelectorAll("#postTitle")
let postBody = document.querySelectorAll("#postBody")
for (let i = 0; i < postTitle.length; i++) {
const titleApi = json[i];
postTitle[i].textContent = titleApi["title"]
postBody[i].textContent = titleApi["body"]
}
})
const limit = 100;
var number = document.querySelectorAll("#number")
if(number.length < limit) {
for (let i = number.length; i < number.length + 5; i++) {
var newNumb = i + 1;
if(newNumb <= limit){
var tbodyHtml = document.createElement("tbody");
tbodyHtml.innerHTML = "<tr class='h-50 mainRow'><th id='number' scope='row'>"+ newNumb +"</th><td id='postTitle'></td><td id='postBody'></td><td><svg style='cursor:pointer' xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-pencil-square edit' viewBox='0 0 16 16'><path d='M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z'/><path fill-rule='evenodd' d='M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z'/></svg></td><td><svg style='cursor:pointer' xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-x-circle delete' viewBox='0 0 16 16'><path d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/><path d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z'/></svg></td></tr>"
tableHtml.appendChild(tbodyHtml);
mainRow[i].addEventListener("click", openModal);
}
}
}
}
});
Loading