Solution 1 :

I think i have a solution for you, you can create a ‘template’ and retrieve that template with jquery.
If you put this in your main html file

<script id="hidden-template" type="text/x-custom-template">
    <div class="main-middle-column-wrapper">
  <div class="main-middle-column-container">
    <div class="main-middle-column">
      <div class="tweet-pic-wrapper">
        <div class="tweet-pic-container">
          <img src="Picture of the Moon.jpeg" class="tweet-pic" alt="Picture of the moon.">
        </div>
      </div>
      <div class="title-account-time">
        <span class="msg-title">My Twitter</span>
        <span class="msg-acc-name">@username</span>
        <div class="msg-date">date/time</div>
      </div>
      <div class="tweet-msg">
        this is a story all about how my life got flipped turned upside down and id like to take a minute and just sit right there id like to tell you how i became a prince in a town called belair.
      </div>
    </div>
  </div>
</div>
</script>

You can get the content with jquery like this

var template = $('#hidden-template').html();

Now you have your html ‘template’ in your javascipt, now your can create more than one of these elements.

$('#target').append(template);

Or you can use a better/simpler method with plain javascript

const card = ({ img_alt, img_src, title, username, date, msg }) => `
  <div class="main-middle-column-wrapper">
  <div class="main-middle-column-container">
    <div class="main-middle-column">
      <div class="tweet-pic-wrapper">
        <div class="tweet-pic-container">
          <img src="${img_src}" class="tweet-pic" alt="${img_alt}">
        </div>
      </div>
      <div class="title-account-time">
        <span class="msg-title">${title}</span>
        <span class="msg-acc-name">@${username}</span>
        <div class="msg-date">${date}</div>
      </div>
      <div class="tweet-msg">${msg}</div>
    </div>
  </div>
</div>
`;

You can use this as a function to create your elements dynamically with all kinds of data.

Solution 2 :

Create a function that returns a Template Literal with the desired HTML markup structure. Map your tweets and insert them into a target parent:

const tweets = [
  {
    _id: 321,
    pic: "https://placehold.it/80x80/0bf",
    title: "My Twitter",
    name: "@username",
    date: "2020-01-18",
    msg: "this is a story"
  },
  {
    _id: 231,
    pic: "https://placehold.it/80x80/f0b",
    title: "My alter Twitter",
    name: "@user",
    date: "2020-01-19",
    msg: "Again, another story"
  }
];

const newTweet = tweet => `<div class="main-middle-column">
    <div class="tweet-pic-wrapper">
      <div class="tweet-pic-container">
        <img src="${tweet.pic}" class="tweet-pic" alt="${tweet.title}">
      </div>
    </div>
    <div class="title-account-time">
      <span class="msg-title">${tweet.title}</span>
      <span class="msg-acc-name">${tweet.name}</span>
      <div class="msg-date">${tweet.date}</div>
    </div>
    <div class="tweet-msg">${tweet.msg}</div>
  </div>`; 
  
const populateNewTweets = (tweets, parent) => {
  if (!tweets.length) return;
  $('<div>', {
    class: 'main-middle-column-container',
    appendTo: parent,
    append: tweets.map(newTweet)
  });
};

populateNewTweets(tweets, '.main-middle-column-wrapper');
.main-middle-column-wrapper{
  display: flex;
  flex-direction: column;
  width: 49%;
}

.main-middle-column-container{
  width: 100%;
}

.main-middle-column{
  font-family: "Helvetica Neue", Helvetica, Arial ,sans-serif;
  font-size: 14px;
  height: auto;
  width: 100%;
  background-color: white;
  padding: 9px 12px;
  z-index: -2;
  box-shadow: 0 0 2px 0 lightgray;
  position: relative;
}

.main-middle-column:hover{
  background-color: hsl(200, 23%, 96%);
}

.tweet-pic-wrapper{
  position: absolute;
  top: 5px;
}

.tweet-pic-container{
  position: relative;
  height: 48px;
  width: 48px;
  border: 3px solid transparent;
  border-radius: 100%;
  overflow: hidden;
  z-index: 1;
  display: inline-block;
}

.tweet-pic{
  position: absolute;
  margin: 0 auto;
  height: 100%;
  left: -6px;
  width: auto;
}

.title-account-time{
  margin-left: 55px;
}

.msg-title{
  font-weight: bold;
}

.msg-acc-name{
  color: #657786;
}

.msg-acc-name:hover{
  cursor: pointer;
}

.msg-date{
  color: #657786;
  margin-top: 1px;
}

.tweet-msg{
  margin-left: 55px;
  margin-top: 5px;
}
<div class="main-middle-column-wrapper"></div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

Solution 3 :

The best solution to this would be to use some kind of templating engine, for example Mustache. If that however is out of the question, the solution to your problem would be something like this:

jQuery(document).ready(function() {
     /* this should store the container templates clone in a variable */
     mainMiddleContainerTemplate = jQuery(".main-middle-column-container").get(0).clone();

     /* this should remove every main middle container from the view, in case
        you have multiple containers that are not templates, consider adding
        an additional class to your template container */
     jQuery(".main-middle-column-container").remove();
});

function addNewContainer(containerData) {
    var newContainer = mainMiddleContainerTemplate.clone();

    /** add and replace all the data needed on the newContainer **/
    newContainer.find('.message-title').html(containerData.title);
    newContainer.find('.msg-acc-name').html(containerData.accountName);
    ....

    jQuery(".main-middle-container-wrapper").append(newContainer);
}

But still, I would advice you, to use a templating engine for these kinds of stuff.

Solution 4 :

$('.main-middle-column-container').first().clone().appendTo('.main-middle-column-wrapper');

The key is to select only one element to be cloned. First is as good as any other.

Problem :

I created a div element called main-middle-column-container in my HTML and styled it with CSS. Basically, main-middle-column-container will create a twitter-like message box that will have a name, date/time, and the message.

I want to reuse main-middle-column-container and all the code inside of it with jQuery so that when new data comes in, it will use a fresh main-middle-column-container as a template to add in the new values (like how twitter would work). When new data comes in, @username, date/time, and This is a random message. #random will be replaced with the incoming data or leave the elements empty and have the new data fill it in.

I thought about using $('.main-middle-column-container').clone().appendTo('.main-middle-column-wrapper'); but that will keep double cloning it (1 box -> 2 box -> 4 box -> 8 box…) instead of cloning it once. I also have an issue of getting rid of main-middle-column-container before I receive any data because I don’t want an empty box on the website I am trying to create. I want main-middle-column-container to be created right when I get some kind of data/message.

CSS and HTML (message box)

.main-middle-column-wrapper{
  display: flex;
  flex-direction: column;
  width: 49%;
}

.main-middle-column-container{
  width: 100%;
}

.main-middle-column{
  font-family: "Helvetica Neue", Helvetica, Arial ,sans-serif;
  font-size: 14px;
  height: auto;
  width: 100%;
  background-color: white;
  padding: 9px 12px;
  z-index: -2;
  box-shadow: 0 0 2px 0 lightgray;
  position: relative;
}

.main-middle-column:hover{
  background-color: hsl(200, 23%, 96%);
}

.tweet-pic-wrapper{
  position: absolute;
  top: 5px;
}

.tweet-pic-container{
  position: relative;
  height: 48px;
  width: 48px;
  border: 3px solid transparent;
  border-radius: 100%;
  overflow: hidden;
  z-index: 1;
  display: inline-block;
}

.tweet-pic{
  position: absolute;
  margin: 0 auto;
  height: 100%;
  left: -6px;
  width: auto;
}

.title-account-time{
  margin-left: 55px;
}

.msg-title{
  font-weight: bold;
}

.msg-acc-name{
  color: #657786;
}

.msg-acc-name:hover{
  cursor: pointer;
}

.msg-date{
  color: #657786;
  margin-top: 1px;
}

.tweet-msg{
  margin-left: 55px;
  margin-top: 5px;
}
<div class="main-middle-column-wrapper">
  <div class="main-middle-column-container">
    <div class="main-middle-column">
      <div class="tweet-pic-wrapper">
        <div class="tweet-pic-container">
          <img src="Picture of the Moon.jpeg" class="tweet-pic" alt="Picture of the moon.">
        </div>
      </div>
      <div class="title-account-time">
        <span class="msg-title">My Twitter</span>
        <span class="msg-acc-name">@username</span>
        <div class="msg-date">date/time</div>
      </div>
      <div class="tweet-msg">
        This is a random message. #random
      </div>
    </div>
  </div>
</div>

Comments

Comment posted by J. GarcĂ­a

The thing is you are setting a

Comment posted by Autex

Great idea with the card function. In case any are wondering like I was how to call such a function:

By