Search code examples
javascriptinputtitle-case

Code that changes an input field to Title Case with exceptions


I know there are several variations of this here, but I cannot find one that is doing what I want. I need the text in an input field to be updated to Title Case prior to form submission either via onkeup, keydown or when clicking out of the field (or any similar method). Preferably as the text is inputed.

I also need some exceptions for words like and, the, in, but, on, to, etc. to be lowercase.

I still need any word to be capitalized at the beginning of the sentence. AND in an ideal world the script would always capitalize words such as USA, NATO, NFL, NASA, etc. (or just allow these to be input as is).

The field input HTML is

<input name="title" id="title" autocomplete="off" type="text" value="" class="dev-input aa-form-text">

It would be good if this was done via Javascript that I could place on the page (or external .JS file).


Solution

  • Something like this?

    const exceptions = ['and', 'the', 'in', 'but', 'on', 'to', 'a', 'an', 'for', 'nor', 'with'];
    const acronyms = ['USA', 'NATO', 'NFL', 'NASA'];
    
    const toTitleCase = (str) => {
      return str.split(' ').map((word, index) => {
        const lowerCaseWord = word.toLowerCase();
        if (acronyms.includes(word.toUpperCase())) {
          return word.toUpperCase();
        }
        if (exceptions.includes(lowerCaseWord) && index !== 0) {
          return lowerCaseWord;
        }
        return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
      }).join(' ');
    };
    
    const handleInput = (event) => {
      const inputField = event.target;
      const cursorPosition = inputField.selectionStart; // Save cursor position
      inputField.value = toTitleCase(inputField.value);
      inputField.setSelectionRange(cursorPosition, cursorPosition); // Restore cursor position
    };
    
    document.getElementById('title').addEventListener('input', handleInput);
    <input name="title" id="title" autocomplete="off" type="text" value="" class="dev-input aa-form-text">