spt
spt

Reputation: 407

unable to retrive the data dynamically by filtering from database using servlets and mysql

I created a Dynamic Java Project with eclipse using sevlets mysql and trying to retrive the data dynamically when selected the particular discipline or batch. everything working fine and also the getting json response but nothing is displayed when executed. this is my servletPortfolioServlet.java

 @WebServlet("/portfolios")
    public class PortfolioServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("application/json");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            JSONArray portfolioList = new JSONArray();
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                // Database Connection
                Class.forName("com.mysql.cj.jdbc.Driver");
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxxx?useSSL=false", "root","xxxx");
                stmt = conn.createStatement();
                rs = stmt.executeQuery("SELECT * FROM users");
    
                // Convert ResultSet to JSON
                while (rs.next()) {
                    JSONObject portfolio = new JSONObject();
                    portfolio.put("id", rs.getInt("id"));
                    portfolio.put("full_name", rs.getString("full_name"));
                    portfolio.put("discipline", rs.getString("discipline"));
                    portfolio.put("batch", rs.getString("batch"));
                    portfolio.put("keywords", rs.getString("keywords"));
                    portfolio.put("profile_photo", "image?type=profile_photo&id=" + rs.getInt("id")); 
                    portfolio.put("background_image", "image?type=background_image&id=" + rs.getInt("id"));
                    portfolioList.put(portfolio);
                }
                out.print(portfolioList.toString());
                out.flush();
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                JSONObject errorResponse = new JSONObject();
                errorResponse.put("error", "Failed to load portfolios: " + e.getMessage());
                out.print(errorResponse.toString());
                out.flush();
    
            } finally {
                try {
                    if (rs != null)
                        rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    if (stmt != null)
                        stmt.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    if (conn != null)
                        conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

ImageServlet.java:

@WebServlet("/image")
public class ImageServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String type = request.getParameter("type"); // "portfolio", or "background"
        int id = Integer.parseInt(request.getParameter("id"));

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxxx?useSSL=false", "root","xxxx");
            PreparedStatement stmt = conn.prepareStatement("SELECT " + type + " FROM users WHERE id = ?");
            stmt.setInt(1, id);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()) {
                byte[] imgData = rs.getBytes(1);
                String contentType = "image/jpeg"; // Default
                if (imgData.length > 4 && imgData[0] == (byte) 0x89 && imgData[1] == (byte) 0x50) {
                    contentType = "image/png"; // PNG signature detected
                }
                response.setContentType(contentType);
                OutputStream os = response.getOutputStream();
                os.write(imgData);
                os.close();
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

index.html:

<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" />
      <link rel="stylesheet" href="assets/css/style.css" />
      <title></title>
    </head>
    <body>
      <section class="header">
        <div class="hero__container">
          <div class="logo__container">
            <img src="assets/images/logo.png" alt="Logo" />
          </div>
          <div class="hero__content">
            <p>Discover diverse portfolios from <br />the xxxxx</p>
            <div class="connect__data">
              <div class="hero__title-1"><span>connect</span><div class="circle"></div></div>
              <div class="hero__title-2"><span>collaborate</span><div class="circle"></div></div>
              <div class="hero__title-3"><span>create</span><div class="circle"></div><div class="circle-cut"></div></div>
            </div>
          </div>
        </div>
      </section>
    
      <!-- Filters Container -->
      <section class="body__container">
        <div class="filter__container">
          <div class="filter_buttons">
            <button class="filter-btn active" data-name="All">All Programs</button>
            <button class="filter-btn" data-name="IndustrialDesign">Industrial Design</button>
            <button class="filter-btn" data-name="CommunicationDesign">Communication Design</button>
            <button class="filter-btn" data-name="TextileandApparelDesign">Textile and Apparel Design</button>
          </div>
    
          <!-- Dropdown Menu -->
          <div class="dropdown">
            <div class="select">
              <div class="selected placeholder">All batches</div>
              <i class="bi bi-chevron-down caret"></i>
            </div>
          </div>
        </div>
    
        <!-- Dynamic Card Container -->
        <div class="card-container">
          <!-- Cards will be loaded dynamically here -->
        </div>
      </section>
    
      <script src="assets/js/index.js"></script>
    </body>
    </html>

JavaScript:

document.addEventListener("DOMContentLoaded", function() { console.log("Script loaded, waiting for portfolios...");

    const cardContainer = document.querySelector(".card-container");
    if (!cardContainer) {
        console.error("Error: .card-container not found!");
        return;
    }

    const loadingMessage = document.createElement("p");
    loadingMessage.className = "loading-message";
    loadingMessage.innerText = "Loading portfolios...";
    cardContainer.appendChild(loadingMessage);

    console.log("Fetching data from /portfolios...");

    fetch("/Student/portfolios")
        .then(response => {
            console.log("Response received:", response);

            if (!response.ok) {
                throw new Error(`HTTP error! Status: ${response.status}`);
            }

            return response.json();
        })
        .then(data => {
            console.log("Fetched data:", data);

            cardContainer.innerHTML = ""; // Clear loading message

            if (!Array.isArray(data) || data.length === 0) {
                console.warn("No portfolios found:", data);
                cardContainer.innerHTML = "<p>No portfolios found.</p>";
                return;
            }

            data.forEach(portfolio => {
                console.log("Processing portfolio:", portfolio);

                const profilePhotoURL = "/Student" + portfolio.profile_photo;
                const backgroundImageURL = "/Student" + portfolio.background_image;

                console.log("Updated Profile Photo URL:", profilePhotoURL);
                console.log("Updated Background Image URL:", backgroundImageURL);

                const cardHTML = `
                <div class="card" data-name="${portfolio.discipline}" data-batch="${portfolio.batch}">
                    <img class="card__image" src="${portfolio.background_image}" alt="Portfolio Image" />
                    <div class="card__overlay">
                        <div class="card__header">
                            <img src="${portfolio.profile_photo}" class="card__thumb" alt="Profile Image" />
                            <div class="card__header-text">
                                <h3 class="card__title">${portfolio.full_name}</h3>
                                <p class="card__status">${portfolio.discipline}, ${portfolio.batch}</p>
                            </div>
                        </div>
                        <div class="card__descraption-box">
                            <h3 class="card__descraption-title">Interests</h3>
                            <p class="card__descraption">${portfolio.keywords}</p>
                        </div>
                    </div>
                </div>`;
                cardContainer.insertAdjacentHTML("beforeend", cardHTML);
            });

            console.log("Portfolios successfully loaded.");
            filterCardsByData();
        })
        .catch(error => {
            console.error("Error loading portfolios:", error);
            cardContainer.innerHTML = `<p>Error loading portfolios. Please try again later.</p>`;
        });
});


// **Filtering Logic**
// Select all filter buttons, filterable cards, and dropdowns
const filterButtons = document.querySelectorAll(".filter_buttons button");
const filterableCards = document.querySelectorAll(".card-container .card");
const dropdowns = document.querySelectorAll(".dropdown");

// Common filtering logic
function filterCardsByData(selectedFilter) {
  filterableCards.forEach((card) => {
    const cardBatch = card.getAttribute("data-batch");
    const cardName = card.dataset.name;

    // Show or hide the card based on filter condition
    if (
      selectedFilter === "All batches" ||
      selectedFilter === "" ||
      cardBatch === selectedFilter ||
      cardName === selectedFilter
    ) {
      // Show card and add reveal animation
      card.classList.remove("hide", "exit");
      setTimeout(() => {
        card.classList.add("reveal"); // Add reveal class for the animation
      }, 10);

      setTimeout(() => {
        card.classList.add("visible"); // Ensure visibility after animation
      }, 500); // Adjust based on reveal animation duration
    } else {
      // Apply exit animation before hiding the card
      card.classList.remove("reveal", "visible");
      card.classList.add("exit");
      setTimeout(() => {
        card.classList.add("hide");
      }, 500); // Ensure card hides after exit animation
    }
  });
}

// Button click event
filterButtons.forEach((button) => {
  button.addEventListener("click", (e) => {
    // Update active button state
    document
      .querySelector(".filter_buttons .active")
      .classList.remove("active");
    e.target.classList.add("active");

    // Get filter value from the button's data-name attribute or default to "All batches"
    const filterValue = e.target.dataset.name || "All batches";

    // Apply the filter
    filterCardsByData(filterValue);
  });
});

// Dropdown logic
dropdowns.forEach((dropdown) => {
  const select = dropdown.querySelector(".select");
  const caret = dropdown.querySelector(".caret");
  const selected = dropdown.querySelector(".selected");
  const menu = document.createElement("ul");

  menu.className = "menu";

  const menuItems = [
    "All batches",
    "Batch of 2017",
    "Batch of 2018",
    "Batch of 2019",
    "Batch of 2020",
    "Batch of 2021",
    "Batch of 2022",
    "Batch of 2023",
    "Batch of 2024",
  ];

  // Add menu items dynamically
  menuItems.forEach((item) => {
    const option = document.createElement("li");
    option.innerText = item;

    // Handle dropdown item selection
    option.addEventListener("click", () => {
      selected.innerText = item;
      caret.classList.remove("caret-rotate");
      menu.classList.remove("menu-open");

      // Add dd-active to the selected option and remove it from others
      menu.querySelectorAll("li").forEach((opt) => {
        opt.classList.remove("dd-active"); // Remove dd-active from all items
      });
      option.classList.add("dd-active"); // Add dd-active to the clicked option

      // Apply the filter
      filterCardsByData(item);
    });

    menu.appendChild(option);
  });

  dropdown.appendChild(menu);

  // Toggle dropdown visibility
  select.addEventListener("click", (event) => {
    event.stopPropagation();
    caret.classList.toggle("caret-rotate");
    menu.classList.toggle("menu-open");
  });

  // Close dropdown if clicked outside
  document.addEventListener("click", (event) => {
    if (!dropdown.contains(event.target)) {
      caret.classList.remove("caret-rotate");
      menu.classList.remove("menu-open");
    }
  });
});

// Ensure cards are visible on page load or refresh by applying the default filter
document.addEventListener("DOMContentLoaded", () => {
  // Trigger the default filter to show all cards (or set to a specific filter if needed)
  filterCardsByData("All batches");
});

CSS:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
/* Font-Falimy  */
@font-face {
  font-family: "manrope-bold";
  src: url(./../fonts/manrope.bold.otf);
}
@font-face {
  font-family: "manrope-extrabold";
  src: url(./../fonts/manrope.extrabold.otf);
}
@font-face {
  font-family: "manrope-light";
  src: url(./../fonts/manrope.light.otf);
}
@font-face {
  font-family: "manrope-medium";
  src: url(./../fonts/manrope.medium.otf);
}
@font-face {
  font-family: "manrope-regular";
  src: url(./../fonts/manrope.regular.otf);
}
:root {
  --baseWhite: #ffffff;
  --accentBlue: #0048ff;
  --textGray: #838383;
  --secoundaryGray: #b3b3b3;
}
body {
  font-family: "manrope-regular" !important;
  font-size: 16px;
  min-height: 100vh;
  background-color: var(--baseWhite);
}
/* .container {
    width: 90%;
    margin: 0 0 0 1em;
} */
.container {
  width: 90%;
  margin: 0 auto;
}
.hero__container {
  width: 98%;
  margin: 10px 0 10px 20px;
}
.logo__container {
  border: 1px solid black;
  width: 253px;
  border-radius: 10px;
  float: right;
  margin: 10px 10px 0 0;
}
.logo__container img {
  width: 250px;
  border-radius: 10px;
}
/* Hero Section */
.hero__container p {
  clear: both;
  font-size: 16px;
  color: var(--textGray);
}
.hero__title-1 {
  width: 100%;
  font-size: 48px;
  font-weight: 300;
  color: black;
  position: relative;
  display: inline-block;
}
.hero__title-1 span {
  font-size: 120px;
  font-family: "manrope-light";
  line-height: 1.1;
}
.hero__title-1::after {
  content: " ";
  height: 7px;
  width: auto;
  background: var(--accentBlue);
  display: block;
  position: absolute;
  top: 80%;
  left: 10.5em;
  right: 0;
}
.hero__title-1 .circle {
  position: absolute;
  width: 77px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: 64px;
  background: linear-gradient(to bottom, #1c40a5, #728dd1);
  border-radius: 50%;
  margin: 0 5px;
}
.hero__title-2 {
  margin-top: 10px;
  width: 100%;
  font-size: 48px;
  font-weight: 300;
  color: black;
  position: relative;
  display: inline-block;
}
.hero__title-2 span {
  font-size: 120px;
  font-family: "manrope-bold";
  line-height: 1.1;
}
.hero__title-2::after {
  content: " ";
  height: 7px;
  width: auto;
  background: var(--accentBlue);
  display: block;
  position: absolute;
  top: 80%;
  left: 15em;
  right: 0;
}
.hero__title-2 .circle {
  position: absolute;
  /* Position relative to the container */
  width: 77px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: 69px;
  background: linear-gradient(to bottom, #1c40a5, #728dd1);
  border-radius: 50%;
  margin: 0 5px;
}
.hero__title-3 {
  margin-top: 10px;
  width: 100%;
  font-size: 48px;
  font-weight: 300;
  color: black;
  position: relative;
  display: inline-block;
}
.hero__title-3 span {
  font-size: 120px;
  font-family: "manrope-bold";
  line-height: 1.1;
}
.hero__title-3::after {
  content: " ";
  height: 7px;
  width: auto;
  background: var(--accentBlue);
  display: block;
  position: absolute;
  top: 80%;
  left: 8.9em;
  right: 0;
}
.hero__title-3 .circle {
  position: absolute;
  width: 77px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: -1px;
  background: linear-gradient(to bottom, #1c40a5, #728dd1);
  border-radius: 50%;
  margin: 0 5px;
}
.circle-cut {
  position: absolute;
  width: 15px;
  height: 77px;
  /* opacity: .8; */
  top: 39px;
  left: 61px;
  background-color: var(--baseWhite);
  margin: 0 5px;
  cursor: not-allowed;
}
/* Body Start */
.body__container {
  width: 95%;
  margin: 0 auto;
  height: auto;
}
/*  */
/* Dropdown Section */
.filter__container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 2em 0;
  border-bottom: 1px solid black;
}
.filter_buttons {
  gap: 30px;
  display: flex;
}
button.filter-btn {
  padding: 20px 0;
  font-family: "manrope-regular";
  font-size: 16px;
  cursor: pointer;
  background-color: var(--baseWhite);
  border: none;
}
.filter-btn.active {
  border-bottom: 2px solid var(--accentBlue);
}

.dropdown {
  display: inline-block;
  position: relative;
}
.label {
  margin-bottom: 3px;
}
/* Select container */
.select {
  cursor: pointer;
  transition: 0.3s;
  background-color: var(--baseWhite);
  border-radius: 5px;
  border: 1px solid black;
  display: flex;
  padding: 5px 15px;
  align-items: center;
  justify-content: space-between;
}
.selected {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.caret {
  margin-left: 10px;
  transition: 0.3s;
}
/* Hover effect for the select container */
.select:hover {
  background-color: var(--secoundaryGray);
}
/* Dropdown Menu Animation */
.menu {
  visibility: hidden;
  border-radius: 5px;
  border: 1px solid black;
  background-color: var(--baseWhite);
  overflow: hidden;
  position: absolute;
  width: 100%;
  top: 146%;
  opacity: 0;
  transform: translateY(-20px);
  transition: visibility 0s, opacity 0.3s ease, transform 0.3s ease;
  z-index: 10;
}
.menu-open {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
}
/* Caret animation */
.caret {
  margin-left: 10px;
  transition: transform 0.3s ease;
}
.caret-rotate {
  transform: rotate(180deg);
}
/* Menu items */
.menu li {
  cursor: pointer;
  padding: 10px;
}
/* Hover effect for menu items */
.menu li:hover {
  background-color: var(--secoundaryGray);
}
/* Active item style */
.dd-active {
  background-color: var(--accentBlue);
  color: #fff;
}
/* "All batches" - Make clickable */
.menu li:first-child {
  font-weight: normal;
  cursor: pointer;
}
/* Show all batches filter text */
.show-all-batches {
  font-weight: bold;
  color: var(--accentBlue);
  cursor: pointer;
  padding: 10px;
}
/* Card Container */
.card-container {
  margin: 2em 0 5em 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 50px;
}
.card {
  transform: scale(0) translate(0, 0);
  opacity: 0;
  transition: transform 0.5s ease, opacity 0.5s ease;
  transform-origin: top left;
}
/* When the card becomes visible */
.card.visible {
  transform: scale(1) translate(0, 0);
  opacity: 1;
}
.card {
  background-color: var(--baseWhite);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  width: 417px;
  height: 312px;
  transition: transform 0.3s ease;
  position: relative;
}
.card.hide {
  display: none;
}
.card__image {
  width: 100%;
  height: 100%;
  max-height: auto;
  object-fit: cover;
}
.card__overlay {
  position: absolute;
  bottom: 0;
  height: 257px;
  left: 0;
  right: 0;
  z-index: 1;
  background-color: rgba(39, 39, 39, 0.6);
  backdrop-filter: blur(5px);
  transform: translateY(100%);
  transition: transform 0.3s ease-in-out, box-shadow 0.4s ease-in-out;
  color: var(--baseWhite);
}
.card:hover .card__overlay {
  transform: translateY(0);
  box-shadow: 0 8px 15px rgba(0, 0, 0, 0);
}
.card__header {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2rem;
  background-color: rgba(33, 33, 33, 0.9);
  padding: 2em;
  transform: translateY(-100%);
  transition: 0.3s ease-in-out;
  font-size: 16px;
  font-family: "manrope-regular";
}
.card:hover .card__header {
  transform: translateY(0);
  background-color: rgba(33, 33, 33, 0);
  transition: 0.3s ease-in-out;
  transition-delay: 0s;
}
.card__thumb {
  flex-shrink: 0;
  width: 3.125em;
  height: 3.125em;
  border-radius: 50%;
}
.card__title {
  font-size: 16px;
  margin: 0 0 0.3rem;
  font-family: "manrope-bold";
}
.card__status {
  font-size: 16px;
}
.card__descraption-box {
  padding: 0 2em 0 7em;
  font-size: 16px;
}
.card__descraption-title {
  margin: 0;
  font-size: 16px;
  font-family: "manrope-bold";
}
.card__descraption {
  font-size: 16px;
  font-family: "manrope-regular";
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@keyframes revealAnimation {
  0% {
    transform: scale(0) translate(-50%, -50%);
    opacity: 0;
  }
  100% {
    transform: scale(1) translate(0, 0);
    opacity: 1;
  }
}

I want a display as per below screenshot, but i am empty results/data when filtering or when executed: Output required

But getting below output and displaying message when refreshing the page "loading portfolios..." enter image description here

So please guide me where is the exact problem why the data is not displaying. I am debugging the code many times but not able to find the actual problem.

Upvotes: -4

Views: 43

Answers (0)

Related Questions