You are viewing limited content. For full access, please sign in.

Question

Question

toTitleCase JavaScript Issue

asked on October 25, 2024

We like to use the toTitleCase JavaScript code to auto capitalize only the first letter on each word entered into a Form field. However, the code isn't perfect for names like McCowan or names with dashes in them where there is another capitalized character in the name. The seconded capitalized letter in the name is automatically changed to lower case. So for example, McCowan is changed to Mccowan. Is there JavaScript that only auto capitalizes the first letter of a word?

This is the current JavaScript code we have:

  $('.toTitleCase input').change(function() {
    var sInput = $(this).val().toLowerCase();
    var words = sInput.split(" ");
    for (let i = 0; i < words.length; i++) {
      words[i] = words[i][0].toUpperCase() + words[i].substr(1);
    }
    $(this).val(words.join(" "));
  });

Before Tabbing Out:

After Tabbing Out:

0 0

Answer

SELECTED ANSWER
replied on October 29, 2024

Here is a more reliable method.  It first checks for spaces and splits into individual words and then processes each word.  If the word has a hyphen, it splits on the hyphen and processes the 2 parts individually, otherwise it just processes the word.

$(document).ready(function () {
  $('.toTitleCase input').change(function() {
    // get input as lower case
    var sInput = $(this).val().toLowerCase();
    // split on space
    var words = sInput.split(" ");
    // process each individual word
    for (let i = 0; i < words.length; i++) {
      // process words with hyphen
      if (words[i].indexOf('-') > -1) {
        // text up to and including hyphen
        var w1 = words[i].slice(0, words[i].indexOf('-') + 1);
        // process if not blank
        if (w1) {
          w1 = procText(w1);
        }
        // text after the hyphen
        var w2 = words[i].slice(words[i].indexOf('-') + 1);
        // process if not blank
        if (w2) {
          w2 = procText(w2);
        }
        // put processed text back together
        words[i] = w1 + w2;
      } else {
        // process unhyphenated words
        words[i] = procText(words[i]);
      }
    }
    // put processed text back together
    sInput = words.join(" ");
    // Set the field value
    $(this).val(sInput);
  });
  
  function procText(txt) {
    // variable to track if we split the word
    var addSpace = false;
    // check if startes with mc
    if (txt.startsWith("mc")){
      // set variable that we split the word
      addSpace = true;
      // add space after first 2 characters
      txt = txt.slice(0, 2) + " " + txt.slice(2);
    }
    // check if startes with o'
    if (txt.startsWith("o'")){
      // set variable that we split the word
      addSpace = true;
      // add space after first 2 characters
      txt = txt.slice(0, 2) + " " + txt.slice(2);
    }
    // split on space
    var words = txt.split(" ");
    // process each part
    for (let i = 0; i < words.length; i++) {
      words[i] = words[i][0].toUpperCase() + words[i].substr(1);
    }
    // update text with processed data
    txt = words.join(" ");
    // check if need to remove space
    if (addSpace) {
      // remove space
      txt = txt.replace(/ /, '');
    }
    // returned processed data
    return txt;
  }
});

 

2 0

Replies

replied on October 25, 2024

The problem here is that you are making the whole string lower case (line 2 of your code) before it comes back and makes the first letter upper case.  So McCowan becomes mccowan and then becomes Mccowan. 

If you edited line 2 to remove the function to make the string lower case, then McCowan would still work and so would mcCowan to become McCowan - but unfortunately, MCCOWAN would still be MCCOWAN.

There really isn't any way for the script to know that McCowan should have a capital C but Johnson shouldn't have a capital H for example - unless you specifically code for names that start with Mc.

3 0
replied on October 28, 2024 Show version history

@████████, you can build in if statements to handle certain cases.  In the code below, I handle if the input starts with mc or o'

Edit: added handling for hyphenated words

$(document).ready(function () {
  $('.toTitleCase input').change(function() {
    var addSpace = false;
    var sInput = $(this).val().toLowerCase();
    if (sInput.startsWith("mc")){
      addSpace = true;
      sInput = sInput.slice(0, 2) + " " + sInput.slice(2);
    }
    if (sInput.startsWith("o'")){
      addSpace = true;
      sInput = sInput.slice(0, 2) + " " + sInput.slice(2);
    }
    if (sInput.indexOf('-') > -1)
    {
      addSpace = true;
      sInput = sInput.slice(0, sInput.indexOf('-') + 1) + " " + sInput.slice(sInput.indexOf('-') + 1);
    }
    var words = sInput.split(" ");
    for (let i = 0; i < words.length; i++) {
      words[i] = words[i][0].toUpperCase() + words[i].substr(1);
    }
    sInput = words.join(" ");
    if (addSpace) {
      sInput = sInput.replace(/ /, '');
    }
    $(this).val(sInput);
  });
});

 

3 0
SELECTED ANSWER
replied on October 29, 2024

Here is a more reliable method.  It first checks for spaces and splits into individual words and then processes each word.  If the word has a hyphen, it splits on the hyphen and processes the 2 parts individually, otherwise it just processes the word.

$(document).ready(function () {
  $('.toTitleCase input').change(function() {
    // get input as lower case
    var sInput = $(this).val().toLowerCase();
    // split on space
    var words = sInput.split(" ");
    // process each individual word
    for (let i = 0; i < words.length; i++) {
      // process words with hyphen
      if (words[i].indexOf('-') > -1) {
        // text up to and including hyphen
        var w1 = words[i].slice(0, words[i].indexOf('-') + 1);
        // process if not blank
        if (w1) {
          w1 = procText(w1);
        }
        // text after the hyphen
        var w2 = words[i].slice(words[i].indexOf('-') + 1);
        // process if not blank
        if (w2) {
          w2 = procText(w2);
        }
        // put processed text back together
        words[i] = w1 + w2;
      } else {
        // process unhyphenated words
        words[i] = procText(words[i]);
      }
    }
    // put processed text back together
    sInput = words.join(" ");
    // Set the field value
    $(this).val(sInput);
  });
  
  function procText(txt) {
    // variable to track if we split the word
    var addSpace = false;
    // check if startes with mc
    if (txt.startsWith("mc")){
      // set variable that we split the word
      addSpace = true;
      // add space after first 2 characters
      txt = txt.slice(0, 2) + " " + txt.slice(2);
    }
    // check if startes with o'
    if (txt.startsWith("o'")){
      // set variable that we split the word
      addSpace = true;
      // add space after first 2 characters
      txt = txt.slice(0, 2) + " " + txt.slice(2);
    }
    // split on space
    var words = txt.split(" ");
    // process each part
    for (let i = 0; i < words.length; i++) {
      words[i] = words[i][0].toUpperCase() + words[i].substr(1);
    }
    // update text with processed data
    txt = words.join(" ");
    // check if need to remove space
    if (addSpace) {
      // remove space
      txt = txt.replace(/ /, '');
    }
    // returned processed data
    return txt;
  }
});

 

2 0
replied on October 29, 2024

And here is for the new designer.  Just make sure to update the fieldID.

 

LFForm.onFieldBlur(function() {LFForm.setFieldValues({fieldId: 1},toTitleCase(LFForm.getFieldValues({fieldId: 1})))},{fieldId: 1});

function toTitleCase(sInput) {
  var words = sInput.split(" ");
  for (let i = 0; i < words.length; i++) {
    if (words[i].indexOf('-') > -1) {
      var w1 = words[i].slice(0, words[i].indexOf('-') + 1);
      if (w1) {
        w1 = procText(w1);
      }
      var w2 = words[i].slice(words[i].indexOf('-') + 1);
      if (w2) {
        w2 = procText(w2);
      }
      words[i] = w1 + w2;
    } else {
      words[i] = procText(words[i]);
    }
  }
  sInput = words.join(" ");
  return sInput;
}
  
function procText(txt) {
  var addSpace = false;
  if (txt.startsWith("mc")){
    addSpace = true;
    txt = txt.slice(0, 2) + " " + txt.slice(2);
  }
  if (txt.startsWith("o'")){
    addSpace = true;
    txt = txt.slice(0, 2) + " " + txt.slice(2);
  }
  var words = txt.split(" ");
  for (let i = 0; i < words.length; i++) {
    words[i] = words[i][0].toUpperCase() + words[i].substr(1);
  }
  txt = words.join(" ");
  if (addSpace) {
    txt = txt.replace(/ /, '');
  }
  return txt;
}

 

2 0
replied on November 6, 2024

Excellent! This updated JavaScript code working well Bert. Thank you!

1 0
You are not allowed to follow up in this post.

Sign in to reply to this post.