skip to Main Content

Description

Currently, if the user pastes images multiple times to the chat input using the ‘ctrl’ and ‘v’ keys, they get stacked vertically. The chat input is right above the ‘run’ button. Above the chat input is where the loaded images are displayed.

Expected Behavior

Make the loaded multiple images get stacked horizontally(left to right) if the user pastes images multiple times to the chat input.

Current Behavior

Currently, loaded multiple images get stacked vertically.

Current state

HTML, CSS, JS

document.addEventListener('DOMContentLoaded', () => {
  const textInput = document.getElementById('textInput');
  const imageContainer = document.getElementById('imageContainer');
  const runButton = document.getElementById('runButton');

  textInput.addEventListener('paste', (event) => {
      const items = (event.clipboardData || window.clipboardData).items;
      for (const item of items) {
          if (item.type.indexOf('image') !== -1) {
              const file = item.getAsFile();
              const reader = new FileReader();
              reader.onload = (event) => {
                  displayImage(event.target.result);
              };
              reader.readAsDataURL(file);
              event.preventDefault();
          }
      }
  });

  function displayImage(src) {
      const imgContainer = document.createElement('div');
      imgContainer.classList.add('img-preview-container');
      
      const img = document.createElement('img');
      img.src = src;
      img.classList.add('img-preview');
      
      const removeButton = document.createElement('button');
      removeButton.classList.add('remove-button');
      removeButton.textContent = '✖';
      removeButton.addEventListener('click', () => {
          imgContainer.remove();
      });

      imgContainer.appendChild(img);
      imgContainer.appendChild(removeButton);
      imageContainer.appendChild(imgContainer);
  }

  runButton.addEventListener('click', () => {
      console.log('Run button clicked');
  });
});
body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #181818;
}

.chat-container {
    width: 80%;
    max-width: 800px;
    background-color: #2e2e2e;
    border-radius: 10px;
    padding: 10px;
    color: #fff;
    outline: 2px solid black; /* Added outline */
}

.input-container {
    width: 100%;
    min-height: 50px;
    padding: 10px;
    background-color: #1e1e1e;
    border: 1px solid #444;
    border-radius: 5px;
    outline: none;
    color: #fff;
    margin-bottom: 10px;
}

.image-container {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    width: 100%;
    padding: 10px;
    background-color: #1e1e1e;
    border: 1px solid #444;
    border-radius: 5px;
    min-height: 50px;
    margin-bottom: 10px;
}

.run-button {
    margin-top: 10px;
    padding: 10px;
    background-color: #3b82f6;
    border: none;
    border-radius: 5px;
    color: #fff;
    cursor: pointer;
}

.run-button:hover {
    background-color: #2563eb;
}

.img-preview-container {
    position: relative;
    display: inline-block;
}

.img-preview {
    max-width: 100%;
    border-radius: 5px;
}

.remove-button {
    position: absolute;
    top: 5px;
    right: 5px;
    background-color: #ff4d4d;
    border: none;
    border-radius: 50%;
    color: white;
    cursor: pointer;
    width: 20px;
    height: 20px;
    font-size: 12px;
    line-height: 20px;
    text-align: center;
    padding: 0;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Chat Input with Image Paste</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <div class="chat-container">
      <div class="image-container" id="imageContainer"></div>
      <div
        class="input-container"
        contenteditable="true"
        id="textInput"
        placeholder="Type something"
      ></div>
      <button class="run-button" id="runButton">Run</button>
    </div>
    <script src="script.js"></script>
  </body>
</html>

2

Answers


  1. Try adding the flex-direction:row attribute to your body tag and see if that changes anything

    Login or Signup to reply.
  2. The issue is your image divs are full 100% width by default, even thought they’re inline-block elements. You need to set the width of each one.

    In my example I did that with by setting th ewidth of each one dynamically based on how many images there are: ${100/all_images.length-10}%.

    I subtracted 10 additional pixels to account for padding and margin for this example instead of trying to calculate that dynamically.

    const all_images = imageContainer.querySelectorAll('.img-preview-container');
    all_images.forEach(img=>img.style.width=`${100/all_images.length-10}%`);
    
    document.addEventListener('DOMContentLoaded', () => {
      const textInput = document.getElementById('textInput');
      const imageContainer = document.getElementById('imageContainer');
      const runButton = document.getElementById('runButton');
    
      textInput.addEventListener('paste', (event) => {
          const items = (event.clipboardData || window.clipboardData).items;
          for (const item of items) {
              if (item.type.indexOf('image') !== -1) {
                  const file = item.getAsFile();
                  const reader = new FileReader();
                  reader.onload = (event) => {
                      displayImage(event.target.result);
                  };
                  reader.readAsDataURL(file);
                  event.preventDefault();
              }
          }
      });
    
      function displayImage(src) {
          const imgContainer = document.createElement('div');
          imgContainer.classList.add('img-preview-container');
          
          const img = document.createElement('img');
          img.src = src;
          img.classList.add('img-preview');
          
          const removeButton = document.createElement('button');
          removeButton.classList.add('remove-button');
          removeButton.textContent = '✖';
          removeButton.addEventListener('click', () => {
              imgContainer.remove();
          });
    
          imgContainer.appendChild(img);
          imgContainer.appendChild(removeButton);
          imageContainer.appendChild(imgContainer);
          
          const all_images = imageContainer.querySelectorAll('.img-preview-container');
          all_images.forEach(img=>img.style.width=`${100/all_images.length-10}%`);
      }
    
      runButton.addEventListener('click', () => {
          console.log('Run button clicked');
      });
    });
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        background-color: #181818;
    }
    
    .chat-container {
        width: 80%;
        max-width: 800px;
        background-color: #2e2e2e;
        border-radius: 10px;
        padding: 10px;
        color: #fff;
        outline: 2px solid black; /* Added outline */
    }
    
    .input-container {
        width: 100%;
        min-height: 50px;
        padding: 10px;
        background-color: #1e1e1e;
        border: 1px solid #444;
        border-radius: 5px;
        outline: none;
        color: #fff;
        margin-bottom: 10px;
    }
    
    .image-container {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        width: 100%;
        padding: 10px;
        background-color: #1e1e1e;
        border: 1px solid #444;
        border-radius: 5px;
        min-height: 50px;
        margin-bottom: 10px;
    }
    
    .run-button {
        margin-top: 10px;
        padding: 10px;
        background-color: #3b82f6;
        border: none;
        border-radius: 5px;
        color: #fff;
        cursor: pointer;
    }
    
    .run-button:hover {
        background-color: #2563eb;
    }
    
    .img-preview-container {
        position: relative;
        display: inline-block;
    }
    
    .img-preview {
        max-width: 100%;
        border-radius: 5px;
    }
    
    .remove-button {
        position: absolute;
        top: 5px;
        right: 5px;
        background-color: #ff4d4d;
        border: none;
        border-radius: 50%;
        color: white;
        cursor: pointer;
        width: 20px;
        height: 20px;
        font-size: 12px;
        line-height: 20px;
        text-align: center;
        padding: 0;
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Chat Input with Image Paste</title>
        <link rel="stylesheet" href="styles.css" />
      </head>
      <body>
        <div class="chat-container">
          <div class="image-container" id="imageContainer"></div>
          <div
            class="input-container"
            contenteditable="true"
            id="textInput"
            placeholder="Type something"
          ></div>
          <button class="run-button" id="runButton">Run</button>
        </div>
        <script src="script.js"></script>
      </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search