Javascript – CodingNepal https://www.codingnepalweb.com CodingNepal is a blog dedicated to providing valuable and informative content about web development technologies such as HTML, CSS, JavaScript, and PHP. Fri, 15 Dec 2023 12:17:32 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.2 Build An AI Image Generator Website in HTML CSS and JavaScript https://www.codingnepalweb.com/ai-image-generator-website-html-javascript/ https://www.codingnepalweb.com/ai-image-generator-website-html-javascript/#respond Fri, 15 Dec 2023 01:52:37 +0000 https://www.codingnepalweb.com/?p=5761 Build An AI Image Generator Website in HTML CSS and JavaScript

Websites like Midjourney and DALL-E have gained significant popularity in recent months or years for their ability to generate creative and imaginative images using AI. If you’re a beginner web developer, have you ever considered creating your own version of an AI image generator website? The great news is that with the help of only HTML, CSS, and JavaScript, you too can build a website like Midjourney or DALL-E.

If you’re unfamiliar, Midjourny and DALL-E are AI image-generation websites. They use a machine-learning model to create images based on text descriptions. Users can input their desired image prompt, and these websites will generate a corresponding image that matches the description.

In this blog post, I will provide a step-by-step guide on how to build your own website for generating AI images using HTML, CSS, and JavaScript. The website will be built entirely from scratch using pure JavaScript. So, as a beginner, you can gain practical experience by applying your newly learned HTML, CSS, and JavaScript skills to real-world web projects.

On this custom AI image generation website, users enter their prompt, choose the number of images they want to generate, and click the “Generate” button. The AI will then create images based on the user prompt. To download each image, the user can click on the corresponding download button provided.

Video Tutorial of AI Image Generator HTML and JavaScript

If you enjoy learning through video tutorials, the above YouTube video can be an excellent resource. In the video, I’ve explained each line of code and included informative comments to make building your own AI image generator website simple and easy to follow.

However, if you like reading blog posts or want a step-by-step guide for this project, you can continue reading this post. By the end of this post, you will have your own AI image generator website that you can showcase with your friends and include in your portfolio.

Steps to Build AI Image Generator Website HTML & JavaScript

To build an AI image generator website using HTML, CSS, and vanilla JavaScript, follow these simple step-by-step instructions:

  • First, create a folder with any name you like. Then, make the necessary files inside it.
  • Create a file called index.html to serve as the main file.
  • Create a file called style.css for the CSS code.
  • Create a file called script.js for the JavaScript code.
  • Finally, download the Images folder and put it in your project directory. This folder contains default showcase images for the website. You can also use your own images.

To start, add the following HTML codes to your index.html file. These codes include essential HTML markup with different semantic tags, such as div, form, input, button, image, etc., to build the website layout.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>AI Image Generator HTML CSS and JavaScript | CodingNepal</title>
  <link rel="stylesheet" href="style.css">
  <script src="script.js" defer></script>
</head>
<body>
  <section class="image-generator">
    <div class="content">
      <h1>AI Image Generator Tool JavaScript</h1>
      <p>Convert your text into an image within a second using this
        JavaScript-powered AI Image Generator tool.</p>
      <form action="#" class="generate-form">
        <input class="prompt-input" type="text" placeholder="Describe what you want to see" required>
        <div class="controls">
          <select class="img-quantity">
            <option value="1">1 Image</option>
            <option value="2">2 Images</option>
            <option value="3">3 Images</option>
            <option value="4" selected>4 Images</option>
          </select>
          <button type="submit" class="generate-btn">Generate</button>
        </div>
      </form>
    </div>
  </section>
  <section class="image-gallery">
    <div class="img-card"><img src="images/img-1.jpg" alt="image"></div>
    <div class="img-card"><img src="images/img-2.jpg" alt="image"></div>
    <div class="img-card"><img src="images/img-3.jpg" alt="image"></div>
    <div class="img-card"><img src="images/img-4.jpg" alt="image"></div>
  </section>
</body>
</html>

Next, add the following CSS codes to your style.css file to make your AI image generator website beautiful and user-friendly. You can customize the different CSS properties, such as color, background, font, etc., to give a personalized touch to your website. Now, if you load the web page in your browser, you can see your AI image generator website with four preloaded images.

/* Importing Google font - Poppins */
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

.image-generator {
  height: 40vh;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  background: url("images/bg.jpg");
  background-size: cover;
  background-position: center;
}

.image-generator::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 0.5;
  background: #121212;
}

.image-generator .content {
  position: relative;
  color: #fff;
  padding: 0 15px;
  max-width: 760px;
  text-align: center;
}

.image-generator h1 {
  font-size: 2.5rem;
  font-weight: 700;
}

.image-generator p {
  margin-top: 10px;
  font-size: 1.35rem;
}

.image-generator .generate-form {
  height: 56px;
  padding: 6px;
  display: flex;
  margin-bottom: 15px;
  background: #fff;
  align-items: center;
  border-radius: 30px;
  margin-top: 45px;
  justify-content: space-between;
}

.generate-form .prompt-input {
  width: 100%;
  height: 100%;
  outline: none;
  padding: 0 17px;
  border: none;
  background: none;
  font-size: 1rem;
  border-radius: 30px;
}

.generate-form .controls {
  display: flex;
  height: 100%;
  gap: 15px;
}

.generate-form .img-quantity {
  outline: none;
  border: none;
  height: 44px;
  background: none;
  font-size: 1rem;
}

.generate-form .generate-btn {
  font-size: 1rem;
  outline: none;
  border: none;
  font-weight: 500;
  color: #fff;
  cursor: pointer;
  height: 100%;
  padding: 0 25px;
  border-radius: 30px;
  background: #4949E7;
}

.generate-form .generate-btn[disabled] {
  opacity: 0.6;
  pointer-events: none;
}

.generate-form button:hover {
  background: #1d1de2;
}

.image-gallery {
  display: flex;
  gap: 15px;
  padding: 0 15px;
  flex-wrap: wrap;
  justify-content: center;
  margin: 50px auto;
  max-width: 1250px;
}

.image-gallery .img-card {
  display: flex;
  position: relative;
  align-items: center;
  justify-content: center;
  background: #f2f2f2;
  border-radius: 4px;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  width: 285px;
}

.image-gallery .img-card img {
  height: 100%;
  width: 100%;
  object-fit: cover;
}

.image-gallery .img-card.loading img {
  width: 80px;
  height: 80px;
}

.image-gallery .img-card .download-btn {
  bottom: 15px;
  right: 15px;
  height: 36px;
  width: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  background: #fff;
  border-radius: 50%;
  position: absolute;
  opacity: 0;
  pointer-events: none;
  transition: 0.2s ease;
}

.image-gallery .img-card .download-btn img {
  width: 14px;
  height: 14px;
}

.image-gallery .img-card:not(.loading):hover .download-btn {
  opacity: 1;
  pointer-events: auto;
}

@media screen and (max-width: 760px) {
  .image-generator {
    height: 45vh;
    padding-top: 30px;
    align-items: flex-start;
  }

  .image-generator h1 {
    font-size: 1.8rem;
  }

  .image-generator p {
    font-size: 1rem;
  }

  .image-generator .generate-form {
    margin-top: 30px;
    height: 52px;
    display: block;
  }

  .generate-form .controls {
    height: 40px;
    margin-top: 15px;
    justify-content: end;
    align-items: center;
  }

  .generate-form .generate-btn[disabled] {
    opacity: 1;
  }

  .generate-form .img-quantity {
    color: #fff;
  }

  .generate-form .img-quantity option {
    color: #000;
  }

  .image-gallery {
    margin-top: 20px;
  }

  .image-gallery .img-card:not(.loading) .download-btn {
    opacity: 1;
    pointer-events: auto;
  }
}

@media screen and (max-width: 500px) {
  .image-gallery .img-card {
    width: 100%;
  }
}

Finally, add the following JavaScript code to your script.js file to make your AI image generator website functional. This code handles various functions, even listeners, input handling, API calls, image rendering, etc. to generate AI images based on user prompts.

const generateForm = document.querySelector(".generate-form");
const generateBtn = generateForm.querySelector(".generate-btn");
const imageGallery = document.querySelector(".image-gallery");

const OPENAI_API_KEY = "YOUR-OPENAI-API-KEY-HERE"; // Your OpenAI API key here
let isImageGenerating = false;

const updateImageCard = (imgDataArray) => {
  imgDataArray.forEach((imgObject, index) => {
    const imgCard = imageGallery.querySelectorAll(".img-card")[index];
    const imgElement = imgCard.querySelector("img");
    const downloadBtn = imgCard.querySelector(".download-btn");
    
    // Set the image source to the AI-generated image data
    const aiGeneratedImage = `data:image/jpeg;base64,${imgObject.b64_json}`;
    imgElement.src = aiGeneratedImage;
    
    // When the image is loaded, remove the loading class and set download attributes
    imgElement.onload = () => {
      imgCard.classList.remove("loading");
      downloadBtn.setAttribute("href", aiGeneratedImage);
      downloadBtn.setAttribute("download", `${new Date().getTime()}.jpg`);
    }
  });
}

const generateAiImages = async (userPrompt, userImgQuantity) => {
  try {
    // Send a request to the OpenAI API to generate images based on user inputs
    const response = await fetch("https://api.openai.com/v1/images/generations", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${OPENAI_API_KEY}`,
      },
      body: JSON.stringify({
        prompt: userPrompt,
        n: userImgQuantity,
        size: "512x512",
        response_format: "b64_json"
      }),
    });

    // Throw an error message if the API response is unsuccessful
    if(!response.ok) throw new Error("Failed to generate AI images. Make sure your API key is valid.");

    const { data } = await response.json(); // Get data from the response
    updateImageCard([...data]);
  } catch (error) {
    alert(error.message);
  } finally {
    generateBtn.removeAttribute("disabled");
    generateBtn.innerText = "Generate";
    isImageGenerating = false;
  }
}

const handleImageGeneration = (e) => {
  e.preventDefault();
  if(isImageGenerating) return;

  // Get user input and image quantity values
  const userPrompt = e.srcElement[0].value;
  const userImgQuantity = parseInt(e.srcElement[1].value);
  
  // Disable the generate button, update its text, and set the flag
  generateBtn.setAttribute("disabled", true);
  generateBtn.innerText = "Generating";
  isImageGenerating = true;
  
  // Creating HTML markup for image cards with loading state
  const imgCardMarkup = Array.from({ length: userImgQuantity }, () => 
      `<div class="img-card loading">
        <img src="images/loader.svg" alt="AI generated image">
        <a class="download-btn" href="#">
          <img src="images/download.svg" alt="download icon">
        </a>
      </div>`
  ).join("");

  imageGallery.innerHTML = imgCardMarkup;
  generateAiImages(userPrompt, userImgQuantity);
}

generateForm.addEventListener("submit", handleImageGeneration);

Please note that your website is still unable to generate AI images because you have not provided your API key in the OPENAI_API_KEY variable. We’re using OpenAI API to generate images. So to get a free API key from OpenAI, sign up for an account at https://platform.openai.com/account/api-keys.

” Remember that when you sign up for OpenAI, you’ll get a free $5 credit for your API usage. If your account is older than 3 months or the credit runs out, you’ll need a paid account or create a new one with a new number to keep using the API. Your API usage and expiration date can be found on the account’s usage page.”

To understand the JavaScript code better, I recommend watching the above video tutorial, reading the code comments, and experimenting with the code.

Conclusion and Final words

In conclusion, building your own AI-powered image generation website is not just an exciting project but also a valuable opportunity to apply your web development skills to projects that are increasingly in demand in today’s digital world.

By following the steps outlined in this article, I believe that you have successfully created your own unique version of an AI image generator. Feel free to experiment with different styles and features to take your website to the next level. To further improve your skills, I recommend you try creating a ChatGPT clone, chatbot, or image search engine.

If you encounter any problems while building your AI-powered image generation website, you can download the source code files for this project for free by clicking the Download button. Remember that after downloading the file, you’ll have to provide your valid OpenAI API key into the OPENAI_API_KEY variable in the script.js file.

 

]]>
https://www.codingnepalweb.com/ai-image-generator-website-html-javascript/feed/ 0
Create A Responsive Image Slider in HTML CSS and JavaScript https://www.codingnepalweb.com/responsive-image-slider-html-css-javascript/ https://www.codingnepalweb.com/responsive-image-slider-html-css-javascript/#respond Mon, 11 Sep 2023 16:47:06 +0000 https://www.codingnepalweb.com/?p=5743 Create Responsive Image Slider in HTML CSS and JavaScript Image Slider in JavaScript

Image sliders have become an important component of websites, used to showcase multiple images in an engaging way. As a beginner web developer, creating an image slider can be a useful project to understand and improve your fundamental web development concepts, such as responsive designs, DOM manipulation, and JavaScript event listeners.

In this blog post, I will show you how to create a responsive image slider using HTML, CSS, and JavaScript. We will use vanilla JavaScript to create this slider without relying on external JavaScript libraries such as SwiperJs or Owl Carousel. This way, beginners can learn how these image sliders work and the code required to build them.

In this image slider, there are two buttons for sliding images: one for going back and one for moving forward. There is also a horizontal scrollbar that acts as a slider indicator and can be used to slide images by dragging it. This slider supports all major browsers like Chrome, Firefox, and Edge, as well as mobile or tablet devices.

Video Tutorial of Image Slider in HTML and JavaScript

If you enjoy learning through video tutorials, the above YouTube video can be an excellent resource. In the video, I’ve explained each line of code and included informative comments to make the process of creating your own image slider simple and easy to follow.

However, if you like reading blog posts or want a step-by-step guide for this project, you can continue reading this post. By the end of this post, you will have your own image slider that is easy to customize and implement into your other projects.

Steps to Create Image Slider in HTML & JavaScript

To create a responsive image slider using HTML, CSS, and vanilla JavaScript, follow these simple step-by-step instructions:

  • First, create a folder with any name you like. Then, make the necessary files inside it.
  • Create a file called index.html to serve as the main file.
  • Create a file called style.css for the CSS code.
  • Create a file called script.js for the JavaScript code.
  • Finally, download the Images folder and put it in your project directory. This folder contains all the images you’ll need for this image slider. You can also use your own images.

To start, add the following HTML codes to your index.html file. These codes include all essential HTML semantic tags, such as div, button, img, etc., for the image slider.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Image Slider in HTML CSS and JavaScript | CodingNepal</title>
    <!-- Google Fonts Link For Icons -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@48,400,0,0" />
    <link rel="stylesheet" href="style.css" />
    <script src="script.js" defer></script>
  </head>
  <body>
    <div class="container">
      <div class="slider-wrapper">
        <button id="prev-slide" class="slide-button material-symbols-rounded">
          chevron_left
        </button>
        <ul class="image-list">
          <img class="image-item" src="images/img-1.jpg" alt="img-1" />
          <img class="image-item" src="images/img-2.jpg" alt="img-2" />
          <img class="image-item" src="images/img-3.jpg" alt="img-3" />
          <img class="image-item" src="images/img-4.jpg" alt="img-4" />
          <img class="image-item" src="images/img-5.jpg" alt="img-5" />
          <img class="image-item" src="images/img-6.jpg" alt="img-6" />
          <img class="image-item" src="images/img-7.jpg" alt="img-7" />
          <img class="image-item" src="images/img-8.jpg" alt="img-8" />
          <img class="image-item" src="images/img-9.jpg" alt="img-9" />
          <img class="image-item" src="images/img-10.jpg" alt="img-10" />
        </ul>
        <button id="next-slide" class="slide-button material-symbols-rounded">
          chevron_right
        </button>
      </div>
      <div class="slider-scrollbar">
        <div class="scrollbar-track">
          <div class="scrollbar-thumb"></div>
        </div>
      </div>
    </div>
  </body>
</html>

Next, add the following CSS codes to your style.css file to make your image slider beautiful. You can experiment with different CSS properties like colors, fonts, and backgrounds to give a personalized touch to your slider. If you load the web page in your browser, you can see your image slider with a scrollbar and an arrow button.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: #f1f4fd;
}

.container {
  max-width: 1200px;
  width: 95%;
}

.slider-wrapper {
  position: relative;
}

.slider-wrapper .slide-button {
  position: absolute;
  top: 50%;
  outline: none;
  border: none;
  height: 50px;
  width: 50px;
  z-index: 5;
  color: #fff;
  display: flex;
  cursor: pointer;
  font-size: 2.2rem;
  background: #000;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transform: translateY(-50%);
}

.slider-wrapper .slide-button:hover {
  background: #404040;
}

.slider-wrapper .slide-button#prev-slide {
  left: -25px;
  display: none;
}

.slider-wrapper .slide-button#next-slide {
  right: -25px;
}

.slider-wrapper .image-list {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 18px;
  font-size: 0;
  list-style: none;
  margin-bottom: 30px;
  overflow-x: auto;
  scrollbar-width: none;
}

.slider-wrapper .image-list::-webkit-scrollbar {
  display: none;
}

.slider-wrapper .image-list .image-item {
  width: 325px;
  height: 400px;
  object-fit: cover;
}

.container .slider-scrollbar {
  height: 24px;
  width: 100%;
  display: flex;
  align-items: center;
}

.slider-scrollbar .scrollbar-track {
  background: #ccc;
  width: 100%;
  height: 2px;
  display: flex;
  align-items: center;
  border-radius: 4px;
  position: relative;
}

.slider-scrollbar:hover .scrollbar-track {
  height: 4px;
}

.slider-scrollbar .scrollbar-thumb {
  position: absolute;
  background: #000;
  top: 0;
  bottom: 0;
  width: 50%;
  height: 100%;
  cursor: grab;
  border-radius: inherit;
}

.slider-scrollbar .scrollbar-thumb:active {
  cursor: grabbing;
  height: 8px;
  top: -2px;
}

.slider-scrollbar .scrollbar-thumb::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -10px;
  bottom: -10px;
}

/* Styles for mobile and tablets */
@media only screen and (max-width: 1023px) {
  .slider-wrapper .slide-button {
    display: none !important;
  }

  .slider-wrapper .image-list {
    gap: 10px;
    margin-bottom: 15px;
    scroll-snap-type: x mandatory;
  }

  .slider-wrapper .image-list .image-item {
    width: 280px;
    height: 380px;
  }

  .slider-scrollbar .scrollbar-thumb {
    width: 20%;
  }
}

Finally, add the following JavaScript code to your script.js file to make your image slider functional. This code includes event listeners like mouseup, mousemove, mousedown, click, and mathematical calculations to make the slider work as expected.

const initSlider = () => {
    const imageList = document.querySelector(".slider-wrapper .image-list");
    const slideButtons = document.querySelectorAll(".slider-wrapper .slide-button");
    const sliderScrollbar = document.querySelector(".container .slider-scrollbar");
    const scrollbarThumb = sliderScrollbar.querySelector(".scrollbar-thumb");
    const maxScrollLeft = imageList.scrollWidth - imageList.clientWidth;
    
    // Handle scrollbar thumb drag
    scrollbarThumb.addEventListener("mousedown", (e) => {
        const startX = e.clientX;
        const thumbPosition = scrollbarThumb.offsetLeft;
        const maxThumbPosition = sliderScrollbar.getBoundingClientRect().width - scrollbarThumb.offsetWidth;
        
        // Update thumb position on mouse move
        const handleMouseMove = (e) => {
            const deltaX = e.clientX - startX;
            const newThumbPosition = thumbPosition + deltaX;

            // Ensure the scrollbar thumb stays within bounds
            const boundedPosition = Math.max(0, Math.min(maxThumbPosition, newThumbPosition));
            const scrollPosition = (boundedPosition / maxThumbPosition) * maxScrollLeft;
            
            scrollbarThumb.style.left = `${boundedPosition}px`;
            imageList.scrollLeft = scrollPosition;
        }

        // Remove event listeners on mouse up
        const handleMouseUp = () => {
            document.removeEventListener("mousemove", handleMouseMove);
            document.removeEventListener("mouseup", handleMouseUp);
        }

        // Add event listeners for drag interaction
        document.addEventListener("mousemove", handleMouseMove);
        document.addEventListener("mouseup", handleMouseUp);
    });

    // Slide images according to the slide button clicks
    slideButtons.forEach(button => {
        button.addEventListener("click", () => {
            const direction = button.id === "prev-slide" ? -1 : 1;
            const scrollAmount = imageList.clientWidth * direction;
            imageList.scrollBy({ left: scrollAmount, behavior: "smooth" });
        });
    });

     // Show or hide slide buttons based on scroll position
    const handleSlideButtons = () => {
        slideButtons[0].style.display = imageList.scrollLeft <= 0 ? "none" : "flex";
        slideButtons[1].style.display = imageList.scrollLeft >= maxScrollLeft ? "none" : "flex";
    }

    // Update scrollbar thumb position based on image scroll
    const updateScrollThumbPosition = () => {
        const scrollPosition = imageList.scrollLeft;
        const thumbPosition = (scrollPosition / maxScrollLeft) * (sliderScrollbar.clientWidth - scrollbarThumb.offsetWidth);
        scrollbarThumb.style.left = `${thumbPosition}px`;
    }

    // Call these two functions when image list scrolls
    imageList.addEventListener("scroll", () => {
        updateScrollThumbPosition();
        handleSlideButtons();
    });
}

window.addEventListener("resize", initSlider);
window.addEventListener("load", initSlider);

To understand the JavaScript code better, I recommend watching the above video tutorial, reading the code comments, and experimenting with the code.

Conclusion and Final words

In conclusion, creating a responsive image slider from scratch using HTML, CSS, and vanilla JavaScript is not only a valuable learning experience but also a practical addition to your web development skills. By following the steps in this post, you have successfully built a functional image slider, and you can now easily customize it according to your choice.

Feel free to experiment with different styles, transitions, and features to take your image slider to the next level. To further improve your web development, I recommend you try recreating other interactive images or card sliders available on this website.

If you encounter any problems while creating your image slider, you can download the source code files for this project for free by clicking the Download button. Additionally, you can view a live demo of it by clicking the View Live button.

]]>
https://www.codingnepalweb.com/responsive-image-slider-html-css-javascript/feed/ 0
Create Text Typing Effect in HTML CSS and Vanilla JavaScript https://www.codingnepalweb.com/text-typing-effect-html-css-javascript/ https://www.codingnepalweb.com/text-typing-effect-html-css-javascript/#respond Thu, 03 Aug 2023 07:10:59 +0000 https://www.codingnepalweb.com/?p=5709 Create Text Typing Effect in HTML CSS and Vanilla JavaScript

Have you ever come across that cool text typing effect on different websites where the words appear as if they’re being typed out? If you’re a beginner web developer, you might wonder how to create such an eye-catching animation on your own. Well, it’s a simple yet impressive effect that can be achieved using just HTML, CSS, and JavaScript.

In this blog post, I’ll guide you through the steps of creating this text-typing animation using HTML, CSS, and Vanilla JavaScript. This means we don’t rely on any external JavaScript libraries like typed.js. So you’ll gain a deep understanding of how this type of typing animation is created and how you can apply your skills to real-world web projects.

In this typing animation, each letter of the word appears after the other, creating a typewriter effect. There is also a blinking caret animation at the end of the word to make the effect more attractive. To know more about what our typing text animation looks like, you can watch the given YouTube video.

Video Tutorial of Text Typing Effect HTML & JavaScript

If you enjoy learning through video tutorials, the above YouTube video is an excellent resource. In the video, I’ve explained each line of code and provided informative comments to make the process of creating your own text-typing animation beginner-friendly and easy to follow.

However, if you like reading blog posts or want a step-by-step guide for creating this effect, you can continue reading this post. By the end of this post, you’ll have your own customizable text typing effect that you can easily use on your other projects.

Steps to Create Text Typing Animation in HTML & JavaScript

To create a custom text typing effect using HTML, CSS, and vanilla JavaScript, follow these simple step-by-step instructions:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create a style.css file. The file name must be style and its extension .css
  4. Create a script.js file. The file name must be script and its extension .js

To start, add the following HTML codes to your index.html file. This code includes essential HTML markup with <h1> and <span> tags, which we’ll use for the typing effect. Currently, the <span> element is empty, but using JavaScript, we’ll dynamically add the custom typing word.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Typing Text Effect | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js" defer></script>
</head>
<body>
    <h1>Coding is <span></span></h1>
</body>
</html>

Next, add the following CSS codes to your style.css file to apply visual styling to your text like color, font, border, background, etc. Now, if you load the web page in your browser, you will see styled static text with blinking caret animation.

/* Importing Google font - Inter */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Inter", sans-serif;
}

body {
    display: flex;
    height: 100vh;
    align-items: center;
    justify-content: center;
    background: #1D1E23;
}

h1 {
    color: #fff;
    font-size: 2rem;
    font-weight: 600;
}

h1 span {
    color: #BD53ED;
    position: relative;
}

h1 span::before {
    content: "";
    height: 30px;
    width: 2px;
    position: absolute;
    top: 50%;
    right: -8px;
    background: #BD53ED;
    transform: translateY(-45%);
    animation: blink 0.7s infinite;
}

h1 span.stop-blinking::before {
    animation: none;
}

@keyframes blink {
    50% { opacity: 0 }
}

Finally, add the following JavaScript code to your script.js file. These scripts include different JavaScript functions, variables, methods, and others that are responsible for creating the text-typing effect.

const dynamicText = document.querySelector("h1 span");
const words = ["Love", "like Art", "the Future", "Everything"];

// Variables to track the position and deletion status of the word
let wordIndex = 0;
let charIndex = 0;
let isDeleting = false;

const typeEffect = () => {
    const currentWord = words[wordIndex];
    const currentChar = currentWord.substring(0, charIndex);
    dynamicText.textContent = currentChar;
    dynamicText.classList.add("stop-blinking");

    if (!isDeleting && charIndex < currentWord.length) {
        // If condition is true, type the next character
        charIndex++;
        setTimeout(typeEffect, 200);
    } else if (isDeleting && charIndex > 0) {
        // If condition is true, remove the previous character
        charIndex--;
        setTimeout(typeEffect, 100);
    } else {
        // If word is deleted then switch to the next word
        isDeleting = !isDeleting;
        dynamicText.classList.remove("stop-blinking");
        wordIndex = !isDeleting ? (wordIndex + 1) % words.length : wordIndex;
        setTimeout(typeEffect, 1200);
    }
}

typeEffect();

In the above code, you can see there is a “words” array that contains a list of phrases used for the typing animation, some global variables used to track typing status, and a function with an if/else condition to initiate the typing and erasing effects. To understand JavaScript code better, I recommend watching the above video tutorial, paying close attention to the code comments, and experimenting with the code.

Conclusion and Final words

In conclusion, creating a text typing animation is a valuable and useful web project. I believe that by following the steps outlined in this blog post, you’ve successfully created your own text-typing effect using HTML, CSS, and JavaScript.

To further improve your web development skills, I recommend you try recreating the same text-typing animation using only HTML and CSS. By creating this effect, you’ll gain a better understanding of how CSS properties and animations are used to create cool text typing effects.

If you encounter any problems while creating your text-typing effect, you can download the source code files for this project for free by clicking the Download button. You can also view a live demo of it by clicking the View Live button.

 

]]>
https://www.codingnepalweb.com/text-typing-effect-html-css-javascript/feed/ 0
Build A Hangman Game in HTML CSS and JavaScript https://www.codingnepalweb.com/build-hangman-game-html-javascript/ https://www.codingnepalweb.com/build-hangman-game-html-javascript/#respond Fri, 21 Jul 2023 18:16:51 +0000 https://www.codingnepalweb.com/?p=5678 Build A Hangman Game in HTML CSS and JavaScript

Hangman is the classic word-guessing game you’ve likely enjoyed playing. But as a beginner web developer, have you ever thought about building your own Hangman game? Building a hangman game is not only fun and engaging but also provides an excellent opportunity to enhance your web development and problem-solving skills.

If you’re unfamiliar, Hangman is a word-guessing game where players try to guess all the letters of a randomly generated word within a given number of tries. There is also a hangman illustration that will progressively appear on the gallows for each incorrect guess.

In this beginner-friendly blog post, I’ll show you how to build a Hangman game in HTML, CSS, and JavaScript. By creating this game, you’ll gain practical experience and dive into essential concepts of web development, such as DOM manipulation, event handling, conditional statements, array usage, and many more.

Video Tutorial of Hangman Game HTML & JavaScript

If you enjoy learning through video tutorials, the above YouTube video is an excellent resource. In the video, I’ve explained each line of code and provided informative comments to make the process of building your own Hangman game beginner-friendly and easy to follow.

However, if you like reading blog posts or want a step-by-step guide for building this game, you can continue reading this post. By the end of this post, you’ll have your own Hangman game that you can play or show off to your friends.

Steps to Build Hangman Game in HTML & JavaScript

To build a Hangman game using HTML, CSS, and JavaScript, follow these step-by-step instructions:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create a style.css file. The file name must be style and its extension .css
  4. Create a scripts folder with word-list.js and script.js files. The extension of the files must be .js and files should be inside the scripts folder.
  5. Download and place the Images folder in your project directory. This folder includes the necessary images and gifs for the game.

To start, add the following HTML codes to your index.html file. These codes include essential HTML elements, such as a modal box and a container for the game. Using JavaScript later, we’ll add or modify these elements and randomize game letters, hints, and keyboard keys.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hangman Game JavaScript | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <script src="scripts/word-list.js" defer></script>
    <script src="scripts/script.js" defer></script>
</head>
<body>
    <div class="game-modal">
        <div class="content">
            <img src="#" alt="gif">
            <h4>Game Over!</h4>
            <p>The correct word was: <b>rainbow</b></p>
            <button class="play-again">Play Again</button>
        </div>
    </div>
    <div class="container">
        <div class="hangman-box">
            <img src="#" draggable="false" alt="hangman-img">
            <h1>Hangman Game</h1>
        </div>
        <div class="game-box">
            <ul class="word-display"></ul>
            <h4 class="hint-text">Hint: <b></b></h4>
            <h4 class="guesses-text">Incorrect guesses: <b></b></h4>
            <div class="keyboard"></div>
        </div>
    </div>
</body>
</html>

Next, add the following CSS codes to your style.css file to apply visual styling to your game: color, font, border, background, etc. Now, if you load the web page in your browser, you will see the Hangman game with its various styled elements. You can play around with colors, fonts, borders, backgrounds, and more to give your Hangman game a unique and appealing look.

/* Importing Google font - Open Sans */
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap");
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Open Sans", sans-serif;
}
body {
    display: flex;
    padding: 0 10px;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: #5E63BA;
}
.container {
    display: flex;
    width: 850px;
    gap: 70px;
    padding: 60px 40px;
    background: #fff;
    border-radius: 10px;
    align-items: flex-end;
    justify-content: space-between;
    box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
.hangman-box img {
    user-select: none;
    max-width: 270px;
}
.hangman-box h1 {
    font-size: 1.45rem;
    text-align: center;
    margin-top: 20px;
    text-transform: uppercase;
}
.game-box .word-display {
    gap: 10px;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
}
.word-display .letter {
    width: 28px;
    font-size: 2rem;
    text-align: center;
    font-weight: 600;
    margin-bottom: 40px;
    text-transform: uppercase;
    border-bottom: 3px solid #000;
}
.word-display .letter.guessed {
    margin: -40px 0 35px;
    border-color: transparent;
}
.game-box h4 {
    text-align: center;
    font-size: 1.1rem;
    font-weight: 500;
    margin-bottom: 15px;
}
.game-box h4 b {
    font-weight: 600;
}
.game-box .guesses-text b {
    color: #ff0000;
}
.game-box .keyboard {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
    margin-top: 40px;
    justify-content: center;
}
:where(.game-modal, .keyboard) button {
    color: #fff;
    border: none;
    outline: none;
    cursor: pointer;
    font-size: 1rem;
    font-weight: 600;
    border-radius: 4px;
    text-transform: uppercase;
    background: #5E63BA;
}
.keyboard button {
    padding: 7px;
    width: calc(100% / 9 - 5px);
}
.keyboard button[disabled] {
    pointer-events: none;
    opacity: 0.6;
}
:where(.game-modal, .keyboard) button:hover {
    background: #8286c9;
}
.game-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    pointer-events: none;
    background: rgba(0,0,0,0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    padding: 0 10px;
    transition: opacity 0.4s ease;
}
.game-modal.show {
    opacity: 1;
    pointer-events: auto;
    transition: opacity 0.4s 0.4s ease;
}
.game-modal .content {
    padding: 30px;
    max-width: 420px;
    width: 100%;
    border-radius: 10px;
    background: #fff;
    text-align: center;
    box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
.game-modal img {
    max-width: 130px;
    margin-bottom: 20px;
}
.game-modal img[src="images/victory.gif"] {
    margin-left: -10px;
}
.game-modal h4 {
    font-size: 1.53rem;
}
.game-modal p {
    font-size: 1.15rem;
    margin: 15px 0 30px;
    font-weight: 500;
}
.game-modal p b {
    color: #5E63BA;
    font-weight: 600;
}
.game-modal button {
    padding: 12px 23px;
}

@media (max-width: 782px) {
    .container {
        flex-direction: column;
        padding: 30px 15px;
        align-items: center;
    }
    .hangman-box img {
        max-width: 200px;
    }
    .hangman-box h1 {
        display: none;
    }
    .game-box h4 {
        font-size: 1rem;
    }
    .word-display .letter {
        margin-bottom: 35px;
        font-size: 1.7rem;
    }
    .word-display .letter.guessed {
        margin: -35px 0 25px;
    }
    .game-modal img {
        max-width: 120px;
    }
    .game-modal h4 {
        font-size: 1.45rem;
    }
    .game-modal p {
        font-size: 1.1rem;
    }
    .game-modal button {
        padding: 10px 18px;
    }
}

Next, add the following JavaScript code to your word-list.js file: This script includes a list of various words along with corresponding hints. Feel free to expand this list to make your Hangman game even more enjoyable and challenging for players.

const wordList = [
    {
        word: "guitar",
        hint: "A musical instrument with strings."
    },
    {
        word: "oxygen",
        hint: "A colorless, odorless gas essential for life."
    },
    {
        word: "mountain",
        hint: "A large natural elevation of the Earth's surface."
    },
    {
        word: "painting",
        hint: "An art form using colors on a surface to create images or expression."
    },
    {
        word: "astronomy",
        hint: "The scientific study of celestial objects and phenomena."
    },
    {
        word: "football",
        hint: "A popular sport played with a spherical ball."
    },
    {
        word: "chocolate",
        hint: "A sweet treat made from cocoa beans."
    },
    {
        word: "butterfly",
        hint: "An insect with colorful wings and a slender body."
    },
    {
        word: "history",
        hint: "The study of past events and human civilization."
    },
    {
        word: "pizza",
        hint: "A savory dish consisting of a round, flattened base with toppings."
    },
    {
        word: "jazz",
        hint: "A genre of music characterized by improvisation and syncopation."
    },
    {
        word: "camera",
        hint: "A device used to capture and record images or videos."
    },
    {
        word: "diamond",
        hint: "A precious gemstone known for its brilliance and hardness."
    },
    {
        word: "adventure",
        hint: "An exciting or daring experience."
    },
    {
        word: "science",
        hint: "The systematic study of the structure and behavior of the physical and natural world."
    },
    {
        word: "bicycle",
        hint: "A human-powered vehicle with two wheels."
    },
    {
        word: "sunset",
        hint: "The daily disappearance of the sun below the horizon."
    },
    {
        word: "coffee",
        hint: "A popular caffeinated beverage made from roasted coffee beans."
    },
    {
        word: "dance",
        hint: "A rhythmic movement of the body often performed to music."
    },
    {
        word: "galaxy",
        hint: "A vast system of stars, gas, and dust held together by gravity."
    },
    {
        word: "orchestra",
        hint: "A large ensemble of musicians playing various instruments."
    },
    {
        word: "volcano",
        hint: "A mountain or hill with a vent through which lava, rock fragments, hot vapor, and gas are ejected."
    },
    {
        word: "novel",
        hint: "A long work of fiction, typically with a complex plot and characters."
    },
    {
        word: "sculpture",
        hint: "A three-dimensional art form created by shaping or combining materials."
    },
    {
        word: "symphony",
        hint: "A long musical composition for a full orchestra, typically in multiple movements."
    },
    {
        word: "architecture",
        hint: "The art and science of designing and constructing buildings."
    },
    {
        word: "ballet",
        hint: "A classical dance form characterized by precise and graceful movements."
    },
    {
        word: "astronaut",
        hint: "A person trained to travel and work in space."
    },
    {
        word: "waterfall",
        hint: "A cascade of water falling from a height."
    },
    {
        word: "technology",
        hint: "The application of scientific knowledge for practical purposes."
    },
    {
        word: "rainbow",
        hint: "A meteorological phenomenon that is caused by reflection, refraction, and dispersion of light."
    },
    {
        word: "universe",
        hint: "All existing matter, space, and time as a whole."
    },
    {
        word: "piano",
        hint: "A musical instrument played by pressing keys that cause hammers to strike strings."
    },
    {
        word: "vacation",
        hint: "A period of time devoted to pleasure, rest, or relaxation."
    },
    {
        word: "rainforest",
        hint: "A dense forest characterized by high rainfall and biodiversity."
    },
    {
        word: "theater",
        hint: "A building or outdoor area in which plays, movies, or other performances are staged."
    },
    {
        word: "telephone",
        hint: "A device used to transmit sound over long distances."
    },
    {
        word: "language",
        hint: "A system of communication consisting of words, gestures, and syntax."
    },
    {
        word: "desert",
        hint: "A barren or arid land with little or no precipitation."
    },
    {
        word: "sunflower",
        hint: "A tall plant with a large yellow flower head."
    },
    {
        word: "fantasy",
        hint: "A genre of imaginative fiction involving magic and supernatural elements."
    },
    {
        word: "telescope",
        hint: "An optical instrument used to view distant objects in space."
    },
    {
        word: "breeze",
        hint: "A gentle wind."
    },
    {
        word: "oasis",
        hint: "A fertile spot in a desert where water is found."
    },
    {
        word: "photography",
        hint: "The art, process, or practice of creating images by recording light or other electromagnetic radiation."
    },
    {
        word: "safari",
        hint: "An expedition or journey, typically to observe wildlife in their natural habitat."
    },
    {
        word: "planet",
        hint: "A celestial body that orbits a star and does not produce light of its own."
    },
    {
        word: "river",
        hint: "A large natural stream of water flowing in a channel to the sea, a lake, or another such stream."
    },
    {
        word: "tropical",
        hint: "Relating to or situated in the region between the Tropic of Cancer and the Tropic of Capricorn."
    },
    {
        word: "mysterious",
        hint: "Difficult or impossible to understand, explain, or identify."
    },
    {
        word: "enigma",
        hint: "Something that is mysterious, puzzling, or difficult to understand."
    },
    {
        word: "paradox",
        hint: "A statement or situation that contradicts itself or defies intuition."
    },
    {
        word: "puzzle",
        hint: "A game, toy, or problem designed to test ingenuity or knowledge."
    },
    {
        word: "whisper",
        hint: "To speak very softly or quietly, often in a secretive manner."
    },
    {
        word: "shadow",
        hint: "A dark area or shape produced by an object blocking the light."
    },
    {
        word: "secret",
        hint: "Something kept hidden or unknown to others."
    },
    {
        word: "curiosity",
        hint: "A strong desire to know or learn something."
    },
    {
        word: "unpredictable",
        hint: "Not able to be foreseen or known beforehand; uncertain."
    },
    {
        word: "obfuscate",
        hint: "To confuse or bewilder someone; to make something unclear or difficult to understand."
    },
    {
        word: "unveil",
        hint: "To make known or reveal something previously secret or unknown."
    },
    {
        word: "illusion",
        hint: "A false perception or belief; a deceptive appearance or impression."
    },
    {
        word: "moonlight",
        hint: "The light from the moon."
    },
    {
        word: "vibrant",
        hint: "Full of energy, brightness, and life."
    },
    {
        word: "nostalgia",
        hint: "A sentimental longing or wistful affection for the past."
    },
    {
        word: "brilliant",
        hint: "Exceptionally clever, talented, or impressive."
    },
];

Finally, add the following JavaScript code to your script.js file. This script code will be responsible for the game’s logic, including generating a random word, managing user input, keeping track of guessed letters, checking for correct guesses, and updating the hangman’s visual representation as the game progresses.

const wordDisplay = document.querySelector(".word-display");
const guessesText = document.querySelector(".guesses-text b");
const keyboardDiv = document.querySelector(".keyboard");
const hangmanImage = document.querySelector(".hangman-box img");
const gameModal = document.querySelector(".game-modal");
const playAgainBtn = gameModal.querySelector("button");

// Initializing game variables
let currentWord, correctLetters, wrongGuessCount;
const maxGuesses = 6;

const resetGame = () => {
    // Ressetting game variables and UI elements
    correctLetters = [];
    wrongGuessCount = 0;
    hangmanImage.src = "images/hangman-0.svg";
    guessesText.innerText = `${wrongGuessCount} / ${maxGuesses}`;
    wordDisplay.innerHTML = currentWord.split("").map(() => `<li class="letter"></li>`).join("");
    keyboardDiv.querySelectorAll("button").forEach(btn => btn.disabled = false);
    gameModal.classList.remove("show");
}

const getRandomWord = () => {
    // Selecting a random word and hint from the wordList
    const { word, hint } = wordList[Math.floor(Math.random() * wordList.length)];
    currentWord = word; // Making currentWord as random word
    document.querySelector(".hint-text b").innerText = hint;
    resetGame();
}

const gameOver = (isVictory) => {
    // After game complete.. showing modal with relevant details
    const modalText = isVictory ? `You found the word:` : 'The correct word was:';
    gameModal.querySelector("img").src = `images/${isVictory ? 'victory' : 'lost'}.gif`;
    gameModal.querySelector("h4").innerText = isVictory ? 'Congrats!' : 'Game Over!';
    gameModal.querySelector("p").innerHTML = `${modalText} <b>${currentWord}</b>`;
    gameModal.classList.add("show");
}

const initGame = (button, clickedLetter) => {
    // Checking if clickedLetter is exist on the currentWord
    if(currentWord.includes(clickedLetter)) {
        // Showing all correct letters on the word display
        [...currentWord].forEach((letter, index) => {
            if(letter === clickedLetter) {
                correctLetters.push(letter);
                wordDisplay.querySelectorAll("li")[index].innerText = letter;
                wordDisplay.querySelectorAll("li")[index].classList.add("guessed");
            }
        });
    } else {
        // If clicked letter doesn't exist then update the wrongGuessCount and hangman image
        wrongGuessCount++;
        hangmanImage.src = `images/hangman-${wrongGuessCount}.svg`;
    }
    button.disabled = true; // Disabling the clicked button so user can't click again
    guessesText.innerText = `${wrongGuessCount} / ${maxGuesses}`;

    // Calling gameOver function if any of these condition meets
    if(wrongGuessCount === maxGuesses) return gameOver(false);
    if(correctLetters.length === currentWord.length) return gameOver(true);
}

// Creating keyboard buttons and adding event listeners
for (let i = 97; i <= 122; i++) {
    const button = document.createElement("button");
    button.innerText = String.fromCharCode(i);
    keyboardDiv.appendChild(button);
    button.addEventListener("click", (e) => initGame(e.target, String.fromCharCode(i)));
}

getRandomWord();
playAgainBtn.addEventListener("click", getRandomWord);

That’s all! To understand JavaScript code better, I recommend watching the above video tutorial, paying close attention to the code comments, and experimenting with the code.

Conclusion and Final Words

In conclusion, building a Hangman game from scratch using HTML, CSS, and JavaScript is an enjoyable and rewarding experience that can strengthen your web development and problem-solving skills. I believe that by following the steps in this post, you’ve successfully built your very own Hangman game.

Remember to experiment and customize your game to add personal touches and make it even more engaging. To continue improving your skills, I recommend exploring my blog post on How to Build Snake Game in HTML, CSS, and JavaScript.

If you encounter any problems while building your Hangman game, you can download the source code files for this game project for free by clicking the Download button. You can also view a live demo of it by clicking the View Live button.

]]>
https://www.codingnepalweb.com/build-hangman-game-html-javascript/feed/ 0
How to Build A Weather App in HTML CSS and JavaScript https://www.codingnepalweb.com/weather-app-project-html-javascript/ https://www.codingnepalweb.com/weather-app-project-html-javascript/#respond Wed, 28 Jun 2023 19:28:38 +0000 https://www.codingnepalweb.com/?p=5614 Build A Weather App in HTML CSS and JavaScript Weather App Project HTML CSS and JavaScript

Are you new to web development and eager to enhance your skills by working on practical projects? Look no further! Building a weather app is an excellent way to begin your journey. With just HTML, CSS, and JavaScript, you can create an application that not only improves your web development abilities but also makes you familiar with JavaScript API calls.

In this blog post, I’ll guide you through building a weather app project using HTML, CSS, and JavaScript from scratch. If you prefer using Bootstrap, I’ve already covered that in a previous blog post on creating a Weather App in HTML, Bootstrap, and JavaScript. However, this weather project has some extra features that make it more useful.

In this weather app project, users can enter any city name to get the 5-day weather forecast or simply click on the “Use Current Location” button to get their current location’s weather details, including temperature, wind speed, humidity, and more. This project is also mobile-friendly, which means it looks great on all devices.

Video Tutorial of Weather App Project in JavaScript

If you prefer learning through video tutorials, this YouTube video is an excellent resource for understanding the process of creating your own weather app project. In the video, I’ve explained each line of code and provided informative comments to make it beginner-friendly and easy to follow.

However, if you like reading blog posts or want to know the steps involved in creating this weather app project, you can continue reading this post. By the end of this post, you will have your own weather app and a basic understanding of the basics of DOM manipulation, event handling, CSS styling, and APIs.

Steps To Create Weather App in HTML & JavaScript

To create your weather app using HTML, CSS, and JavaScript, follow these step-by-step instructions:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create a style.css file. The file name must be style and its extension .css
  4. Create a script.js file. The file name must be script and its extension .js

To start, add the following HTML codes to your index.html file. This code includes a weather app header, input, button, and unordered list (ul) that are used as a placeholder for weather details. Later, using JavaScript, we’ll replace these placeholders with actual weather details.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Weather App Project JavaScript | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="script.js" defer></script>
  </head>
  <body>
    <h1>Weather Dashboard</h1>
    <div class="container">
      <div class="weather-input">
        <h3>Enter a City Name</h3>
        <input class="city-input" type="text" placeholder="E.g., New York, London, Tokyo">
        <button class="search-btn">Search</button>
        <div class="separator"></div>
        <button class="location-btn">Use Current Location</button>
      </div>
      <div class="weather-data">
        <div class="current-weather">
          <div class="details">
            <h2>_______ ( ______ )</h2>
            <h6>Temperature: __°C</h6>
            <h6>Wind: __ M/S</h6>
            <h6>Humidity: __%</h6>
          </div>
        </div>
        <div class="days-forecast">
          <h2>5-Day Forecast</h2>
          <ul class="weather-cards">
            <li class="card">
              <h3>( ______ )</h3>
              <h6>Temp: __C</h6>
              <h6>Wind: __ M/S</h6>
              <h6>Humidity: __%</h6>
            </li>
            <li class="card">
              <h3>( ______ )</h3>
              <h6>Temp: __C</h6>
              <h6>Wind: __ M/S</h6>
              <h6>Humidity: __%</h6>
            </li>
            <li class="card">
              <h3>( ______ )</h3>
              <h6>Temp: __C</h6>
              <h6>Wind: __ M/S</h6>
              <h6>Humidity: __%</h6>
            </li>
            <li class="card">
              <h3>( ______ )</h3>
              <h6>Temp: __C</h6>
              <h6>Wind: __ M/S</h6>
              <h6>Humidity: __%</h6>
            </li>
            <li class="card">
              <h3>( ______ )</h3>
              <h6>Temp: __C</h6>
              <h6>Wind: __ M/S</h6>
              <h6>Humidity: __%</h6>
            </li>
          </ul>
        </div>
      </div>
    </div>
    
  </body>
</html>

Next, add the following CSS codes to your style.css file to apply visual styling to your weather app. Now, if you load the web page in your browser, you will see the header at the top, a sidebar with input and buttons, and weather detail placeholders. You can customize this code to your liking by adjusting the color, font, size, and other CSS properties.

/* Import Google font - Open Sans */
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap');
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Open Sans', sans-serif;
}
body {
  background: #E3F2FD;
}
h1 {
  background: #5372F0;
  font-size: 1.75rem;
  text-align: center;
  padding: 18px 0;
  color: #fff;
}
.container {
  display: flex;
  gap: 35px;
  padding: 30px;
}
.weather-input {
  width: 550px;
}
.weather-input input {
  height: 46px;
  width: 100%;
  outline: none;
  font-size: 1.07rem;
  padding: 0 17px;
  margin: 10px 0 20px 0;
  border-radius: 4px;
  border: 1px solid #ccc;
}
.weather-input input:focus {
  padding: 0 16px;
  border: 2px solid #5372F0;
}
.weather-input .separator {
  height: 1px;
  width: 100%;
  margin: 25px 0;
  background: #BBBBBB;
  display: flex;
  align-items: center;
  justify-content: center;
}
.weather-input .separator::before{
  content: "or";
  color: #6C757D;
  font-size: 1.18rem;
  padding: 0 15px;
  margin-top: -4px;
  background: #E3F2FD;
}
.weather-input button {
  width: 100%;
  padding: 10px 0;
  cursor: pointer;
  outline: none;
  border: none;
  border-radius: 4px;
  font-size: 1rem;
  color: #fff;
  background: #5372F0;
  transition: 0.2s ease;
}
.weather-input .search-btn:hover {
  background: #2c52ed;
}
.weather-input .location-btn {
  background: #6C757D;
}
.weather-input .location-btn:hover {
  background: #5c636a;
}
.weather-data {
  width: 100%;
}
.weather-data .current-weather {
  color: #fff;
  background: #5372F0;
  border-radius: 5px;
  padding: 20px 70px 20px 20px;
  display: flex;
  justify-content: space-between;
}
.current-weather h2 {
  font-weight: 700;
  font-size: 1.7rem;
}
.weather-data h6 {
  margin-top: 12px;
  font-size: 1rem;
  font-weight: 500;
}
.current-weather .icon {
  text-align: center;
}
.current-weather .icon img {
  max-width: 120px;
  margin-top: -15px;
}
.current-weather .icon h6 {
  margin-top: -10px;
  text-transform: capitalize;
}
.days-forecast h2 {
  margin: 20px 0;
  font-size: 1.5rem;
}
.days-forecast .weather-cards {
  display: flex;
  gap: 20px;
}
.weather-cards .card {
  color: #fff;
  padding: 18px 16px;
  list-style: none;
  width: calc(100% / 5);
  background: #6C757D;
  border-radius: 5px;
}
.weather-cards .card h3 {
  font-size: 1.3rem;
  font-weight: 600;
}
.weather-cards .card img {
  max-width: 70px;
  margin: 5px 0 -12px 0;
}

@media (max-width: 1400px) {
  .weather-data .current-weather {
    padding: 20px;
  }
  .weather-cards {
    flex-wrap: wrap;
  }
  .weather-cards .card {
    width: calc(100% / 4 - 15px);
  }
}
@media (max-width: 1200px) {
  .weather-cards .card {
    width: calc(100% / 3 - 15px);
  }
}
@media (max-width: 950px) {
  .weather-input {
    width: 450px;
  }
  .weather-cards .card {
    width: calc(100% / 2 - 10px);
  }
}
@media (max-width: 750px) {
  h1 {
    font-size: 1.45rem;
    padding: 16px 0;
  }
  .container {
    flex-wrap: wrap;
    padding: 15px;
  }
  .weather-input {
    width: 100%;
  }
  .weather-data h2 {
    font-size: 1.35rem;
  }
}

Finally, add the following JavaScript code to your script.js file. This script code will make your weather app functional, which means now you can get a 5-day weather forecast for any city or your current location.

const cityInput = document.querySelector(".city-input");
const searchButton = document.querySelector(".search-btn");
const locationButton = document.querySelector(".location-btn");
const currentWeatherDiv = document.querySelector(".current-weather");
const weatherCardsDiv = document.querySelector(".weather-cards");

const API_KEY = "YOUR-API-KEY-HERE"; // API key for OpenWeatherMap API

const createWeatherCard = (cityName, weatherItem, index) => {
    if(index === 0) { // HTML for the main weather card
        return `<div class="details">
                    <h2>${cityName} (${weatherItem.dt_txt.split(" ")[0]})</h2>
                    <h6>Temperature: ${(weatherItem.main.temp - 273.15).toFixed(2)}°C</h6>
                    <h6>Wind: ${weatherItem.wind.speed} M/S</h6>
                    <h6>Humidity: ${weatherItem.main.humidity}%</h6>
                </div>
                <div class="icon">
                    <img src="https://openweathermap.org/img/wn/${weatherItem.weather[0].icon}@4x.png" alt="weather-icon">
                    <h6>${weatherItem.weather[0].description}</h6>
                </div>`;
    } else { // HTML for the other five day forecast card
        return `<li class="card">
                    <h3>(${weatherItem.dt_txt.split(" ")[0]})</h3>
                    <img src="https://openweathermap.org/img/wn/${weatherItem.weather[0].icon}@4x.png" alt="weather-icon">
                    <h6>Temp: ${(weatherItem.main.temp - 273.15).toFixed(2)}°C</h6>
                    <h6>Wind: ${weatherItem.wind.speed} M/S</h6>
                    <h6>Humidity: ${weatherItem.main.humidity}%</h6>
                </li>`;
    }
}

const getWeatherDetails = (cityName, latitude, longitude) => {
    const WEATHER_API_URL = `https://api.openweathermap.org/data/2.5/forecast?lat=${latitude}&lon=${longitude}&appid=${API_KEY}`;

    fetch(WEATHER_API_URL).then(response => response.json()).then(data => {
        // Filter the forecasts to get only one forecast per day
        const uniqueForecastDays = [];
        const fiveDaysForecast = data.list.filter(forecast => {
            const forecastDate = new Date(forecast.dt_txt).getDate();
            if (!uniqueForecastDays.includes(forecastDate)) {
                return uniqueForecastDays.push(forecastDate);
            }
        });

        // Clearing previous weather data
        cityInput.value = "";
        currentWeatherDiv.innerHTML = "";
        weatherCardsDiv.innerHTML = "";

        // Creating weather cards and adding them to the DOM
        fiveDaysForecast.forEach((weatherItem, index) => {
            const html = createWeatherCard(cityName, weatherItem, index);
            if (index === 0) {
                currentWeatherDiv.insertAdjacentHTML("beforeend", html);
            } else {
                weatherCardsDiv.insertAdjacentHTML("beforeend", html);
            }
        });        
    }).catch(() => {
        alert("An error occurred while fetching the weather forecast!");
    });
}

const getCityCoordinates = () => {
    const cityName = cityInput.value.trim();
    if (cityName === "") return;
    const API_URL = `https://api.openweathermap.org/geo/1.0/direct?q=${cityName}&limit=1&appid=${API_KEY}`;
    
    // Get entered city coordinates (latitude, longitude, and name) from the API response
    fetch(API_URL).then(response => response.json()).then(data => {
        if (!data.length) return alert(`No coordinates found for ${cityName}`);
        const { lat, lon, name } = data[0];
        getWeatherDetails(name, lat, lon);
    }).catch(() => {
        alert("An error occurred while fetching the coordinates!");
    });
}

const getUserCoordinates = () => {
    navigator.geolocation.getCurrentPosition(
        position => {
            const { latitude, longitude } = position.coords; // Get coordinates of user location
            // Get city name from coordinates using reverse geocoding API
            const API_URL = `https://api.openweathermap.org/geo/1.0/reverse?lat=${latitude}&lon=${longitude}&limit=1&appid=${API_KEY}`;
            fetch(API_URL).then(response => response.json()).then(data => {
                const { name } = data[0];
                getWeatherDetails(name, latitude, longitude);
            }).catch(() => {
                alert("An error occurred while fetching the city name!");
            });
        },
        error => { // Show alert if user denied the location permission
            if (error.code === error.PERMISSION_DENIED) {
                alert("Geolocation request denied. Please reset location permission to grant access again.");
            } else {
                alert("Geolocation request error. Please reset location permission.");
            }
        });
}

locationButton.addEventListener("click", getUserCoordinates);
searchButton.addEventListener("click", getCityCoordinates);
cityInput.addEventListener("keyup", e => e.key === "Enter" && getCityCoordinates());

Please note that your weather app is still unable to show the weather forecast for any location because you’ve not provided your OpenWeatherMap API key in the API_KEY variable. To get a free API key, sign up for an account at https://home.openweathermap.org/api_keys. Your API key may take minutes or hours to activate. You’ll get an error like “Invalid API Key” or something similar during this time.

In the code, there are two API calls. The first one fetches the geographic coordinates of the user-entered city. These coordinates are then used in the second API call to retrieve the weather forecast, which is displayed on the page. The code also includes a feature that asks for user location permission and, once granted, makes the second API call to fetch the weather forecast based on the user’s current location.

Conclusion and Final Words

In conclusion, building a weather app project allows you to apply your web development skills to a real-world application. Also, it helps you to better understand DOM manipulation, Event handling, CSS styling, APIs, and more. I hope that by following the steps in this post, you’ve successfully created your weather app using HTML, CSS, and JavaScript.

To understand this project’s code better, I recommend watching the above tutorial video, reading the code comments, and experimenting with the code. If you want to further enhance your web development skills, you should try recreating the Working Chatbot using HTML, CSS, and JavaScript.

If you encounter any difficulties while creating your weather app or your code is not working as expected, you can download the source code files for this weather app project for free by clicking the Download button. Keep in mind that after downloading the file, you’ll have to paste an “OpenWeatherMap API Key into the API_KEY variable in the script.js file.

]]>
https://www.codingnepalweb.com/weather-app-project-html-javascript/feed/ 0
How to Create Working Chatbot in HTML CSS and JavaScript https://www.codingnepalweb.com/create-chatbot-html-css-javascript/ https://www.codingnepalweb.com/create-chatbot-html-css-javascript/#respond Wed, 14 Jun 2023 11:42:10 +0000 https://www.codingnepalweb.com/?p=5582 How to Create Working Chatbot in HTML CSS and JavaScript

You may have seen chatbots on multiple websites, as they are now essential components for modern websites and apps. If you are unfamiliar, a chatbot is a computer program that serves as a virtual assistant and is capable of understanding user queries and providing relevant responses.

Building a chatbot is a practical way for beginner web developers to gain hands-on experience with HTML, CSS, and JavaScript, as these skills are crucial for creating real-world projects. So, in this blog post, I’ll guide you through creating a working chatbot using HTML, CSS, and JavaScript from scratch.

In this chatbot, users can ask any question and receive instant responses. This chatbot has an elegant and responsive user interface, ensuring a seamless experience across various devices. Keep in mind that to generate a response to the user query, this chatbot uses the OpenAI API, which is free.

Video Tutorial of Chatbot in HTML CSS & JavaScript

If you prefer learning through video tutorials, the provided video is an excellent resource for you to understand the process of creating your own functional chatbot. In the video, I explain each line of code and provide informative comments to make it beginner-friendly and easy to follow.

However, if you prefer reading blog posts or want a quick summary of the steps involved in creating this chatbot project, you can continue reading this post. By the end of this post, you will have your own chatbot that you can use to ask questions or integrate into your website or existing web projects.

Steps To Create Working Chatbot in HTML & JavaScript

To create your own working chatbot using HTML, CSS, and JavaScript, follow these step-by-step instructions:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create a style.css file. The file name must be style and its extension .css
  4. Create a script.js file. The file name must be script and its extension .js

To start, add the following HTML codes to your index.html file: This code snippet includes a chatbot header, a chatbox unordered list (ul), and an input field for user messages. By default, the chatbot will display a greeting message as the first chat “li”. We’ll use JavaScript later to dynamically add more chat “li” that contain chat details.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Chatbot in JavaScript | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Google Fonts Link For Icons -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@48,400,1,0" />
    <script src="script.js" defer></script>
  </head>
  <body>
    <button class="chatbot-toggler">
      <span class="material-symbols-rounded">mode_comment</span>
      <span class="material-symbols-outlined">close</span>
    </button>
    <div class="chatbot">
      <header>
        <h2>Chatbot</h2>
        <span class="close-btn material-symbols-outlined">close</span>
      </header>
      <ul class="chatbox">
        <li class="chat incoming">
          <span class="material-symbols-outlined">smart_toy</span>
          <p>Hi there 👋<br>How can I help you today?</p>
        </li>
      </ul>
      <div class="chat-input">
        <textarea placeholder="Enter a message..." spellcheck="false" required></textarea>
        <span id="send-btn" class="material-symbols-rounded">send</span>
      </div>
    </div>

  </body>
</html>

Next, add the following CSS codes to your style.css file to apply visual styling to your chatbot. Now, if you load the web page in your browser, you will only see the chatbot toggle button at the bottom right corner. You can customize this code to your liking by adjusting the color, font, size, and other CSS properties.

/* Import Google font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}
body {
  background: #E3F2FD;
}
.chatbot-toggler {
  position: fixed;
  bottom: 30px;
  right: 35px;
  outline: none;
  border: none;
  height: 50px;
  width: 50px;
  display: flex;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #724ae8;
  transition: all 0.2s ease;
}
body.show-chatbot .chatbot-toggler {
  transform: rotate(90deg);
}
.chatbot-toggler span {
  color: #fff;
  position: absolute;
}
.chatbot-toggler span:last-child,
body.show-chatbot .chatbot-toggler span:first-child  {
  opacity: 0;
}
body.show-chatbot .chatbot-toggler span:last-child {
  opacity: 1;
}
.chatbot {
  position: fixed;
  right: 35px;
  bottom: 90px;
  width: 420px;
  background: #fff;
  border-radius: 15px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transform: scale(0.5);
  transform-origin: bottom right;
  box-shadow: 0 0 128px 0 rgba(0,0,0,0.1),
              0 32px 64px -48px rgba(0,0,0,0.5);
  transition: all 0.1s ease;
}
body.show-chatbot .chatbot {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
}
.chatbot header {
  padding: 16px 0;
  position: relative;
  text-align: center;
  color: #fff;
  background: #724ae8;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.chatbot header span {
  position: absolute;
  right: 15px;
  top: 50%;
  display: none;
  cursor: pointer;
  transform: translateY(-50%);
}
header h2 {
  font-size: 1.4rem;
}
.chatbot .chatbox {
  overflow-y: auto;
  height: 510px;
  padding: 30px 20px 100px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar {
  width: 6px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar-track {
  background: #fff;
  border-radius: 25px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar-thumb {
  background: #ccc;
  border-radius: 25px;
}
.chatbox .chat {
  display: flex;
  list-style: none;
}
.chatbox .outgoing {
  margin: 20px 0;
  justify-content: flex-end;
}
.chatbox .incoming span {
  width: 32px;
  height: 32px;
  color: #fff;
  cursor: default;
  text-align: center;
  line-height: 32px;
  align-self: flex-end;
  background: #724ae8;
  border-radius: 4px;
  margin: 0 10px 7px 0;
}
.chatbox .chat p {
  white-space: pre-wrap;
  padding: 12px 16px;
  border-radius: 10px 10px 0 10px;
  max-width: 75%;
  color: #fff;
  font-size: 0.95rem;
  background: #724ae8;
}
.chatbox .incoming p {
  border-radius: 10px 10px 10px 0;
}
.chatbox .chat p.error {
  color: #721c24;
  background: #f8d7da;
}
.chatbox .incoming p {
  color: #000;
  background: #f2f2f2;
}
.chatbot .chat-input {
  display: flex;
  gap: 5px;
  position: absolute;
  bottom: 0;
  width: 100%;
  background: #fff;
  padding: 3px 20px;
  border-top: 1px solid #ddd;
}
.chat-input textarea {
  height: 55px;
  width: 100%;
  border: none;
  outline: none;
  resize: none;
  max-height: 180px;
  padding: 15px 15px 15px 0;
  font-size: 0.95rem;
}
.chat-input span {
  align-self: flex-end;
  color: #724ae8;
  cursor: pointer;
  height: 55px;
  display: flex;
  align-items: center;
  visibility: hidden;
  font-size: 1.35rem;
}
.chat-input textarea:valid ~ span {
  visibility: visible;
}

@media (max-width: 490px) {
  .chatbot-toggler {
    right: 20px;
    bottom: 20px;
  }
  .chatbot {
    right: 0;
    bottom: 0;
    height: 100%;
    border-radius: 0;
    width: 100%;
  }
  .chatbot .chatbox {
    height: 90%;
    padding: 25px 15px 100px;
  }
  .chatbot .chat-input {
    padding: 5px 15px;
  }
  .chatbot header span {
    display: block;
  }
}

Finally, add the following JavaScript code to your script.js file: This script code will make your chatbot functional, which means now you can ask your questions, show or hide the chatbot by clicking the bottom right toggle button, and more.

const chatbotToggler = document.querySelector(".chatbot-toggler");
const closeBtn = document.querySelector(".close-btn");
const chatbox = document.querySelector(".chatbox");
const chatInput = document.querySelector(".chat-input textarea");
const sendChatBtn = document.querySelector(".chat-input span");

let userMessage = null; // Variable to store user's message
const API_KEY = "PASTE-YOUR-API-KEY"; // Paste your API key here
const inputInitHeight = chatInput.scrollHeight;

const createChatLi = (message, className) => {
    // Create a chat <li> element with passed message and className
    const chatLi = document.createElement("li");
    chatLi.classList.add("chat", `${className}`);
    let chatContent = className === "outgoing" ? `<p></p>` : `<span class="material-symbols-outlined">smart_toy</span><p></p>`;
    chatLi.innerHTML = chatContent;
    chatLi.querySelector("p").textContent = message;
    return chatLi; // return chat <li> element
}

const generateResponse = (chatElement) => {
    const API_URL = "https://api.openai.com/v1/chat/completions";
    const messageElement = chatElement.querySelector("p");

    // Define the properties and message for the API request
    const requestOptions = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${API_KEY}`
        },
        body: JSON.stringify({
            model: "gpt-3.5-turbo",
            messages: [{role: "user", content: userMessage}],
        })
    }

    // Send POST request to API, get response and set the reponse as paragraph text
    fetch(API_URL, requestOptions).then(res => res.json()).then(data => {
        messageElement.textContent = data.choices[0].message.content.trim();
    }).catch(() => {
        messageElement.classList.add("error");
        messageElement.textContent = "Oops! Something went wrong. Please try again.";
    }).finally(() => chatbox.scrollTo(0, chatbox.scrollHeight));
}

const handleChat = () => {
    userMessage = chatInput.value.trim(); // Get user entered message and remove extra whitespace
    if(!userMessage) return;

    // Clear the input textarea and set its height to default
    chatInput.value = "";
    chatInput.style.height = `${inputInitHeight}px`;

    // Append the user's message to the chatbox
    chatbox.appendChild(createChatLi(userMessage, "outgoing"));
    chatbox.scrollTo(0, chatbox.scrollHeight);
    
    setTimeout(() => {
        // Display "Thinking..." message while waiting for the response
        const incomingChatLi = createChatLi("Thinking...", "incoming");
        chatbox.appendChild(incomingChatLi);
        chatbox.scrollTo(0, chatbox.scrollHeight);
        generateResponse(incomingChatLi);
    }, 600);
}

chatInput.addEventListener("input", () => {
    // Adjust the height of the input textarea based on its content
    chatInput.style.height = `${inputInitHeight}px`;
    chatInput.style.height = `${chatInput.scrollHeight}px`;
});

chatInput.addEventListener("keydown", (e) => {
    // If Enter key is pressed without Shift key and the window 
    // width is greater than 800px, handle the chat
    if(e.key === "Enter" && !e.shiftKey && window.innerWidth > 800) {
        e.preventDefault();
        handleChat();
    }
});

sendChatBtn.addEventListener("click", handleChat);
closeBtn.addEventListener("click", () => document.body.classList.remove("show-chatbot"));
chatbotToggler.addEventListener("click", () => document.body.classList.toggle("show-chatbot"));

Please note that your chatbot is currently unable to retrieve responses to your questions because you have not provided your API key in the AP_KEY variable. To get a free API key from OpenAI, sign up for an account at https://platform.openai.com/account/api-keys.

” Remember that when you sign up for OpenAI, you’ll get a free $5 credit for your API usage. If your account is older than 3 months or the credit runs out, you’ll need a paid account or create a new one with a new number to keep using the API. Your API usage and expiration date can be found on the account’s usage page.”

The above code provided follows a simple flow. First, it displays the user’s message in the chatbox and uses the OpenAI API to generate an appropriate response to the message. While waiting for the API response, a “Thinking…” message is shown. Once the response is received, it replaces the “Thinking…” message in the chatbox.

To understand codes better, I recommend watching the above tutorial video, reading the code comments, and experimenting with the code.

Conclusion and Final Words

In conclusion, creating a working chatbot allows you to apply your skills to a real-world application. I hope that by following the steps in this post, you’ve successfully created your own chatbot using HTML, CSS, and JavaScript.

To further improve your web development skills, you can try recreating the ChatGPT Clone Project using HTML, CSS, and JavaScript. This project helps you expand your knowledge by creating a ChatGPT clone with additional features like dark/light themes and saved chats using local storage.

If you encounter any difficulties while creating your own Chatbot or your code is not working as expected, you can download the source code files for this Chatbot project for free by clicking the Download button. Remember that after downloading the file, you’ll have to paste an “OpenAI API key” into the API_KEY variable in the script.js file.

 

]]>
https://www.codingnepalweb.com/create-chatbot-html-css-javascript/feed/ 0
Create Weather App in HTML Bootstrap and JavaScript https://www.codingnepalweb.com/weather-app-html-bootstrap-javascript/ https://www.codingnepalweb.com/weather-app-html-bootstrap-javascript/#respond Fri, 09 Jun 2023 13:00:33 +0000 https://www.codingnepalweb.com/?p=5568 Create A Weather App in HTML Bootstrap and JavaScript

In today’s digital age, weather apps have become an essential tool for staying informed about ever-changing weather conditions. As a beginner web developer, the idea of creating your weather app can be both exciting and educational.

In this blog post, I’ll guide you through the steps of creating a responsive weather app project using HTML, Bootstrap, and JavaScript. By creating this weather project, not only will you learn the basics of DOM manipulation, event handling, and CSS styling, but you’ll also gain valuable experience working with APIs.

In this weather app, users can enter the name of a city and get different weather details like temperature in Celsius, wind speed, humidity, and a 5-day forecast. But if you wish, you can easily add or remove the particular weather details because we’ll use the OpenWeatherMap API, so you’ll have access to a wide array of weather information.

Steps To Create Weather App in Bootstrap & JavaScript

To create your own weather app project using HTML, Bootstrap, and JavaScript, follow these step-by-step instructions:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create a style.css file. The file name must be style and its extension .css
  4. Create a script.js file. The file name must be script and its extension .js

To start, add the following HTML codes to your index.html file. Since we’ve used Bootstrap for this project, the design, and layout are almost ready and responsive. After saving the HTML file and opening it in your browser, you’ll see a header, a search box on the left side, and some placeholders for weather details.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Weather App Project | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
    <script src="script.js" defer></script>
  </head>
  <body>
    <header class="bg-success text-center py-3">
      <h1 class="fw-bold h3 text-white my-1">Weather Dashboard</h1>
    </header>
    <div class="container-fluid my-4 weather-data">
      <div class="row">
        <div class="col-xxl-3 col-md-4 px-lg-4">
          <h5 class="fw-bold">Enter a City Name</h5>
          <input type="text" id="city-input" class="py-2 form-control" placeholder="E.g., New York, London, Tokyo">
          <button id="search-btn" class="btn btn-success py-2 w-100 mt-3 mb-2">Search</button>
        </div>
        <div class="col-xxl-9 col-md-8 mt-md-1 mt-4 pe-lg-4">
          <div class="current-weather bg-success text-white py-2 px-4 rounded-3">
            <div class="mt-3 d-flex justify-content-between">
              <div>
                <h3 class="fw-bold">_______ ( ______ )</h3>
                <h6 class="my-3 mt-3">Temperature: __°C</h6>
                <h6 class="my-3">Wind: __ M/S</h6>
                <h6 class="my-3">Humidity: __%</h6>
              </div>
          </div>
          </div>
          <h4 class="fw-bold my-4">5-Day Forecast</h4>
          <div class="days-forecast row row-cols-1 row-cols-sm-2 row-cols-lg-4 row-cols-xl-5 justify-content-between">
            <div class="col mb-3">
              <div class="card border-0 bg-secondary text-white">
                <div class="card-body p-3 text-white">
                  <h5 class="card-title fw-semibold">( ______ )</h5>
                  <h6 class="card-text my-3 mt-3">Temp: __°C</h6>
                  <h6 class="card-text my-3">Wind: __ M/S</h6>
                  <h6 class="card-text my-3">Humidity: __%</h6>
                </div>
              </div>
            </div>
            <div class="col mb-3">
              <div class="card border-0 bg-secondary text-white">
                <div class="card-body p-3 text-white">
                  <h5 class="card-title fw-semibold">( ______ )</h5>
                  <h6 class="card-text my-3 mt-3">Temp: __°C</h6>
                  <h6 class="card-text my-3">Wind: __ M/S</h6>
                  <h6 class="card-text my-3">Humidity: __%</h6>
                </div>
              </div>
            </div>
            <div class="col mb-3">
              <div class="card border-0 bg-secondary text-white">
                <div class="card-body p-3 text-white">
                  <h5 class="card-title fw-semibold">( ______ )</h5>
                  <h6 class="card-text my-3 mt-3">Temp: __°C</h6>
                  <h6 class="card-text my-3">Wind: __ M/S</h6>
                  <h6 class="card-text my-3">Humidity: __%</h6>
                </div>
              </div>
            </div>
            <div class="col mb-3">
              <div class="card border-0 bg-secondary text-white">
                <div class="card-body p-3 text-white">
                  <h5 class="card-title fw-semibold">( ______ )</h5>
                  <h6 class="card-text my-3 mt-3">Temp: __°C</h6>
                  <h6 class="card-text my-3">Wind: __ M/S</h6>
                  <h6 class="card-text my-3">Humidity: __%</h6>
                </div>
              </div>
            </div>
            <div class="col mb-3">
              <div class="card border-0 bg-secondary text-white">
                <div class="card-body p-3 text-white">
                  <h5 class="card-title fw-semibold">( ______ )</h5>
                  <h6 class="card-text my-3 mt-3">Temp: __°C</h6>
                  <h6 class="card-text my-3">Wind: __ M/S</h6>
                  <h6 class="card-text my-3">Humidity: __%</h6>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

  </body>
</html>

Next, add the following few CSS codes to your style.css file to add custom styling to some elements like font family, and image width.

/* Import Google font - Open Sans */
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700;800&display=swap');

* {
  font-family: 'Open Sans', sans-serif;
}

.current-weather img {
  max-width: 120px;
  margin-top: -15px;
}

Finally, add the following JavaScript code to your script.js file to make the weather app functional, which means getting different weather details for an entered city.

const cityInput = document.querySelector("#city-input");
const searchButton = document.querySelector("#search-btn");
const currentWeatherDiv = document.querySelector(".current-weather");
const daysForecastDiv = document.querySelector(".days-forecast");

const API_KEY = "PASTE-YOUR-API-KEY"; // Paste your API here

// Create weather card HTML based on weather data
const createWeatherCard = (cityName, weatherItem, index) => {
    if(index === 0) {
        return `<div class="mt-3 d-flex justify-content-between">
                    <div>
                        <h3 class="fw-bold">${cityName} (${weatherItem.dt_txt.split(" ")[0]})</h3>
                        <h6 class="my-3 mt-3">Temperature: ${((weatherItem.main.temp - 273.15).toFixed(2))}°C</h6>
                        <h6 class="my-3">Wind: ${weatherItem.wind.speed} M/S</h6>
                        <h6 class="my-3">Humidity: ${weatherItem.main.humidity}%</h6>
                    </div>
                    <div class="text-center me-lg-5">
                        <img src="https://openweathermap.org/img/wn/${weatherItem.weather[0].icon}@4x.png" alt="weather icon">
                        <h6>${weatherItem.weather[0].description}</h6>
                    </div>
                </div>`;
    } else {
        return `<div class="col mb-3">
                    <div class="card border-0 bg-secondary text-white">
                        <div class="card-body p-3 text-white">
                            <h5 class="card-title fw-semibold">(${weatherItem.dt_txt.split(" ")[0]})</h5>
                            <img src="https://openweathermap.org/img/wn/${weatherItem.weather[0].icon}.png" alt="weather icon">
                            <h6 class="card-text my-3 mt-3">Temp: ${((weatherItem.main.temp - 273.15).toFixed(2))}°C</h6>
                            <h6 class="card-text my-3">Wind: ${weatherItem.wind.speed} M/S</h6>
                            <h6 class="card-text my-3">Humidity: ${weatherItem.main.humidity}%</h6>
                        </div>
                    </div>
                </div>`;
    }
}

// Get weather details of passed latitude and longitude
const getWeatherDetails = (cityName, latitude, longitude) => {
    const WEATHER_API_URL = `https://api.openweathermap.org/data/2.5/forecast?lat=${latitude}&lon=${longitude}&appid=${API_KEY}`;

    fetch(WEATHER_API_URL).then(response => response.json()).then(data => {
        const forecastArray = data.list;
        const uniqueForecastDays = new Set();

        const fiveDaysForecast = forecastArray.filter(forecast => {
            const forecastDate = new Date(forecast.dt_txt).getDate();
            if (!uniqueForecastDays.has(forecastDate) && uniqueForecastDays.size < 6) {
                uniqueForecastDays.add(forecastDate);
                return true;
            }
            return false;
        });

        cityInput.value = "";
        currentWeatherDiv.innerHTML = "";
        daysForecastDiv.innerHTML = "";

        fiveDaysForecast.forEach((weatherItem, index) => {
            const html = createWeatherCard(cityName, weatherItem, index);
            if (index === 0) {
                currentWeatherDiv.insertAdjacentHTML("beforeend", html);
            } else {
                daysForecastDiv.insertAdjacentHTML("beforeend", html);
            }
        });        
    }).catch(() => {
        alert("An error occurred while fetching the weather forecast!");
    });
}

// Get coordinates of entered city name
const getCityCoordinates = () => {
    const cityName = cityInput.value.trim();
    if (cityName === "") return;
    const API_URL = `https://api.openweathermap.org/geo/1.0/direct?q=${cityName}&limit=1&appid=${API_KEY}`;
  
    fetch(API_URL).then(response => response.json()).then(data => {
        if (!data.length) return alert(`No coordinates found for ${cityName}`);
        const { lat, lon, name } = data[0];
        getWeatherDetails(name, lat, lon);
    }).catch(() => {
        alert("An error occurred while fetching the coordinates!");
    });
}

searchButton.addEventListener("click", () => getCityCoordinates());

Please note that your weather app is currently unable to retrieve weather details because you have not provided your API key in the AP_KEY variable. To get a free API key from OpenWeatherMap, sign up for an account at https://home.openweathermap.org/api_keys.

In the code, there are two API calls. The first call gets the geographic coordinates of the city entered by the user. These coordinates are then used in the second call to retrieve the weather details, which are subsequently displayed on the page. Feel free to experiment with the code to gain a better understanding of its functionality.

Conclusion and Final Words

In conclusion, this blog post has guided you through the process of creating your own weather app using HTML, Bootstrap, and JavaScript. By following the steps outlined here, I hope you have successfully created your own weather app and learned how to work with APIs.

In addition to this weather app project, you can explore other exciting Bootstrap and JavaScript API projects available on this website to enhance your web development skills. These include Bootstrap Websites, ChatGPT Clone, Functional Image Gallery, Currency Converter, and more.

If you encounter any difficulties while creating your own weather app or your code is not working as expected, you can download the source code files for this weather app project for free by clicking the Download button. You can also view a live demo of it by clicking the View Live button.

]]>
https://www.codingnepalweb.com/weather-app-html-bootstrap-javascript/feed/ 0
How to Create Your Own ChatGPT in HTML CSS and JavaScript https://www.codingnepalweb.com/create-chatgpt-clone-html-css-javascript/ https://www.codingnepalweb.com/create-chatgpt-clone-html-css-javascript/#respond Wed, 31 May 2023 08:17:30 +0000 https://www.codingnepalweb.com/?p=5535 Create Your Own ChatGPT in HTML, CSS, and JavaScript ChatGPT Clone HTML, CSS, and JavaScript

ChatGPT has gained significant popularity in recent months or years, completely changing how we interact with automated chatbots. As a beginner web developer, you might be curious about creating your own ChatGPT. The good news is that it is possible to create a ChatGPT clone using HTML, CSS, and vanilla JavaScript.

If you’re unfamiliar, ChatGPT is an advanced chatbot model developed by OpenAI. It uses artificial intelligence to generate human-like responses in a conversational format. ChatGPT has gained widespread popularity due to its ability to simulate natural conversations.

In this blog post, we will guide you through the steps of creating your very own ChatGPT using HTML, CSS, and JavaScript. By building a ChatGPT clone project, beginner web developers can gain practical experience by applying their HTML, CSS, and JavaScript skills to real-world projects.

This ChatGPT clone project allows you to ask questions and receive instant responses. Additionally, you have the option to switch between dark and light themes. Your chat history is saved in the browser’s local storage, ensuring it remains even if you refresh the page. However, you can easily delete chats by clicking on the dedicated “Delete Chat” button.

Video Tutorial of ChatGPT Clone in HTML & JavaScript

If you prefer learning through video tutorials, the provided video is an excellent resource for you to understand the process of creating your own ChatGPT. In the video, I explain each line of code and provide informative comments to make it beginner-friendly and easy to follow.

However, if you prefer reading blog posts or want a quick summary of the steps involved in creating a ChatGPT clone project, you can continue reading this post. By the end of this post, you will have your own ChatGPT that you can chat with.

Steps To Create ChatGPT Clone in HTML & JavaScript

To create your own ChatGPT using HTML, CSS, and JavaScript, follow these step-by-step instructions:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create a style.css file. The file name must be style and its extension .css
  4. Create a script.js file. The file name must be script and its extension .js
  5. Download and place the images folder in your project directory. This folder includes the user avatar and chatbot logo.

To start, add the following HTML codes to your index.html file: In this code snippet, you will find an empty “chat-container” div. We will later use JavaScript to dynamically add the “chat” div that will contain all the chat details.

<!DOCTYPE html>
<!-- Coding By CodingNepal - www.codingnepalweb.com -->
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>ChatGPT Clone in JavaScript | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Google Fonts Link For Icons -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
    <script src="script.js" defer></script>
  </head>
  <body>
    <!-- Chats container -->
    <div class="chat-container"></div>
    
    <!-- Typing container -->
    <div class="typing-container">
      <div class="typing-content">
        <div class="typing-textarea">
          <textarea id="chat-input" spellcheck="false" placeholder="Enter a prompt here" required></textarea>
          <span id="send-btn" class="material-symbols-rounded">send</span>
        </div>
        <div class="typing-controls">
          <span id="theme-btn" class="material-symbols-rounded">light_mode</span>
          <span id="delete-btn" class="material-symbols-rounded">delete</span>
      </div>
    </div>

  </body>
</html>

Next, add the following CSS codes to your style.css file to apply visual styling to your ChatGPT interface. Now, if you load the web page in your browser, you will see ChatGPT displayed with a text input box and some icons at the bottom.

/* Import Google font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}
:root {
  --text-color: #FFFFFF;
  --icon-color: #ACACBE;
  --icon-hover-bg: #5b5e71;
  --placeholder-color: #dcdcdc;
  --outgoing-chat-bg: #343541;
  --incoming-chat-bg: #444654;
  --outgoing-chat-border: #343541;
  --incoming-chat-border: #444654;
}
.light-mode {
  --text-color: #343541;
  --icon-color: #a9a9bc;
  --icon-hover-bg: #f1f1f3;
  --placeholder-color: #6c6c6c;
  --outgoing-chat-bg: #FFFFFF;
  --incoming-chat-bg: #F7F7F8;
  --outgoing-chat-border: #FFFFFF;
  --incoming-chat-border: #D9D9E3;
}
body {
  background: var(--outgoing-chat-bg);
}

/* Chats container styling */
.chat-container {
  overflow-y: auto;
  max-height: 100vh;
  padding-bottom: 150px;
}
:where(.chat-container, textarea)::-webkit-scrollbar {
  width: 6px;
}
:where(.chat-container, textarea)::-webkit-scrollbar-track {
  background: var(--incoming-chat-bg);
  border-radius: 25px;
}
:where(.chat-container, textarea)::-webkit-scrollbar-thumb {
  background: var(--icon-color);
  border-radius: 25px;
}
.default-text {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  height: 70vh;
  padding: 0 10px;
  text-align: center;
  color: var(--text-color);
}
.default-text h1 {
  font-size: 3.3rem;
}
.default-text p {
  margin-top: 10px;
  font-size: 1.1rem;
}
.chat-container .chat {
  padding: 25px 10px;
  display: flex;
  justify-content: center;
  color: var(--text-color);
}
.chat-container .chat.outgoing {
  background: var(--outgoing-chat-bg);
  border: 1px solid var(--outgoing-chat-border);
}
.chat-container .chat.incoming {
  background: var(--incoming-chat-bg);
  border: 1px solid var(--incoming-chat-border);
}
.chat .chat-content {
  display: flex;
  max-width: 1200px;
  width: 100%;
  align-items: flex-start;
  justify-content: space-between;
}
span.material-symbols-rounded {
  user-select: none;
  cursor: pointer;
}
.chat .chat-content span {
  cursor: pointer;
  font-size: 1.3rem;
  color: var(--icon-color);
  visibility: hidden;
}
.chat:hover .chat-content:not(:has(.typing-animation), :has(.error)) span {
  visibility: visible;
}
.chat .chat-details {
  display: flex;
  align-items: center;
}
.chat .chat-details img {
  width: 35px;
  height: 35px;
  align-self: flex-start;
  object-fit: cover;
  border-radius: 2px;
}
.chat .chat-details p {
  white-space: pre-wrap;
  font-size: 1.05rem;
  padding: 0 50px 0 25px;
  color: var(--text-color);
  word-break: break-word;
}
.chat .chat-details p.error {
  color: #e55865;
}
.chat .typing-animation {
  padding-left: 25px;
  display: inline-flex;
}
.typing-animation .typing-dot {
  height: 7px;
  width: 7px;
  border-radius: 50%;
  margin: 0 3px;
  opacity: 0.7;
  background: var(--text-color);
  animation: animateDots 1.5s var(--delay) ease-in-out infinite;
}
.typing-animation .typing-dot:first-child {
  margin-left: 0;
}
@keyframes animateDots {
  0%,44% {
    transform: translateY(0px);
  }
  28% {
    opacity: 0.4;
    transform: translateY(-6px);
  }
  44% {
    opacity: 0.2;
  }
}

/* Typing container styling */
.typing-container {
  position: fixed;
  bottom: 0;
  width: 100%;
  display: flex;
  padding: 20px 10px;
  justify-content: center;
  background: var(--outgoing-chat-bg);
  border-top: 1px solid var(--incoming-chat-border);
}
.typing-container .typing-content {
  display: flex;
  max-width: 950px;
  width: 100%;
  align-items: flex-end;
}
.typing-container .typing-textarea {
  width: 100%;
  display: flex;
  position: relative;
}
.typing-textarea textarea {
  resize: none;
  height: 55px;
  width: 100%;
  border: none;
  padding: 15px 45px 15px 20px;
  color: var(--text-color);
  font-size: 1rem;
  border-radius: 4px;
  max-height: 250px;
  overflow-y: auto;
  background: var(--incoming-chat-bg);
  outline: 1px solid var(--incoming-chat-border);
}
.typing-textarea textarea::placeholder {
  color: var(--placeholder-color);
}
.typing-content span {
  width: 55px;
  height: 55px;
  display: flex;
  border-radius: 4px;
  font-size: 1.35rem;
  align-items: center;
  justify-content: center;
  color: var(--icon-color);
}
.typing-textarea span {
  position: absolute;
  right: 0;
  bottom: 0;
  visibility: hidden;
}
.typing-textarea textarea:valid ~ span {
  visibility: visible;
}
.typing-controls {
  display: flex;
}
.typing-controls span {
  margin-left: 7px;
  font-size: 1.4rem;
  background: var(--incoming-chat-bg);
  outline: 1px solid var(--incoming-chat-border);
}
.typing-controls span:hover {
  background: var(--icon-hover-bg);
}

/* Reponsive Media Query */
@media screen and (max-width: 600px) {
  .default-text h1 {
    font-size: 2.3rem;
  }
  :where(.default-text p, textarea, .chat p) {
    font-size: 0.95rem!important;
  }
  .chat-container .chat {
    padding: 20px 10px;
  }
  .chat-container .chat img {
    height: 32px;
    width: 32px;
  }
  .chat-container .chat p {
    padding: 0 20px;
  }
  .chat .chat-content:not(:has(.typing-animation), :has(.error)) span {
    visibility: visible;
  }
  .typing-container {
    padding: 15px 10px;
  }
  .typing-textarea textarea {
    height: 45px;
    padding: 10px 40px 10px 10px;
  }
  .typing-content span {
    height: 45px;
    width: 45px;
    margin-left: 5px;
  }
  span.material-symbols-rounded {
    font-size: 1.25rem!important;
  }
}

Finally, add the following JavaScript code to your script.js file. This script code will make your ChatGPT functional by enabling features such as chatting, switching between dark and light themes, and saving chat history in the browser.

const chatInput = document.querySelector("#chat-input");
const sendButton = document.querySelector("#send-btn");
const chatContainer = document.querySelector(".chat-container");
const themeButton = document.querySelector("#theme-btn");
const deleteButton = document.querySelector("#delete-btn");

let userText = null;
const API_KEY = "PASTE-YOUR-API-KEY-HERE"; // Paste your API key here

const loadDataFromLocalstorage = () => {
    // Load saved chats and theme from local storage and apply/add on the page
    const themeColor = localStorage.getItem("themeColor");

    document.body.classList.toggle("light-mode", themeColor === "light_mode");
    themeButton.innerText = document.body.classList.contains("light-mode") ? "dark_mode" : "light_mode";

    const defaultText = `<div class="default-text">
                            <h1>ChatGPT Clone</h1>
                            <p>Start a conversation and explore the power of AI.<br> Your chat history will be displayed here.</p>
                        </div>`

    chatContainer.innerHTML = localStorage.getItem("all-chats") || defaultText;
    chatContainer.scrollTo(0, chatContainer.scrollHeight); // Scroll to bottom of the chat container
}

const createChatElement = (content, className) => {
    // Create new div and apply chat, specified class and set html content of div
    const chatDiv = document.createElement("div");
    chatDiv.classList.add("chat", className);
    chatDiv.innerHTML = content;
    return chatDiv; // Return the created chat div
}

const getChatResponse = async (incomingChatDiv) => {
    const API_URL = "https://api.openai.com/v1/completions";
    const pElement = document.createElement("p");

    // Define the properties and data for the API request
    const requestOptions = {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${API_KEY}`
        },
        body: JSON.stringify({
            model: "text-davinci-003",
            prompt: userText,
            max_tokens: 2048,
            temperature: 0.2,
            n: 1,
            stop: null
        })
    }

    // Send POST request to API, get response and set the reponse as paragraph element text
    try {
        const response = await (await fetch(API_URL, requestOptions)).json();
        pElement.textContent = response.choices[0].text.trim();
    } catch (error) { // Add error class to the paragraph element and set error text
        pElement.classList.add("error");
        pElement.textContent = "Oops! Something went wrong while retrieving the response. Please try again.";
    }

    // Remove the typing animation, append the paragraph element and save the chats to local storage
    incomingChatDiv.querySelector(".typing-animation").remove();
    incomingChatDiv.querySelector(".chat-details").appendChild(pElement);
    localStorage.setItem("all-chats", chatContainer.innerHTML);
    chatContainer.scrollTo(0, chatContainer.scrollHeight);
}

const copyResponse = (copyBtn) => {
    // Copy the text content of the response to the clipboard
    const reponseTextElement = copyBtn.parentElement.querySelector("p");
    navigator.clipboard.writeText(reponseTextElement.textContent);
    copyBtn.textContent = "done";
    setTimeout(() => copyBtn.textContent = "content_copy", 1000);
}

const showTypingAnimation = () => {
    // Display the typing animation and call the getChatResponse function
    const html = `<div class="chat-content">
                    <div class="chat-details">
                        <img src="images/chatbot.jpg" alt="chatbot-img">
                        <div class="typing-animation">
                            <div class="typing-dot" style="--delay: 0.2s"></div>
                            <div class="typing-dot" style="--delay: 0.3s"></div>
                            <div class="typing-dot" style="--delay: 0.4s"></div>
                        </div>
                    </div>
                    <span onclick="copyResponse(this)" class="material-symbols-rounded">content_copy</span>
                </div>`;
    // Create an incoming chat div with typing animation and append it to chat container
    const incomingChatDiv = createChatElement(html, "incoming");
    chatContainer.appendChild(incomingChatDiv);
    chatContainer.scrollTo(0, chatContainer.scrollHeight);
    getChatResponse(incomingChatDiv);
}

const handleOutgoingChat = () => {
    userText = chatInput.value.trim(); // Get chatInput value and remove extra spaces
    if(!userText) return; // If chatInput is empty return from here

    // Clear the input field and reset its height
    chatInput.value = "";
    chatInput.style.height = `${initialInputHeight}px`;

    const html = `<div class="chat-content">
                    <div class="chat-details">
                        <img src="images/user.jpg" alt="user-img">
                        <p>${userText}</p>
                    </div>
                </div>`;

    // Create an outgoing chat div with user's message and append it to chat container
    const outgoingChatDiv = createChatElement(html, "outgoing");
    chatContainer.querySelector(".default-text")?.remove();
    chatContainer.appendChild(outgoingChatDiv);
    chatContainer.scrollTo(0, chatContainer.scrollHeight);
    setTimeout(showTypingAnimation, 500);
}

deleteButton.addEventListener("click", () => {
    // Remove the chats from local storage and call loadDataFromLocalstorage function
    if(confirm("Are you sure you want to delete all the chats?")) {
        localStorage.removeItem("all-chats");
        loadDataFromLocalstorage();
    }
});

themeButton.addEventListener("click", () => {
    // Toggle body's class for the theme mode and save the updated theme to the local storage 
    document.body.classList.toggle("light-mode");
    localStorage.setItem("themeColor", themeButton.innerText);
    themeButton.innerText = document.body.classList.contains("light-mode") ? "dark_mode" : "light_mode";
});

const initialInputHeight = chatInput.scrollHeight;

chatInput.addEventListener("input", () => {   
    // Adjust the height of the input field dynamically based on its content
    chatInput.style.height =  `${initialInputHeight}px`;
    chatInput.style.height = `${chatInput.scrollHeight}px`;
});

chatInput.addEventListener("keydown", (e) => {
    // If the Enter key is pressed without Shift and the window width is larger 
    // than 800 pixels, handle the outgoing chat
    if (e.key === "Enter" && !e.shiftKey && window.innerWidth > 800) {
        e.preventDefault();
        handleOutgoingChat();
    }
});

loadDataFromLocalstorage();
sendButton.addEventListener("click", handleOutgoingChat);

Remember, your ChatGPT is not yet ready to generate chats based on prompts. To make it functional, you need to pay attention to a crucial detail in the code. Take a closer look, and you’ll notice that you have to paste an “OpenAI API key” into the API_KEY variable.

To get your API key, visit the following URL: https://platform.openai.com/account/api-keys. Once there, log in to your account, and you will be able to generate a free API key. To understand other things in the code. I recommend watching the tutorial video, reading the code comments, and experimenting with the code.

” Remember that when you sign up for OpenAI, you’ll get a free $5 credit for your API usage. If your account is older than 3 months or the credit runs out, you’ll need a paid account or create a new one with a new number to keep using the API. Your API usage and expiration date can be found on the account’s usage page.”

Conclusion and Final Words

Congratulations! You have successfully created a ChatGPT clone project using HTML, CSS, and vanilla JavaScript and integrated it with the OpenAI API. Now, you can engage in meaningful conversations and showcase your talent to friends and beyond.

I encourage you to continue improving your skills by diving into other exciting real-world projects such as JavaScript API projects, JavaScript games, Form validations, Image sliders, and more.

If you encounter any difficulties while creating your own ChatGPT or your code is not working as expected, you can download the source code files for this ChatGPT clone project for free by clicking the Download button. You can also view a live demo of it by clicking the View Live button.

Remember that after downloading the file, you’ll have to paste an “OpenAI API key” into the API_KEY variable in the script.js file. To get your API key, visit the following URL: https://platform.openai.com/account/api-keys. Once there, log in to your account, and you will be able to generate a free API key.

]]>
https://www.codingnepalweb.com/create-chatgpt-clone-html-css-javascript/feed/ 0
How to Implement Form Validation in HTML CSS and JavaScript https://www.codingnepalweb.com/implement-form-validation-html-javascript/ https://www.codingnepalweb.com/implement-form-validation-html-javascript/#respond Thu, 25 May 2023 10:08:50 +0000 https://www.codingnepalweb.com/?p=5492 How to Implement Form Validation in HTML CSS and JavaScript

Forms play a crucial role in web development, allowing users to input and submit their data. However, ensuring the accuracy and integrity of the data is essential. This is where form validation comes into play.

Form validation involves ensuring that the data entered by users in a form meets specific criteria and is valid. Its primary purpose is to prevent the submission of incomplete or invalid data.

This blog post is designed to guide beginner web developers through the process of form validation using HTML, CSS, and JavaScript. You will start from scratch, learning how to create a responsive form using HTML and CSS. Then, we will dive into the world of form validation and explore how to apply it effectively using JavaScript.

Additionally, you’ll also learn how to show or hide password visibility on the toggle button click. To see a live demo of this form validation in action, scroll to the bottom of this page and click on the View Live Demo button.

Steps For Creating Form Validation in HTML

To create a form and do the validation using HTML, CSS, and vanilla JavaScript, follow the given steps line by line:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create an thank-you.html file. The file name must be index and its extension .html
  4. Create a style.css file. The file name must be style and its extension .css
  5. Create a script.js file. The file name must be script and its extension .js

To start, add the following HTML codes to your index.html file to create a basic form layout: This form includes full name, email, password, date of birth, and gender fields, but you can add or remove fields as desired.

<!DOCTYPE html>
<!-- Website - www.codingnepalweb.com -->
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form Validation in HTML | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <!-- Fontawesome CDN Link For Icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" />
  </head>
  <body>
    <form action="thank-you.html">
      <h2>Form Validation</h2>
      <div class="form-group fullname">
        <label for="fullname">Full Name</label>
        <input type="text" id="fullname" placeholder="Enter your full name">
      </div>
      <div class="form-group email">
        <label for="email">Email Address</label>
        <input type="text" id="email" placeholder="Enter your email address">
      </div>
      <div class="form-group password">
        <label for="password">Password</label>
        <input type="password" id="password" placeholder="Enter your password">
        <i id="pass-toggle-btn" class="fa-solid fa-eye"></i>
      </div>
      <div class="form-group date">
        <label for="date">Birth Date</label>
        <input type="date" id="date" placeholder="Select your date">
      </div>
      <div class="form-group gender">
        <label for="gender">Gender</label>
        <select id="gender">
          <option value="" selected disabled>Select your gender</option>
          <option value="Male">Male</option>
          <option value="Female">Female</option>
          <option value="Other">Other</option>
        </select>
      </div>
      <div class="form-group submit-btn">
        <input type="submit" value="Submit">
      </div>
    </form>

    <script src="script.js"></script>
  </body>
</html>

Next, add the following HTML codes to your thank-you.html file: When the user fills out the form with valid data, they will be redirected to this HTML page. This page includes only a heading that says, “Thank you for filling out the form correctly.”.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Thanks page</title>
</head>
<body>
    <h1>Thank you for filling out the form correctly.</h1>
</body>
</html>

Next, add the following CSS codes to your style.css file to style the form and make it responsive and beautiful. You can customize this code to your liking by adjusting the color, font, size, and other CSS properties.

@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap');

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Open Sans', sans-serif;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  min-height: 100vh;
  background: #1BB295;
}

form {
  padding: 25px;
  background: #fff;
  max-width: 500px;
  width: 100%;
  border-radius: 7px;
  box-shadow: 0 10px 15px rgba(0, 0, 0, 0.05);
}

form h2 {
  font-size: 27px;
  text-align: center;
  margin: 0px 0 30px;
}

form .form-group {
  margin-bottom: 15px;
  position: relative;
}

form label {
  display: block;
  font-size: 15px;
  margin-bottom: 7px;
}

form input,
form select {
  height: 45px;
  padding: 10px;
  width: 100%;
  font-size: 15px;
  outline: none;
  background: #fff;
  border-radius: 3px;
  border: 1px solid #bfbfbf;
}

form input:focus,
form select:focus {
  border-color: #9a9a9a;
}

form input.error,
form select.error {
  border-color: #f91919;
  background: #f9f0f1;
}

form small {
  font-size: 14px;
  margin-top: 5px;
  display: block;
  color: #f91919;
}

form .password i {
  position: absolute;
  right: 0px;
  height: 45px;
  top: 28px;
  font-size: 13px;
  line-height: 45px;
  width: 45px;
  cursor: pointer;
  color: #939393;
  text-align: center;
}

.submit-btn {
  margin-top: 30px;
}

.submit-btn input {
  color: white;
  border: none;
  height: auto;
  font-size: 16px;
  padding: 13px 0;
  border-radius: 5px;
  cursor: pointer;
  font-weight: 500;
  text-align: center;
  background: #1BB295;
  transition: 0.2s ease;
}

.submit-btn input:hover {
  background: #179b81;
}

Finally, add the following JavaScript code to your script.js file to enable form validation, display appropriate error messages, and implement the toggle functionality for password visibility.

// Selecting form and input elements
const form = document.querySelector("form");
const passwordInput = document.getElementById("password");
const passToggleBtn = document.getElementById("pass-toggle-btn");

// Function to display error messages
const showError = (field, errorText) => {
    field.classList.add("error");
    const errorElement = document.createElement("small");
    errorElement.classList.add("error-text");
    errorElement.innerText = errorText;
    field.closest(".form-group").appendChild(errorElement);
}

// Function to handle form submission
const handleFormData = (e) => {
    e.preventDefault();

    // Retrieving input elements
    const fullnameInput = document.getElementById("fullname");
    const emailInput = document.getElementById("email");
    const dateInput = document.getElementById("date");
    const genderInput = document.getElementById("gender");

    // Getting trimmed values from input fields
    const fullname = fullnameInput.value.trim();
    const email = emailInput.value.trim();
    const password = passwordInput.value.trim();
    const date = dateInput.value;
    const gender = genderInput.value;

    // Regular expression pattern for email validation
    const emailPattern = /^[^ ]+@[^ ]+\.[a-z]{2,3}$/;

    // Clearing previous error messages
    document.querySelectorAll(".form-group .error").forEach(field => field.classList.remove("error"));
    document.querySelectorAll(".error-text").forEach(errorText => errorText.remove());

    // Performing validation checks
    if (fullname === "") {
        showError(fullnameInput, "Enter your full name");
    }
    if (!emailPattern.test(email)) {
        showError(emailInput, "Enter a valid email address");
    }
    if (password === "") {
        showError(passwordInput, "Enter your password");
    }
    if (date === "") {
        showError(dateInput, "Select your date of birth");
    }
    if (gender === "") {
        showError(genderInput, "Select your gender");
    }

    // Checking for any remaining errors before form submission
    const errorInputs = document.querySelectorAll(".form-group .error");
    if (errorInputs.length > 0) return;

    // Submitting the form
    form.submit();
}

// Toggling password visibility
passToggleBtn.addEventListener('click', () => {
    passToggleBtn.className = passwordInput.type === "password" ? "fa-solid fa-eye-slash" : "fa-solid fa-eye";
    passwordInput.type = passwordInput.type === "password" ? "text" : "password";
});

// Handling form submission event
form.addEventListener("submit", handleFormData);

Conclusion and Final Words

In conclusion, we started creating the structure of the form using HTML, defining the necessary input fields and their attributes. Then, we used CSS to apply styles to elements such as form fields, labels, and buttons. And last, we used JavaScript to implement form validation logic to ensure that users input valid data.

By following the instructions in this blog post, you should now have a functional form with validation features. For further enhancement of your web development skills, I encourage you to explore and experiment with the various types of forms and form validations provided on this website.

If you encounter any difficulties while creating your form or your code is not working as expected, you can download the source code files for this form for free by clicking the Download button. You can also view a live demo of it by clicking the View Live button.

]]>
https://www.codingnepalweb.com/implement-form-validation-html-javascript/feed/ 0
Create Draggable Bottom Sheet Modal in HTML CSS & JavaScript https://www.codingnepalweb.com/draggable-bottom-sheet-modal-html-css-javascript/ https://www.codingnepalweb.com/draggable-bottom-sheet-modal-html-css-javascript/#respond Wed, 17 May 2023 10:09:57 +0000 https://www.codingnepalweb.com/?p=5487 Create A Draggable Bottom Sheet Modal in HTML CSS and JavaScript

Have you ever used an app like Facebook or Instagram and see a modal that slides up from the bottom of the screen? These bottom-sheet modals are a great way to provide users with additional information or functionality without taking up too much screen space. As a beginner web developer, you might wonder how to create one of these modals yourself.

In this blog post, I’ll show you how to create a draggable bottom sheet modal using HTML, CSS, and JavaScript from scratch. This modal allows the user to view its contents, drag it up or down, and close it similarly to Facebook. It is responsive and also works on touch-enabled devices like phones.

By the end of this post, you’ll have a basic idea of how dragging bottom sheet modal popups works and how to use them on your own projects.

Video Tutorial of Bottom Sheet Modal in JavaScript

If you prefer visual learning, then the above video tutorial is a great resource for you. I highly recommend watching it for beginners because I go through each line of code in detail and provide explanatory comments to make the code easy to understand and follow.

However, if you prefer reading blog posts or want a quick summary of the steps involved in creating a bottom sheet modal, you can continue reading this post. By the end of this post, you will have a good understanding of how to create a draggable bottom sheet modal by yourself with HTML, CSS, and JavaScript.

Steps To Create Bottom Sheet Modal in JavaScript

To create a draggable bottom sheet modal using HTML, CSS, and JavaScript, follow the given steps line by line:

  1. Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
  2. Create an index.html file. The file name must be index and its extension .html
  3. Create a style.css file. The file name must be style and its extension .css
  4. Create a script.js file. The file name must be script and its extension .js

To start, add the following HTML codes to your index.html file to create a basic layout for our modal. This code includes a “button” element and a “div” container that includes modal content. The button will use to show the modal on click.

<!DOCTYPE html>
<!-- Website - www.codingnepalweb.com -->
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Draggable Bottom Sheet Modal | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="script.js" defer></script>
  </head>
  <body>
    <button class="show-modal">Show Bottom Sheet</button>
    <div class="bottom-sheet">
      <div class="sheet-overlay"></div>
      <div class="content">
        <div class="header">
          <div class="drag-icon"><span></span></div>
        </div>
        <div class="body">
          <h2>Bottom Sheet Modal</h2>
          <p>Create a bottom sheet modal that functions similarly to Facebook modal using HTML CSS and JavaScript. This modal allows user to view its contents, drag it up or down, and close it. It also works on touch-enabled devices. Lorem Ipsum are simply dummy text of there printing and typesetting industry. Lorem new Ipsum has been the industryss standard dummy text ever since the 1500s, when an off unknown printer tooks a galley of type and scrambled it to makes type spemen book It has survived not only five centuries.</p>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellat quae facere, quaerat deleniti, voluptates optio ipsam ipsum beatae, maxime quis ea quasi minima numquam. Minima accusamus reiciendis, impedit blanditiis nulla quia? Odio deleniti commodi id nesciunt voluptas cumque odit, vel molestias ratione sit consectetur inventore error ullam magni labore voluptate doloribus sed similique. Delectus non pariatur eligendi eos voluptatum provident eveniet consequuntur. Laboriosam, nesciunt reiciendis libero sunt adipisci numquam voluptas ullam, iure voluptates soluta mollitia quam voluptatem? Nemo, ipsum magnam.</p>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum eligendi commodi tenetur est beatae cupiditate incidunt aspernatur asperiores repudiandae? Odit, nulla modi ducimus assumenda ad voluptatem explicabo laudantium est unde ea similique excepturi fugiat nisi facere ab pariatur libero eius aperiam, non accusantium, asperiores optio. Accusantium, inventore in. Quaerat exercitationem aut, alias dolorem facere atque sint quo quasi vitae sed corrupti perferendis laborum eligendi repudiandae esse autem doloribus sapiente deleniti.</p>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Unde voluptates, animi ipsa explicabo assumenda molestiae adipisci. Amet, dignissimos reiciendis, voluptatibus placeat quo ab quibusdam illum repellat, ad molestias quaerat saepe modi aperiam distinctio dolore id sapiente molestiae quas! Animi optio nobis nesciunt pariatur? Non necessitatibus mollitia veniam nihil eos natus libero quaerat vitae maiores. Praesentium nesciunt natus tempora. Doloremque, fuga?</p>
          <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Deserunt deleniti a non dolorem delectus possimus distinctio! Nemo officiis tempore quos culpa fugit iste suscipit minus voluptatem, officia dicta ad deleniti harum voluptatibus dignissimos in, commodi placeat accusamus sint tenetur non natus? Error fugit quasi repudiandae mollitia doloribus officia eius magnam ratione soluta aut in iusto vel ut minima, at facere, minus sequi earum dolores animi ipsa nihil labore. Odio eius vitae iste repellendus molestias, amet sapiente laudantium optio, provident dignissimos voluptatum nesciunt nemo magni obcaecati commodi officiis delectus esse sed.</p>
          <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quaerat atque labore eligendi iusto sint! Fuga vel eius dolor eligendi ab cumque, maxime commodi, ducimus inventore temporibus illo delectus iste, quisquam ipsum labore eaque ipsa soluta praesentium voluptatem accusamus amet recusandae. Veniam necessitatibus laboriosam deleniti maxime, saepe vitae officia tempora voluptates voluptas ratione fugiat ad? Nostrum explicabo, earum dolor magnam commodi maiores iusto delectus porro ducimus architecto non enim eum, perspiciatis facere mollitia. Minus, mollitia animi! Nostrum deleniti, error quia hic eum modi? Corrupti illo provident dolores qui enim, expedita adipisci.</p>
        </div>
      </div>
    </div>

  </body>
</html>

Next, add the following CSS codes to your style.css file to style the bottom sheet modal and the button. You can customize this code to your liking by adjusting the color, font, size, and other CSS properties. Upon adding these styles, the modal will initially be hidden in the browser, while the button remains visible.

/* Import Google font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: #E3F2FD;
}
.show-modal {
  outline: none;
  border: none;
  cursor: pointer;
  color: #fff;
  border-radius: 6px;
  font-size: 1.2rem;
  padding: 15px 22px;
  background: #4A98F7;
  transition: 0.3s ease;
  box-shadow: 0 10px 18px rgba(52,87,220,0.18);
}
.show-modal:hover {
  background: #2382f6;
}
.bottom-sheet {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  opacity: 0;
  pointer-events: none;
  align-items: center;
  flex-direction: column;
  justify-content: flex-end;
  transition: 0.1s linear;
}
.bottom-sheet.show {
  opacity: 1;
  pointer-events: auto;
}
.bottom-sheet .sheet-overlay {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  opacity: 0.2;
  background: #000;
}
.bottom-sheet .content {
  width: 100%;
  position: relative;
  background: #fff;
  max-height: 100vh;
  height: 50vh;
  max-width: 1150px;
  padding: 25px 30px;
  transform: translateY(100%);
  border-radius: 12px 12px 0 0;
  box-shadow: 0 10px 20px rgba(0,0,0,0.03);
  transition: 0.3s ease;
}
.bottom-sheet.show .content{
  transform: translateY(0%);
}
.bottom-sheet.dragging .content {
  transition: none;
}
.bottom-sheet.fullscreen .content {
  border-radius: 0;
  overflow-y: hidden;
}
.bottom-sheet .header {
  display: flex;
  justify-content: center;
}
.header .drag-icon {
  cursor: grab;
  user-select: none;
  padding: 15px;
  margin-top: -15px;
}
.header .drag-icon span {
  height: 4px;
  width: 40px;
  display: block;
  background: #C7D0E1;
  border-radius: 50px;
}
.bottom-sheet .body {
  height: 100%;
  overflow-y: auto;
  padding: 15px 0 40px;
  scrollbar-width: none;
}
.bottom-sheet .body::-webkit-scrollbar {
  width: 0;
}
.bottom-sheet .body h2 {
  font-size: 1.8rem;
}
.bottom-sheet .body p {
  margin-top: 20px;
  font-size: 1.05rem;
}

Finally, add the following JavaScript code to your script.js file to add the functionality of show/hide, and drag up and down to the modal. Upon adding these scripts, when you click on the button, the modal will slide up from the bottom.

// Select DOM elements
const showModalBtn = document.querySelector(".show-modal");
const bottomSheet = document.querySelector(".bottom-sheet");
const sheetOverlay = bottomSheet.querySelector(".sheet-overlay");
const sheetContent = bottomSheet.querySelector(".content");
const dragIcon = bottomSheet.querySelector(".drag-icon");

// Global variables for tracking drag events
let isDragging = false, startY, startHeight;

// Show the bottom sheet, hide body vertical scrollbar, and call updateSheetHeight
const showBottomSheet = () => {
    bottomSheet.classList.add("show");
    document.body.style.overflowY = "hidden";
    updateSheetHeight(50);
}

const updateSheetHeight = (height) => {
    sheetContent.style.height = `${height}vh`; //updates the height of the sheet content
    // Toggles the fullscreen class to bottomSheet if the height is equal to 100
    bottomSheet.classList.toggle("fullscreen", height === 100);
}

// Hide the bottom sheet and show body vertical scrollbar
const hideBottomSheet = () => {
    bottomSheet.classList.remove("show");
    document.body.style.overflowY = "auto";
}

// Sets initial drag position, sheetContent height and add dragging class to the bottom sheet
const dragStart = (e) => {
    isDragging = true;
    startY = e.pageY || e.touches?.[0].pageY;
    startHeight = parseInt(sheetContent.style.height);
    bottomSheet.classList.add("dragging");
}

// Calculates the new height for the sheet content and call the updateSheetHeight function
const dragging = (e) => {
    if(!isDragging) return;
    const delta = startY - (e.pageY || e.touches?.[0].pageY);
    const newHeight = startHeight + delta / window.innerHeight * 100;
    updateSheetHeight(newHeight);
}

// Determines whether to hide, set to fullscreen, or set to default 
// height based on the current height of the sheet content
const dragStop = () => {
    isDragging = false;
    bottomSheet.classList.remove("dragging");
    const sheetHeight = parseInt(sheetContent.style.height);
    sheetHeight < 25 ? hideBottomSheet() : sheetHeight > 75 ? updateSheetHeight(100) : updateSheetHeight(50);
}

dragIcon.addEventListener("mousedown", dragStart);
document.addEventListener("mousemove", dragging);
document.addEventListener("mouseup", dragStop);

dragIcon.addEventListener("touchstart", dragStart);
document.addEventListener("touchmove", dragging);
document.addEventListener("touchend", dragStop);

sheetOverlay.addEventListener("click", hideBottomSheet);
showModalBtn.addEventListener("click", showBottomSheet);

In short, we started by setting up a basic button and modal container. Using CSS, we make them visually appealing while ensuring the modal remains hidden initially. Lastly, we implemented JavaScript functionality to allow for the show/hide feature of the modal and enabled the ability to drag it up or down as desired.

Conclusion and Final Words

In conclusion, by following the step-by-step instructions and the provided code snippets, you have learned how to create an interactive bottom sheet modal that slides from the bottom and enhances the user experience on your web projects.

If you want to further improve your web development skills, I encourage you to try creating other types of modals or other interactive web components. There are many resources available on this website that can help you learn more about web development.

As an example, you could try creating a draggable card slider in HTML, CSS, and JavaScript, where you’ll learn to create your own infinite card slider with autoplay functionality that also works on your phone.

If you encounter any difficulties while creating your bottom sheet modal or your code is not working as expected, you can download the source code files for this bottom sheet for free by clicking the Download button. You can also view a live demo of it by clicking the View Live button.

]]>
https://www.codingnepalweb.com/draggable-bottom-sheet-modal-html-css-javascript/feed/ 0