6

I'm using the popular Firefox extension Greasemonkey.

I'd like to know if there was a way to capitalize all text inputs in a certain form, so if I would use jQuery the code would look something like:

$('form#formid input[type=text]').capitalize();

Now of course I know .capitalize() is not a valid function, and in order to capitalize text you'd need a complicated JavaScript code, but after all the Googling, I could not find one that seemed like it could be implemented into Greasemonkey.

Can anybody help me to write this script?

By capitalize, I mean capitalizing the first letter of each word, like the CSS text-transform:capitalize; and it must override the letters the user might put in, maybe doing it on form submit would be easier...

Thanks.

henryaaron
  • 6,042
  • 20
  • 61
  • 80
  • 1
    why don't you just create a css class that has the text-transform:capitalize and use jQuery to add/remove that class as necessary? – c0deNinja Mar 06 '12 at 01:17
  • @c0deNinja Cause, CSS doesn't change the actual content, this info is being saved in a database... – henryaaron Mar 06 '12 at 01:45

6 Answers6

10
//add a function to jQuery so we can call it on our jQuery collections
$.fn.capitalize = function () {

    //iterate through each of the elements passed in, `$.each()` is faster than `.each()
    $.each(this, function () {

        //split the value of this input by the spaces
        var split = this.value.split(' ');

        //iterate through each of the "words" and capitalize them
        for (var i = 0, len = split.length; i < len; i++) {
            split[i] = split[i].charAt(0).toUpperCase() + split[i].slice(1);
        }

        //re-join the string and set the value of the element
        this.value = split.join(' ');
    });
    return this;
};

Here is a demo: http://jsfiddle.net/jasper/qppGQ/1/

This could be used inside an event handler to always keep a capitalized body of text:

//when the user presses a key and the value of the `textarea` is changed, the new value will have all capitalized words
$('textarea').on('keyup', function () {
    $(this).capitalize();
}).capitalize();//also capitalize the `textarea` element(s) on initialization

Here is a demo: http://jsfiddle.net/jasper/qppGQ/2/

Update

To have the first letter be capitalized and the rest of the word be lowercase we can just use .toLowerCase() in the remainder of the string after capitalizing the first letter:

        ...
        for (var i = 0, len = split.length; i < len; i++) {
            split[i] = split[i].charAt(0).toUpperCase() + split[i].slice(1).toLowerCase();
        }
        ...

Here is a demo: http://jsfiddle.net/jasper/qppGQ/3/

Community
  • 1
  • 1
Jasper
  • 75,717
  • 14
  • 151
  • 146
  • Wow that works very nicely, any way to get that to lowercase the other letters, often some people are typing in caps lock... – henryaaron Mar 06 '12 at 01:38
  • @user1090389 You can just add `.toLowerCase()` to the `split[i].slice(1)` string. Here is a demo: http://jsfiddle.net/jasper/qppGQ/3/ – Jasper Mar 06 '12 at 01:40
  • Hey, do you know anything about Greasemonkey, this script doesn't seem to be working for me: http://jsfiddle.net/pSnqR/ – henryaaron Mar 06 '12 at 01:49
  • @user1090389 No, sorry. I don't have any experience with Greasemonkey. – Jasper Mar 06 '12 at 17:06
  • It's ok somebody else was able to help me – henryaaron Mar 06 '12 at 19:28
  • Hey, starting to get some kind of error in Firefox. Looks like in the update, the JavaScript is having a problem? Any help would be much appreciated. – henryaaron Sep 02 '12 at 06:06
  • @user1090389 Can you copy/paste the error or give a description of the error? – Jasper Sep 03 '12 at 15:47
  • It makes jQuery crash completely. Also, in the jsFiddle. If you click jsLint it shows an error "Attempted to assign to readonly property." – henryaaron Sep 03 '12 at 19:06
  • @user1090389 I'm not seeing any errors, if you can copy/paste them I may be able to help further, but since I can't reproduce the problem I can't help much. – Jasper Sep 03 '12 at 19:41
  • In the version with `.toLowerCase` http://jsfiddle.net/jasper/qppGQ/3/ it says Error: Problem at line 1 character 18: Attempted to assign to readonly property. Implied global: $ 1,2 Unused variable: split 2 "this" – henryaaron Sep 04 '12 at 02:00
  • @user1090389 Maybe there is a problem with `.slice(1)`, you can change-it-out for `.substr(1)`. – Jasper Sep 05 '12 at 16:02
  • I believe the problem should be somewhere here: `for (var i = 0, len = split.length; i < len; i++)` – henryaaron Sep 05 '12 at 19:05
  • Tried changing to `.substr(1)`, didn't work. There is an error in the code according to jsLint on jsFiddle http://jsfiddle.net/X53tm/ – henryaaron Oct 18 '12 at 03:57
  • @user1090389 You forgot to load jQuery, here is an updated version that doesn't throw errors because I told JSFiddle to load jQuery 1.8.2: http://jsfiddle.net/X53tm/1/. Here is an updated version of my JSFiddle but using `.substr(1)` rather than `.slice(1)`: http://jsfiddle.net/qppGQ/90/ – Jasper Oct 18 '12 at 16:29
  • I'm still getting an error `Problem at line 1 character 10: Attempted to assign to readonly property.` It's in the jsLint link on jsFiddle. – henryaaron Oct 19 '12 at 18:43
  • @user1090389 In what browser are you getting the error? What exact action prompts the error? Can you post the link to JSFiddle that you are using? – Jasper Oct 19 '12 at 22:28
  • Both of those fiddles I get the error, Safari, Chrome and Firefox. – henryaaron Oct 20 '12 at 23:31
  • Firefox actually throws a different error, Firefox says `Problem at line 4 character 10: this is undefined` – henryaaron Oct 20 '12 at 23:32
  • @user1090389 Without seeing the code you're working with I really can't help with the errors you're getting. This JSFiddle: http://jsfiddle.net/qppGQ/90/ however does not throw errors in any browser I tested (IE/Firefox/Safari/Chrome). – Jasper Oct 21 '12 at 19:04
  • Is there a pure JavaScript version of this fiddle? – Dantès Cristo Dec 16 '15 at 12:09
4

Is this what you are trying to do?

(function ($) {

    $.fn.capitalize = function () {
        return this.val(function (i, oldValue) {
            return oldValue.charAt(0).toUpperCase() + oldValue.slice(1);
        });
    };

})(jQuery);

If you wanted to perform this action in "realtime", you could just process the action inside of an event:

(function ($) {

    $.fn.capitalize = function () {
        this.on('keyup.capitalize change.capitalize', function () { 
            $(this).val(function (i, oldValue) {
                return oldValue.charAt(0).toUpperCase() + oldValue.slice(1);
            });
        });
    };

})(jQuery);
Eli
  • 17,397
  • 4
  • 36
  • 49
  • Hey I see what you've done but is there any way to have the text also capitalized in real time, like as the user is typing rather than taking just the predefined value of the input? – henryaaron Oct 21 '12 at 16:06
  • Updated to do "realtime" updating. – Eli Oct 21 '12 at 23:52
1

I took the tips here and have formulated something a little easier using standard javascript. I needed to capitalize the each word of an input box on an iPad Web App, autocapitalize was failing to work consistently. Here's the work around:

HTML Input

<input type="text" id="this_input" name="this_input" onkeyup="javascript:capitalize(this.id, this.value);">

Javascript

<script type="text/javascript">
  function capitalize(textboxid, text) {
      // string with alteast one character
      var i, words, w, result = '';

    words = text.split(' ');

    for (i = 0; i < words.length; i += 1) {
        w = words[i];
        result += w.substr(0,1).toUpperCase() + w.substr(1);
        if (i < words.length - 1) {
            result += ' ';    // Add the spaces back in after splitting
        }
    }
      document.getElementById(textboxid).value = result;
  }
  </script>
davidbii
  • 105
  • 1
  • 1
  • 5
1

My simple implementation of a capitalize function splits up a string by spaces and capitalizes the first letter of each word. It assumes each word is divided by at least one space.

function capitalize(text) {
    var i, words, w, result = '';

    words = text.split(' ');

    for (i = 0; i < words.length; i += 1) {
        w = words[i];
        result += w.substr(0,1).toUpperCase() + w.substr(1);
        if (i < words.length - 1) {
            result += ' ';    // Add the spaces back in after splitting
        }
    }

    return result;
}

Example console output:

> capitalize("some tEsT e strING a B c 1 2 3")
  "Some TEsT E StrING A B C 1 2 3"
Matt Esch
  • 22,661
  • 8
  • 53
  • 51
0

You're going to want an event handler for the DOM object in question--specifically, the keypress event handler. You'll need to read the text of the input field after each key press to ensure that all words (text surrounded by spaces) have the first character capitalized.

For instance:

$('form#formid input[type=text]').keypress(function(event) {
// Function body goes here
});

As a general strategy, I recommend splitting the value of the input field by spaces (using str.split(" ");). Then, iterate through each of the resulting strings. For each string, slice off everything after the first letter, and append a capitalized first character to the sliced string. You can see other answers show you how to do this. Combine all these strings into one and set the value of the input to this capitalized string.

fruchtose
  • 1,270
  • 2
  • 13
  • 16
0

version with event binding built in

Simpl use

$('input[type="text"]').capitalize()

http://jsfiddle.net/uUjgg/

(function($) {

$.fn.capitalize = function() {
    return this.each(function() {
        var $field = $(this);

        $field.on('keyup change', function() {
            $field.val(function(i, old) {
                if (old.indexOf(' ') > -1) {
                    var words = old.split(' ');
                    for (i = 0; i < words.length; i++) {
                        words[i] = caps(words[i]);
                    }
                    return words.join(' ');
                } else {
                    return caps(old);
                }
            });
        });
    });

    function caps(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    }
};

})(jQuery);
charlietfl
  • 170,828
  • 13
  • 121
  • 150