Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to add tags and normal text in same input box

I need to add tags and text in the same input box. The normal text can be delete a character at once. The tags which will be selected from a particular set of words which are pre defined will be deleted all at once. The normal text and tags will be on the same box.

The link to fiddle link So far I have tried to

document.querySelector('.selectable-icons').addEventListener('click', function(e) {
 
    document.querySelector('[contenteditable]').appendChild(e.target.cloneNode(true));
  
});


document.querySelector('div').addEventListener('keydown', function(event) {
    // Check for a backspace
    if (event.which == 8) {
        s = window.getSelection();
        r = s.getRangeAt(0)
        el = r.startContainer.parentElement
        // Check if the current element is the .label
        if (el.classList.contains('label')) {
            // Check if we are exactly at the end of the .label element
            if (r.startOffset == r.endOffset && r.endOffset == el.textContent.length) {
                // prevent the default delete behavior
                event.preventDefault();
                if (el.classList.contains('highlight')) {
                    // remove the element
                    el.remove();
                } else {
                    el.classList.add('highlight');
                }
                return;
            }
        }
    }
    event.target.querySelectorAll('span.label.highlight').forEach(function(el) { el.classList.remove('highlight');})
});
[contenteditable] {
  border: 1px solid #000;
  margin: 0.4em 0;
  line-height: 1.4em;
  -webkit-appearance: textfield;
  appearance: textfield;
}
img {
  vertical-align: top;
  max-height: 1.4em;
  max-width: 1.4em;
}
.selectable-icons img {
  cursor: pointer;
}

span.label.highlight {
    background: #E1ECF4;
    border: 1px dotted #39739d;
}

span.label  {
    background: #E1ECF4;
    border: 1px dotted #39739d;
}
<p>Just click on an icon to add it.</p>

<div class="custom-input">
  <div class="selectable-icons">
      <span class="label"> Tag </span> 
       <span class="label"> Tag 2 </span> 
      <span class="label">Tag 3</span>  
  </div>
  <div contenteditable="true">
    You can type here. Add an icon.
  </div>
</div>

add tags but the issue is when click on the tag it adds it to the text box and when I write text after that tag this all is added to same span of tag and Tag + Text all is deleted together rather I need text to be deleted one character at once and the tags all at once. Please suggest a better way to achieve this with textarea instead of div.

Note: If I change tag data in span which are also editable. Also reflects in the editable div of tags and text

like image 648
ser cha Avatar asked Oct 17 '22 07:10

ser cha


1 Answers

When the tag is added to the div, set its contenteditable attribute to false:

el.setAttribute('contenteditable', false);

I hope that solves your problem - see demo below:

document.querySelector('.selectable-icons').addEventListener('click', function(e) {
  var el = e.target.cloneNode(true);
  el.setAttribute('contenteditable', false);
  document.querySelector('[contenteditable]').appendChild(el);

});


document.querySelector('div').addEventListener('keydown', function(event) {
  // Check for a backspace
  if (event.which == 8) {
    s = window.getSelection();
    r = s.getRangeAt(0)
    el = r.startContainer.parentElement
    // Check if the current element is the .label
    if (el.classList.contains('label')) {
      // Check if we are exactly at the end of the .label element
      if (r.startOffset == r.endOffset && r.endOffset == el.textContent.length) {
        // prevent the default delete behavior
        event.preventDefault();
        if (el.classList.contains('highlight')) {
          // remove the element
          el.remove();
        } else {
          el.classList.add('highlight');
        }
        return;
      }
    }
  }
  event.target.querySelectorAll('span.label.highlight').forEach(function(el) {
    el.classList.remove('highlight');
  })
});
[contenteditable] {
  border: 1px solid #000;
  margin: 0.4em 0;
  line-height: 1.4em;
  -webkit-appearance: textfield;
  appearance: textfield;
}

img {
  vertical-align: top;
  max-height: 1.4em;
  max-width: 1.4em;
}

.selectable-icons img {
  cursor: pointer;
}

span.label.highlight {
  background: #E1ECF4;
  border: 1px dotted #39739d;
}

span.label {
  background: #E1ECF4;
  border: 1px dotted #39739d;
}
<p>Just click on an icon to add it.</p>

<div class="custom-input">
  <div class="selectable-icons">
    <span class="label"> Tag </span>
    <span class="label"> Tag 2 </span>
    <span class="label">Tag 3</span>
  </div>
  <div contenteditable="true">
    You can type here. Add an icon.
  </div>
</div>
like image 103
kukkuz Avatar answered Nov 03 '22 00:11

kukkuz