Create a Twitter Edit Button using JavaScript

Web Development

In this web development tutorial I am going to create the Twitter edit button using HTML CSS and JavaScript, in order to create new tweets and also be able to edit ther content.

Or at least what I would imagine the tweeter edit button should look like and how it should work.

The main focus of this tutorial is to create the tweeter edit button and make it functional using javascript, this means that I will not focus so much on the CSS part and I would encourage you to pause the video and get all the css from the link down below and then come back to the video.

Creating the project HTML and CSS files

To start out lets create an empty folder, name it tweeter edit button and in here create the index.html file.

Next create the HTML5 DOCTYPE using shift + !, create and link up the style.css file and git the project the title of “Twitter Edit Button”, and we are good to go.

Some basic styling and a general reset for the complete CSS

* {
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
}

:root {
  --tweetLight: #1d9bf0;
  --tweetDark: #147dc2;
  --tweetDisabled: #8bcdf9;
  --hover: #eeefef;
  --lightGray: #536471;
}

body {
  display: grid;
  grid-template-columns: 80px 1fr;
}

Creating the tweeter menu / sidebar using HTML and CSS

Next up we can create the sidebar navigation using html and css. Aldo this will only have an astatic effect and no functionality, the procces will be Extremely simple and we will use Font Awesome. In order to use Font Awesome you need to include the cdn by copying in the link in your head, all the links are provided …

Font Awesome CDN Link

After the Font Awesome CDN is linked up you can start using the Font Awesome icons.

Now lets create the navigation bar…

 <nav class="navigation">
      <i class="fa-brands fa-twitter"></i>
      <i class="fa-solid fa-house"></i>
      <i class="fa-solid fa-magnifying-glass"></i>
      <i class="fa-solid fa-bell"></i>
      <i class="fa-solid fa-envelope"></i>
      <i class="fa-solid fa-bookmark"></i>
      <i class="fa-solid fa-file-lines"></i>
      <i class="fa-solid fa-ellipsis"></i>
      <i class="fa-solid fa-feather-pointed"></i>
</nav>


/* Navigation */

.navigation {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100vh;
  border-right: 1px solid var(--hover);
}
.navigation i {
  font-size: 1.5rem;
  margin: 1rem 2rem;
  padding: 1rem;
}
.navigation i:hover {
  border-radius: 50%;
  cursor: pointer;
  background-color: var(--hover);
}
.navigation .fa-twitter {
  color: var(--tweetLight);
}
.navigation .fa-feather-pointed {
  background-color: var(--tweetLight);
  color: #fff;
  padding: 1rem;
  border-radius: 50%;
}

.navigation .fa-feather-pointed:hover {
  background-color: var(--tweetDark);
  border-radius: 50%;
}

Create the Tweeter main container

The main Tweeter container will container the exiting tweet and also the posibility to create new tweets and display them.

   <main class="container">
    <h4>Home</h4>
   </main>

/* Main Container */
.container {
  width: 500px;
  border: 1px solid var(--hover);
}


/* Title */
h4 {
  padding: 1rem;
}

Create a new tweet & tweet button using html and css

New tweet HTML

<header class="new-tweet">
        <div class="user-img"></div>
        <form id="addTweet">
          <input
            type="text"
            class="tweet-text-content"
            placeholder="What's happening?"
          />
          <button type="submit" class="tweet-btn" disabled>Tweet</button>
        </form>
</header>

New tweet CSS

/* New Tweet */

.new-tweet {
  display: grid;
  grid-template-columns: 1fr 9fr;
  align-items: center;
  padding: 1rem;
  margin-bottom: 4rem;
}

.user-img {
  height: 50px;
  width: 50px;
  border-radius: 50%;
  margin-right: 1rem;
  background-image: url("../Vanila/img/Norbert-menyhart-logo.jpeg");
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  position: relative;
}
#addTweet {
  display: flex;
  justify-content: space-between;
}
.tweet-text-content {
  border: none;
  outline: none;
  font-size: 1rem;
}

/* Tweet Button */

.tweet-btn {
  background-color: var(--tweetLight);
  color: #fff;
  border-radius: 25px;
  padding: 0.45rem 1rem;
  font-weight: 600;
  border: none;
  min-width: 60px;
  cursor: pointer;
}
.tweet-btn:disabled {
  background-color: var(--tweetDisabled);
}
.tweet-btn:disabled:hover {
  background-color: var(--tweetDisabled);
  cursor: default;
}
.tweet-btn:hover {
  background-color: var(--tweetDark);
}

JS

It is time to make possible to tweet, for this we ar going to make the tweet button interact with out typing. This means that the tweet button will remaine disabled until we start typing in the input.

Start by creating a javascript file, name it tweet.js and link it up to your HTML file down right before your closing body tag.

Now with the help of javascript grap on to the DOM elements by using element selectors like, querySelector , querySelectorAll, getElementById.

const twTxtContent = document.querySelector(".tweet-text-content");
const twButton = document.querySelector(".tweet-btn");
let tweetList = document.querySelectorAll(".tweet");
const addTweet = document.getElementById("addTweet");
const tweets = document.querySelector(".tweets");

twTxtContent.onkeyup = () => {
  if (twTxtContent.value === "") {
    twButton.disabled = true;
  } else {
    twButton.disabled = false;
  }
};

Editing existing tweet

Your tweets, old and new once, will be displayed in al ul with the class of tweets witch will contains multiple li with the class of tweet.

Tweet HTML

 <ul class="tweets">
        <li class="tweet">
          <div class="user-details">
            <div class="user-img"></div>
            <div class="tweet-details">
              <div class="user">
                <span class="user-name">NorbertBM</span>
                <span class="user-handel">@NBMenyhart</span>
                <span class="tweet-age">. 4h</span>
              </div>
              <input
                type="text"
                class="tweet-text-content"
                value="My first tweet in this"
                readonly
              />
              <i class="fa-solid fa-pen-to-square"></i>
            </div>
          </div>
          <div class="interactions">
            <small class="interection"
              ><i class="fa-solid fa-comment"></i> <span>71</span></small
            >
            <small class="interection"
              ><i class="fa-solid fa-retweet"></i><span>23</span></small
            >
            <small class="interection"
              ><i class="fa-regular fa-heart"></i><span>23</span></small
            >
            <small class="interection"
              ><i class="fa-solid fa-upload"></i
            ></small>
          </div>
        </li>
 </ul>

Tweet CSS



.tweet {
  width: 100%;
  padding: 1rem;

  border: 1px solid #eff3f4;
  cursor: pointer;
}
.tweet:hover {
  background-color: var(--hover);
}

.user-details {
  width: 100%;
  display: flex;
}
.user {
  width: 100%;
  margin-bottom: 0.5rem;
}
.user-name {
  font-weight: 600;
  margin-right: 0.5rem;
}
.user-handel {
  color: #5d6d79;
}
.fa-ellipsis {
  color: var(--lightGray);
  justify-self: flex-end;
}
.fa-ellipsis:hover {
  background-color: var(--tweetDisabled);
  border-radius: 50%;
  /* height: 20px; */
}
.interactions {
  margin-left: 4rem;
  display: flex;
  justify-content: space-between;
  color: #5d6d79;
}

.interactions i {
  margin-right: 0.5rem;
}

/* Edit */

.fa-pen-to-square:hover {
  color: orangered;
}

.fa-circle-check {
  color: green;
}


// Create new tweet and add it to the DOM

let newTweetContent = document.createElement("div");

addTweet.onsubmit = (e) => {
  e.preventDefault();

  newTweetContent.innerHTML = `
      <div class="tweet">
      <div class="user-details">
        <div class="user-img"></div>
        <div class="tweet-details">
          <div class="user">
            <span class="user-name">NorbertBM</span>
            <span class="user-handel">@NBMenyhart</span>
            <span class="tweet-age"></span>
          </div>

          <input type="text" class="tweet-text-content" value="${twTxtContent.value}" readonly />


          <i class="fa-solid fa-pen-to-square"></i>
        </div>

      </div>
      <div class="interactions">
        <small class="interection"
          ><i class="fa-solid fa-comment"></i> <span></span></small
        >
        <small class="interection"
          ><i class="fa-solid fa-retweet"></i><span></span></small
        >
        <small class="interection"
          ><i class="fa-regular fa-heart"></i><span></span></small
        >
        <small class="interection"
          ><i class="fa-solid fa-upload"></i
        ></small>
      </div>
    </div>

      `;
  // tweetList = [...tweetList, newTweetContent];

  twTxtContent.value = "";
  twButton.disabled = true;
  tweets.appendChild(newTweetContent);
};


Create new tweet edit button using JavaScript

This is where we are going to create a new tweet and also make the tweet editable using the edit button by changing the input content from readonly to editable using javascript.


// Make tweet editable

tweets.onmouseenter = () => {
  document.querySelectorAll(".fa-pen-to-square").forEach(
    (edit) =>
      (edit.onclick = (e) => {
        let text = e.target.previousElementSibling;
        if (e.target.classList.contains("fa-pen-to-square")) {
          e.target.classList.replace("fa-pen-to-square", "fa-circle-check");
          text.style.color = "var(--lightGray)";
          text.readOnly = false;
        } else {
          e.target.classList.replace("fa-circle-check", "fa-pen-to-square");
          text.style.color = "initial";
          text.readOnly = true;
        }
      })
  );
};

Video Tutorial

Check out the complete video tutorial for this web development project in order to get a more indeath understanding of the project.

Complete Code for The Project

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
      integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    />
    <link rel="stylesheet" href="style.css" />
    <title>Twitter edit button</title>
  </head>
  <body>
    <nav class="navigation">
      <i class="fa-brands fa-twitter"></i>
      <i class="fa-solid fa-house"></i>
      <i class="fa-solid fa-bell"></i>
      <i class="fa-solid fa-envelope"></i>
      <i class="fa-solid fa-bookmark"></i>
      <i class="fa-solid fa-file-lines"></i>
      <i class="fa-solid fa-ellipsis"></i>
      <i class="fa-solid fa-feather-pointed"></i>
    </nav>
    <main class="container">
      <h4>Home</h4>
      <header class="new-tweet">
        <div class="user-img"></div>
        <form id="addTweet">
          <input
            type="text"
            class="tweet-text-content"
            placeholder="What's happening"
          />
          <button type="submit" class="tweet-btn" disabled>Tweet</button>
        </form>
      </header>
      <ul class="tweets">
        <li class="tweet">
          <div class="user-details">
            <div class="user-img"></div>
            <div class="tweet-detail">
              <div class="user">
                <span class="user-name">NorbertBM</span>
                <span class="user-handel">@NBMenyhart</span>
                <span class="tweet-age">. 4h</span>
              </div>
              <input
                type="text"
                class="tweet-text-content"
                value="My first tweet"
                readonly
              />
              <i class="fa-solid fa-pen-to-square"></i>
            </div>
          </div>
          <div class="interactions">
            <small class="interection"
              ><i class="fa-solid fa-comment"></i> <span>71</span></small
            >
            <small class="interection"
              ><i class="fa-solid fa-retweet"></i><span>23</span></small
            >
            <small class="interection"
              ><i class="fa-regular fa-heart"></i><span>23</span></small
            >
            <small class="interection"
              ><i class="fa-solid fa-upload"></i
            ></small>
          </div>
        </li>
      </ul>
    </main>
    <script src="tweet.js"></script>
  </body>
</html>

CSS

* {
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
}

:root {
  --tweetLight: #1d9bf0;
  --tweetDark: #147dc2;
  --tweetDisabled: #8bcdf9;
  --hover: #eeefef;
  --lightGray: #536471;
}

/* Main Container */
body {
  display: grid;
  grid-template-columns: 80px 1fr;
}
.container {
  width: 500px;
  border: 1px solid var(--hover);
}

/* Navigation */

.navigation {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100vh;
  border-right: 1px solid var(--hover);
}
.navigation i {
  font-size: 1.5rem;
  margin: 1rem 2rem;
  padding: 1rem;
}
.navigation i:hover {
  border-radius: 50%;
  cursor: pointer;
  background-color: var(--hover);
}
.navigation .fa-twitter {
  color: var(--tweetLight);
}
.navigation .fa-feather-pointed {
  background-color: var(--tweetLight);
  color: #fff;
  padding: 1rem;
  border-radius: 50%;
}

.navigation .fa-feather-pointed:hover {
  background-color: var(--tweetDark);
  border-radius: 50%;
}

/* Title */
h4 {
  padding: 1rem;
}

/* New Tweet */

.new-tweet {
  display: grid;
  grid-template-columns: 1fr 9fr;
  align-items: center;
  padding: 1rem;
  margin-bottom: 4rem;
}

.user-img {
  height: 50px;
  width: 50px;
  border-radius: 50%;
  margin-right: 1rem;
  background-image: url("./img/Norbert-menyhart-logo.jpeg");
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  position: relative;
}
#addTweet {
  display: flex;
  justify-content: space-between;
}
.tweet-text-content {
  border: none;
  outline: none;
  font-size: 1rem;
}

/* Tweet Button */

.tweet-btn {
  background-color: var(--tweetLight);
  color: #fff;
  border-radius: 25px;
  padding: 0.45rem 1rem;
  font-weight: 600;
  border: none;
  min-width: 60px;
  cursor: pointer;
}
.tweet-btn:disabled {
  background-color: var(--tweetDisabled);
}
.tweet-btn:disabled:hover {
  background-color: var(--tweetDisabled);
  cursor: default;
}
.tweet-btn:hover {
  background-color: var(--tweetDark);
}

.tweet {
  width: 100%;
  padding: 1rem;

  border: 1px solid #eff3f4;
  cursor: pointer;
}
.tweet:hover {
  background-color: var(--hover);
}

.user-details {
  width: 100%;
  display: flex;
}
.user {
  width: 100%;
  margin-bottom: 0.5rem;
}
.user-name {
  font-weight: 600;
  margin-right: 0.5rem;
}
.user-handel {
  color: #5d6d79;
}
.fa-ellipsis {
  color: var(--lightGray);
  justify-self: flex-end;
}
.fa-ellipsis:hover {
  background-color: var(--tweetDisabled);
  border-radius: 50%;
  /* height: 20px; */
}
.interactions {
  margin-left: 4rem;
  display: flex;
  justify-content: space-between;
  color: #5d6d79;
}

.interactions i {
  margin-right: 0.5rem;
}

/* Edit */

.fa-pen-to-square:hover {
  color: orangered;
}

.fa-circle-check {
  color: green;
}

JavaScript

Now lets create a javascript file.

You need to get all elements from the DOM. You can use querySelector or getElementById for ID selection.

const twTxtContent = document.querySelector(".tweet-text-content");
const twButton = document.querySelector(".tweet-btn");

const addTweet = document.getElementById("addTweet");
const tweets = document.querySelector(".tweets");

After you have your elements, you must now add to the twTxtContent a keyboard event. You can do this by either adding a event listener of keyup or or use the onkeyup on the element.

twTxtContent.onkeyup = () => {
  if (twTxtContent.value === "") {
    twButton.disabled = true;
  } else {
    twButton.disabled = false;
  }
};




let newTweetContent = document.createElement("div");

addTweet.onsubmit = (e) => {
  e.preventDefault();

  newTweetContent.innerHTML = `
 <li class="tweet">
          <div class="user-details">
            <div class="user-img"></div>
            <div class="tweet-detail">
              <div class="user">
                <span class="user-name">NorbertBM</span>
                <span class="user-handel">@NBMenyhart</span>
                <span class="tweet-age">. 4h</span>
              </div>
              <input
                type="text"
                class="tweet-text-content"
                value="${twTxtContent.value}"
                readonly
              />
              <i class="fa-solid fa-pen-to-square"></i>
            </div>
          </div>
          <div class="interactions">
            <small class="interection"
              ><i class="fa-solid fa-comment"></i> <span>71</span></small
            >
            <small class="interection"
              ><i class="fa-solid fa-retweet"></i><span>23</span></small
            >
            <small class="interection"
              ><i class="fa-regular fa-heart"></i><span>23</span></small
            >
            <small class="interection"
              ><i class="fa-solid fa-upload"></i
            ></small>
          </div>
        </li>

`;
  twTxtContent.value = "";
  twButton.disabled = true;
  tweets.appendChild(newTweetContent);
};

// Make tweet editable

tweets.onmouseenter = () => {
  console.log("Tweets");
  document.querySelectorAll(".fa-pen-to-square").forEach(
    (edit) =>
      (edit.onclick = (e) => {
        let text = e.target.previousElementSibling;

        if (e.target.classList.contains("fa-pen-to-square")) {
          e.target.classList.replace("fa-pen-to-square", "fa-circle-check");
          text.readOnly = false;
          text.style.color = "var(--lightGray)";
        } else {
          e.target.classList.replace("fa-circle-check", "fa-pen-to-square");
          text.readOnly = true;
          text.style.color = "initial";
        }
      })
  );
};

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.