skip to Main Content

My code currently wraps each word with a div by splitting it with the space and adds a class which has a grey background.

I want to keep this styling, but set a character count. That at ‘26‘ if happens to be inside a word, it’ll choose to split before that word and add .overMax with an orange background to all words over the character limit.

Currently the words are:

Samsung Galaxy S20+5GS Black (345) Smartphone

Splitting at 26 would make it:

Samsung Galaxy S20+5G S Bl

Desired output:

Samsung Galaxy S20+5G S

Keep in mind all the .splitDIVtitle div’s should also remain around their current words.

Final HTML will look like this:

<div id="title-editable" contenteditable="true" data-size="-2">
    <div class="splitDIVtitle">Samsung</div>
    <div class="splitDIVtitle">Galaxy</div>
    <div class="splitDIVtitle">S20+5G</div>
    <div class="splitDIVtitle">S</div>
    <div class="splitDIVtitle overMax">Black</div>
    <div class="splitDIVtitle overMax">(345)</div>
    <div class="splitDIVtitle overMax">Smartphone</div>
</div>
// Find spaces, wrap words with div.splitDIVtitle
let get_gtTitle = document.getElementById("title-editable").textContent;
let split_gtTitle = get_gtTitle.split(' ');

// Removes any duplicates found (e.g in example Samung)
const notduplicates = split_gtTitle.filter((item, index) => index == split_gtTitle.indexOf(item) && item !== "");

const mainDiv = document.getElementById('title-editable');
mainDiv.innerText = ""
notduplicates.forEach(item => {
  const div = document.createElement("div")
  div.classList.add('splitDIVtitle');
  div.innerHTML = item;
  mainDiv.appendChild(div)
})

let length_GTEditableTitle = $("#gumtree-title-editable").text()
.length;
let length_GTSetMax = 26;
if (length_GTEditableTitle < length_GTSetMax) {
    // Add .overMax here if .splitDIVtitle falls 'within' or 'outside' of 26
    // Which would be: Samsung Galaxy S20+5G S Bl
    // Decided Output should be: Samsung Galaxy S20+5G S
    // This should be done without breaking the div.splitDIVtitle's that have been added
}
.splitDIVtitle {
  display: inline-block;
  background: #ccc;
  margin-right: 5px;
}
.overMax {
  background: orange !important;
}
#example { 
  padding-top: 30px 
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="title-editable" contenteditable="true" data-size="-2">
  Samsung Galaxy S20+5G Samsung S Black (345) Samsung Smartphone
</div>

How can I do this? I can do it without divs inside the divs. But keeping the styling/classes is what is killing me.

2

Answers


  1. Can you just keep track of the number of characters seen so far?

    let character_count = 0
    notduplicates.forEach(item => {
      ...
      character_count += (item.length + 1)
      if (character_count > 26) {
          div.classList.add('overMax');
      }
      ...
    })
    
    // Find spaces, wrap words with div.splitDIVtitle
    let get_gtTitle = document.getElementById("title-editable").textContent;
    let split_gtTitle = get_gtTitle.split(' ');
    
    // Removes any duplicates found (e.g in example Samung)
    const notduplicates = split_gtTitle.filter((item, index) => index == split_gtTitle.indexOf(item) && item !== "");
    
    const mainDiv = document.getElementById('title-editable');
    mainDiv.innerText = ""
    let character_count = 0
    notduplicates.forEach(item => {
      const div = document.createElement("div")
      div.classList.add('splitDIVtitle');
      character_count += (item.length + 1)
      if (character_count > 26) {
          div.classList.add('overMax');
      }
      div.innerHTML = item;
      mainDiv.appendChild(div)
    })
    .splitDIVtitle {
      display: inline-block;
      background: #ccc;
      margin-right: 5px;
    }
    .overMax {
      background: orange !important;
    }
    #example { 
      padding-top: 30px 
     }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="title-editable" contenteditable="true" data-size="-2">
      Samsung Galaxy S20+5G Samsung S Black (345) Samsung Smartphone
    </div>
    Login or Signup to reply.
  2. To do what you require you can loop through the array of words and keep a running count of the number of characters used in each entity within the array. If that count goes over the 26 character limit, then add the overMax class to the current div.

    // jQuery version
    $('#title-editable').html((i, html) => {
      let characterCount = 0;
      let response = [];
      console.log([...new Set(html.trim().split(' '))]);
      [...new Set(html.trim().split(' '))].forEach((word, i) => {
        response.push(`<div class="splitDIVtitle ${(characterCount + i > 26 ? 'overMax' : '')}">${word}</div>`)
        characterCount += word.length;
      });
      return response;
    });
    
    // Plain JS version
    /*
      let title = document.querySelector('#title-editable');
      let characterCount = 0;
      let response = [];
      [...new Set(title.innerHTML.trim().split(' '))].forEach((word, i) => {
        response.push(`<div class="splitDIVtitle ${(characterCount + i> 26 ? 'overMax' : '')}">${word}</div>`)
        characterCount += word.length;
      });
      title.innerHTML = response.join('');
    */
    .splitDIVtitle {
      display: inline-block;
      background: #ccc;
      margin-right: 5px;
    }
    
    .overMax {
      background: orange !important;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <div id="title-editable" contenteditable="true" data-size="-2">
      Samsung Galaxy S20+5G Samsung S Black (345) Samsung Smartphone
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search