1

Here I am trying to wrap the selected value from the drop down by comparing length of the string. The code i am using applying for the first line. How can i apply the same logic by comparing the length of the string for second line to next line.Below is some example i am using , what if my Item.value.length = 81.

var selectedItemLength = 
    Math.round(((Item.bounds.width) / (state.style.fontSize * (0.512 * scale))) * (pfConstants.LINE_HEIGHT));
//Here selectedItemLength gives 32
if (selectedItemLength < Item.value.length) {
  Item.value = 
    Item.value.substring(0, selectedItemLength) 
      + "\n" 
      + Item.value.substring(selectedItemLength, Item.value.length);
}
arcyqwerty
  • 10,325
  • 4
  • 47
  • 84
Adam Gilly
  • 59
  • 1
  • 9
  • Reevaluate `Item.value.substring(selectedItemLength, Item.value.length);` using the same logic to split the second line, and then add the rest to the first line (will end like `blablabalbalabla\nblablablabal\n` so it's just rinse and repeat) – LordNeo Jun 10 '16 at 20:28
  • @LordNeo can we use for loop? as my value could be display maximum of 3 lines only. So, is it good practice to use a for loop If so, how can i use it? – Adam Gilly Jun 10 '16 at 20:47
  • Possible duplicate of [Split large string in n-size chunks in JavaScript](http://stackoverflow.com/questions/7033639/split-large-string-in-n-size-chunks-in-javascript) – Fabricator Jun 10 '16 at 22:05

1 Answers1

4

Note: A good CSS rule might solve your problem, no JS required. Look into the word-wrap property.

Moving on with the code, here's a few solutions.

First, I recommend isolating your concerns in separate functions. In your snippet, you reach into a few different things, like Item.bounds.width and Item.value. You're better off passing these to functions to operate on them and handing the result back to the object. So as I understand the core of your question, you want a function like:

function(str: string,
         chunkLength: number,
         delimiter: string = "\n",
         maxLines: number = 3) { /* code */ }

The function needs to:

  • Break str into chunks of given size
  • Take only as many chunks as allowed by line size
  • Join them all together with a delimiter

You would invoke this function in your above snippet:

Item.value = demoFunction(Item.value,selectedItemLength);

Keep in mind that as you asked it (and as I wrote my solutions), you ignore whitespace. This will break words or tokens apart with no regard for whitespace. This may not be desired. ie,

testFunction("teal mittens", 8) == "teal mit\ntens";

Imperative Solution

This is a stateful for loop, as you mentioned.

var demoImperative = function(str, chunkLength, delimiter = "\n", maxLines = 3) {
  var chunks = [];
  for (var index = 0; index < str.length && chunks.length < maxLines; index += chunkLength) {
    // NOTE: substr != substring. See https://stackoverflow.com/questions/3745515/what-is-the-difference-between-substr-and-substring
    chunks.push(str.substr(index, chunkLength));
  }
  return chunks.join(delimiter);
}

Messy, but it works. The for loop keeps moving through the str by index until out of string or lines. I chose not to build the string on the fly, since this means the loop would have to track the current line number as another variable and joining (without putting an extra \n on the end) is trickier.

RegExp Solution

This makes use of a trick I found on SO to split js strings by length.

var demoRegExp =  function(str, chunkLength, delimiter = "\n", maxLines = 3) {
  var regExp = new RegExp('.{1,'+chunkLength+'}', 'g');
  return str.match(regExp).slice(0,maxLines).join(delimiter);
}

Certainly terse, if a tad unclear. The .match() does the split, .slice() takes only the proper number of lines, and .join() brings the array back to a string.

Ramda Solution

This one uses Ramda.JS, a functional library that makes data transformation in js (what you're doing here) much simpler. I wrote this one for fun.

var demoRamda = function(str, chunkLength, delimiter = "\n", maxLines = 3) {
  return R.pipe(
    R.splitEvery(chunkLength),
    R.take(maxLines),
    R.join(delimiter)
  )(str);
}

Clear and simple, but this requires the ramda.js library. Unless you're doing this server-side (unlikely) including a huge utility library for this one action is overkill, so I would advise against this one.

Community
  • 1
  • 1
user01
  • 891
  • 7
  • 13