Home > Software engineering >  How to split across multiple divs while keep the formating, then addClass to divs over max character
How to split across multiple divs while keep the formating, then addClass to divs over max character

Time:08-24

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 >Samsung</div>
    <div >Galaxy</div>
    <div >S20 5G</div>
    <div >S</div>
    <div >Black</div>
    <div >(345)</div>
    <div >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.

CodePudding user response:

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>

CodePudding user response:

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 = [];
  [...new Set(html.trim().split(' '))].forEach(word => {
    response.push(`<div >${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 => {
    response.push(`<div >${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>

  • Related