8

1) I'm trying to apply the first letter in uppercase and the other as lowercase. If the user write in the input, it should automatically transform. Examples:

"isaac guilherme araújo" to "Isaac Guilherme Araújo"

"iSAAC guILHErme aRAÚJO" to "Isaac Guilherme Araújo"

2) In Brazil there are names with connectives. Examples: "das" "da" "dos" "do" "de" "e".

Carlos Eduardo Julio dos Santos

Carlos Eduardo dos Santos e Silva

Carlos Eduardo da Silva

3) I am having this problem to work with the name fields. With the following code, i could apply the first letter in uppercase, but the others as lowercase i couldn't. Then, according to problem number 2, if I write:

value entered: "douglas de oliveira júnior"

should be: "Douglas de Oliveira Júnior"

shouldn't: "douglas de Oliveira Júnior". //value shown with current code

function contains(str, search){
 if(str.indexOf(search) >= 0){
   return true;
 } else {
   return false;
 }
}

$.fn.capitalize = function(str) {
    $.each(this, function() {
        var split = this.value.split(' ');
        for (var i = 0, len = split.length; i < len; i++) {
            var verify = (split[len - 1] == "D" || split[len - 1] == "d") && (str == "e" || str == "E") || (str == "o" || str == "O");
            if (verify == false) {
                if ( contains(split[i], 'de') == false && contains(split[i], 'do') == false) {
                    split[i] = split[i].charAt(0).toUpperCase() + split[i].slice(1);
                }
            }
        }
        this.value = split.join(' ');
    });
    return this;
};

$(".capitalize").keypress(function(e) {
    var str = String.fromCharCode(e.which);
    $(this).capitalize(str);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Nome: </label>
<input type="text" id="nome" name="nome" class="form-control input-sm capitalize">

I'm a new member here on Stackoverflow and I apologize for the mistakes, I am learning javascript. Thank you!

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Paulo Pitta
  • 163
  • 7
  • Doing it as they type will screw up delete key, putting cursor in different spots, etc. – epascarello Sep 08 '17 at 18:05
  • 1
    Does it have to be on key press? it will be easier to change to value only on change. It would also be more practical since right now, you can't place the cursor in the middle of the input and edit correctly. – Karl-André Gagnon Sep 08 '17 at 18:05
  • I think it should be: var str = String.fromCharCode(e.target.innerHtml); https://api.jquery.com/event.target/ – kangaro0 Sep 08 '17 at 18:13
  • I hadn't seen that question (you can't place the cursor in the middle of the input and edit correctly) before. Honestly, I don't know what to do in this situation. hahaha :( – Paulo Pitta Sep 08 '17 at 18:15

6 Answers6

2

You could use a format function that capitalizes all words except those provided in a whitelist. Then format the input value whenever the user presses a key (doesn't work well if the user moves the input cursor around though):

function format(string, noCapList=[]) {
  const words = string.toLowerCase().split(' ');
  return words.map((word) => {
    if(!word.length || noCapList.includes(word)) {
      return word;
    } else {
      return word[0].toUpperCase() + word.slice(1);
    }
  }).join(' ');
}

const input = document.querySelector('input');
input.addEventListener('keyup', () => {
  input.value = format(input.value, ["das", "da", "dos", "do", "de", "e"]);
});
<input/>

It looks like the issue with your code is in how you're formatting the input. I'm not 100% sure I understood the question, but this format function provides the output you were looking for.

SimpleJ
  • 13,812
  • 13
  • 53
  • 93
  • Hello friend, thanks for the contribution, forgot to mention that I'm not using javascript6. But the question is when the user putting the cursor in the middle of input to change. – Paulo Pitta Sep 08 '17 at 18:37
2

This solution also fixes connectives in uppercase, such as carlos DE silva.
Try it with the snippet below :)

var connectives = {
    das: true,
    da: true,
    dos: true,
    do: true,
    de: true,
    e: true
};

function capitalize(str) {
    return str
        .split(" ")
        .map(function(word) {
            return !connectives[word.toLowerCase()]
                ? word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
                : word.toLowerCase();
        })
        .join(" ");
};

$(".capitalize").keyup(function() {
    var cursorStart = this.selectionStart;
    var cursorEnd = this.selectionEnd;
    var capitalizedString = capitalize($(this).val());

    $(this).val(capitalizedString);
    this.setSelectionRange(cursorStart, cursorEnd);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Nome: </label>
<input type="text" id="nome" name="nome" class="form-control input-sm capitalize">
Borja Canseco
  • 325
  • 1
  • 6
  • 24
  • Hello friend, thanks for the contribution!! This solution also fixes connectives in uppercase, but continue with the problem that you can't place the cursor in the middle of the input and edit correctly... but, thanks :) – Paulo Pitta Sep 08 '17 at 19:11
  • Thank you, now works!! Can you tell me the difference from your code to these? https://stackoverflow.com/a/46122855/8577413 – Paulo Pitta Sep 08 '17 at 19:24
  • Aside from complexity: that solution works on keypress rather than keyup, so it's always delayed by one letter. For example, if you type Carlos and then remove the 'C', then it would take 'arlos' as valid input. – Borja Canseco Sep 08 '17 at 19:28
2

for simplicity I used npm lodash

https://lodash.com/docs/4.17.11#capitalize

    const _ = require('lodash');
    const connectives = {
               das: true,
               da: true,
               dos: true,
               do: true,
               de: true,
               e: true
                     };


    const nameToCapitalize = str.split(' ').map(word => connectives[word] ? 
    word.toLowercase : _.capitalize(word)).join(' ');
chaimm
  • 192
  • 1
  • 8
0

SimpleJ's answer is right, but to clarify your original approach: the "problem" is in the contains function - it actually does what it should according to it's name and returns true if the str contains search, so contains('douglas', 'do') === true; you already have the string split into separate words so just use split[i] !== "de" && split[i] !== "do" instead of the contains calls.

Tomas Varga
  • 1,432
  • 15
  • 23
0

I have posted algorithm in FCC about title casing a sentence . Might it would help you!

 function titleCase(str) {
     //First Converted to lowercase in case of test cases are tricky ones
      var spl=str.toLowerCase();

      //Then  Splitted in one word format as leaving one space as ' '
      spl = spl.split(' ');

      for(var i=0;i<spl.length;i++){

        //Again Splitting done to split one letter from that respective word   
        var spl2= spl[i].split('');  

        // In specific word's letter looping has to be done in order to 
        // convert 0th index character to uppercase
        for(var j=0;j<spl2.length;j++){

        spl2[0]= spl2[0].toUpperCase();
        }
        // Then Joined Those letters to form into word again
        spl[i] = spl2.join('');   
      }
      // Then joined those words to form string
      str = spl.join(' ');
      return str;
    }

titleCase("sHoRt AnD sToUt");
Meet Zaveri
  • 2,921
  • 1
  • 22
  • 33
  • Hello friend, thanks for the contribution, I understood the logic that you used to change letters. The question we are raising here is regarding the change directly in the input when the user presses any key. Thank you for the explanation! – Paulo Pitta Sep 08 '17 at 18:53
0

I found something that apparently was satisfactory. It even works when the user places the cursor in the middle of the input. I found it here: Link - Stackoverflow

Can anyone here evaluate and tell me if have some problem with this code from the user Doglas?

function ucfirst (str) {
    //  discuss at: http://locutus.io/php/ucfirst/
    str += '';
    var f = str.charAt(0).toUpperCase();
    return f + str.substr(1);
}

var not_capitalize = ['de', 'da', 'do', 'das', 'dos', 'e'];
$.fn.maskOwnName = function(pos) {
    $(this).keypress(function(e){
        if(e.altKey || e.ctrlKey)
            return;
        var new_char = String.fromCharCode(e.which).toLowerCase();
        
        if(/[a-zà-ú\.\, ]/.test(new_char) || e.keyCode == 8){
            var start = this.selectionStart, end = this.selectionEnd;
        
        if(e.keyCode == 8){
            if(start == end)
                start--;

            new_char = '';
        }
        
        var new_value = [this.value.slice(0, start), new_char, this.value.slice(end)].join('');
        var maxlength = this.getAttribute('maxlength');
        var words = new_value.split(' ');
        start += new_char.length;
        end = start;

        if(maxlength === null || new_value.length <= maxlength)
            e.preventDefault();
        else
            return;

        for (var i = 0; i < words.length; i++){
            words[i] = words[i].toLowerCase();

            if(not_capitalize.indexOf(words[i]) == -1)
                words[i] = ucfirst(words[i]);
        }

        this.value = words.join(' ');
        this.setSelectionRange(start, end);
    }
});

$.fn.maskLowerName = function(pos) {
  $(this).css('text-transform', 'lowercase').bind('blur change', function(){
      this.value = this.value.toLowerCase();
  });
};

$.fn.maskUpperName = function(pos) {
  $(this).css('text-transform', 'uppercase').bind('blur change', function(){
      this.value = this.value.toUpperCase();
  });
};

};

$('.capitalize').maskOwnName();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Nome: </label>
<input type="text" id="nome" name="nome" class="form-control input-sm capitalize">
Paulo Pitta
  • 163
  • 7