Capitalize first letter of words in sentence, except on manual replacement - javascript

I have an input field that the user will fill in and I want to automatically capitalize the first letter of each word as they're typing. However, if they manually delete a capital letter and replace it with a lower case, I want that to remain (basically capitalizing the letters is what we recommend, but not required). I'm having trouble implementing something that will leave the letters they manually typed alone and not change them.
Here is the code I have along with a Jsfiddle link to it.
<input class="capitalize" />
and JS:
lastClick = 0;
$(document).ready(function() {
$(".capitalize").keyup(function() {
var key = event.keyCode || event.charCode;
if (!(lastClick == 8 || lastClick == 46)) {
//checks if last click was delete or backspace
str = $(this).val();
//Replace first letter of each word with upper-case version.
$(this).val(str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}));
}
lastClick = key;
});
});
I haven't allowed for preserving the user's manual corrections, but as it is you can see in the jsfiddle that the input jumps around and doesn't work correctly. Can anyone help me or recommend a best way to do this? Thank you.

$(document).ready(function() {
var last;
$(".capitalize").on('keyup', function(event) {
var key = event.keyCode || event.which,
pos = this.value.length,
value = this.value;
if (pos == 1 || last == 32 && (last !== 8 || last !== 46)) {
this.value = value.substring(0, pos - 1) +
value.substring(pos - 1).toUpperCase();
}
last = key;
});
});
http://jsfiddle.net/userdude/tsUnH/1

$(document).ready(function() {
$(".capitalize")
.keyup(function(event) {
var key = event.keyCode || event.charCode;
// store the key which was just pressed
$(this).data('last-key', key);
})
.keypress(function(event) {
var key = event.keyCode || event.charCode;
var lastKey = $(this).data('last-key') ? $(this).data('last-key') : 0; // we store the previous action
var $this = $(this); // local reference to the text input
var str = $this.val(); // local copy of what our value is
var pos = str.length;
if(null !== String.fromCharCode(event.which).match(/[a-z]/g)) {
if ((pos == 0 || str.substr(pos - 1) == " ") && (!(lastKey == 8 || lastKey == 46))) {
event.preventDefault();
$this.val($this.val() + String.fromCharCode(event.which).toUpperCase());
}
}
// store the key which was just pressed
$(this).data('last-key', key);
});
});
I have updated your fiddle http://jsfiddle.net/nB4cj/4/ which will show this working.

Related

How to make letter replace after it has been added?

I have a working script to replace non alphanumerical letters from the text input. If you add special chars to text input, it doesnt let you to add to there. However, I want this script delete the special char after you add the letter, means that you can see the letter there but just after that it hs been removed (like when you try to upvote your own question on stackoverflow)
$("#nick").on("keypress", function(event) {
var englishAlphabetAndWhiteSpace = /[A-Za-z]/g;
var key = String.fromCharCode(event.which);
if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || englishAlphabetAndWhiteSpace.test(key)) {
return true;
}
return false;
});
What is the correct way to do it ?
You want to show the letter and then remove it, use 'keyup' event
$('#test').on('keyup keypress', function(e) {
var reg = /[A-Za-z]/;
var value = $(this).val();
if (value && !reg.test(value[value.length - 1])) {
$(this).val(value.slice(0, value.length - 1));
}
})
Code on jsfiddler
You can use regex that'll replace all the non-alphabetic characters in the input value.
Use HTML5 pattern attribute on input to give regex
Use keyup and input event handlers to capture events
Use negated class regex to remove all non-alphabet symbols
Use setTimeout to clear the special characters after a delay
var timeout;
$("#nick").on("keypress input", function(e) {
var keyCode = e.keyCode || e.which; // Browser-independant
// If left or right arrow, then don't do anything
if (keyCode === 8 || keyCode === 37 || keyCode === 39) {
return true;
}
var $this = $(this); // Cache this
clearTimeout(timeout); // Clear previous timeouts
timeout = setTimeout(function() {
$this.val($this.val().replace(/[^A-Za-z]/g, ''));
}, 500);
});
input:valid {
color: green;
}
input:invalid {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="nick" pattern="[A-Za-z]+" />
Regex Explanation:
The regex on pattern, [A-Za-z]+ only matches one or more of the alphabet characters both uppercase and lowercase.
If I read it correctly, you are talking about inserting a delay before the invalid character vanishes?
It's a bit trickier as there is the clause of how long you want to see it before it vanishes & also what if you are faster than typing the next letter before it does.
After taking care of these, it should look something like this :
var removelast = false, remover;
var nick = $("#nick").on("keypress", function(event) {
function remove() {
nick.val(nick.val().slice(0,-1));
removelast = false;
}
clearTimeout(remover);
if(removelast) remove();
var englishAlphabetAndWhiteSpace = /[A-Za-z]/g;
var key = String.fromCharCode(event.which);
var allowed = event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || englishAlphabetAndWhiteSpace.test(key);
if (!allowed) {
removelast = true;
remover = setTimeout(remove, 100);
}
return true;
});
<input type="text" id="nick" >
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Disable first character in textbox

I have a textbox and it contain a value "Given Name". I want to disable first character of a textbox so that user cannot change the First Charcter in textbox by using backspace or any other means.
For Example: suppose textbox contains the value "Given Name". I want that user cannot change the First character "G" by using backspace or any other means.
<input type="text" id="nameId" onkeydown="validate(this.val)"/>
Below is javascript function:
function validate2(val) {
// have no idea how to do.
}
I have no idea how to do it in Javscript or Jquery.
You could do like follow :
$("#nameId").on("keydown", function(e) {
// if user writes a char at index === 0 that is not an arrow or HOME or END
if (($(this).get(0).selectionStart === 0 && (e.keyCode < 35 || e.keyCode > 40))
// or if user tries to erase first char
|| ($(this).get(0).selectionStart === 1 && $(this).get(0).selectionEnd === 1 && e.keyCode === 8)) {
// don't write the character
return false;
}
});
// prevent right click
$("#nameId").bind("contextmenu", function(e) {
e.preventDefault();
});
JSFIDDLE
Wasn't planning on answering, leaving it with the comment, but after seeing the other answers thought I might have a quick go at it after all:
The html:
<input type="text" id="nameId" value="Given Name" onkeydown="save(this,event)" onkeyup="restore(this,event)" onchange="restore(this,event)"/>
The javascript:
function restore(el,event) {
if(el.value.length == 0){
el.value = el.dataset.value.substr(0,1);
}else{
el.dataset.value = el.value;
}
}
function save(el,event) {
var key = event.which || event.charCode || event.keyCode;
if((key === 8 && el.value.length === 1)
|| (key === 46 && el.selectionStart == 0 && el.value.length === 1)){
event.preventDefault();
}
if(el.value.length > 0){
el.dataset.value = el.value;
}
}
The approach was to not mess around too much with preventing the deletion of the actual character (just the very bare basics) and instead ensure that if somebody deletes the first character to always restore it somehow. It creates code that's easy to comprehend and maintain, yet works quite neatly. A fiddle can be found here as well. Do note though that event.which is not the most cross browser consistent interface, so either use jQuery for that or check in other browsers before using it in production. Edited it in a way that should work cross browser including older browsers.
Here's mine version.
Html
<input type="text" id="nameId" value="Given Name" />
JS
var lastentry = '';
$("#nameId").on("keyup", function(e) {
var targetValue = $(e.currentTarget).attr('value');
var targetValueLength = targetValue.length;
var inputValue = this.value;
if(checkChanges(targetValueLength, targetValue, inputValue))
this.value = targetValue + lastentry;
else
lastentry = this.value.slice(targetValueLength)
});
function checkChanges(targetValueLength, targetValue, inputValue)
{
for(var i = 0; i < targetValueLength ; i++)
{
if(targetValue[i] != inputValue[i])
return true;
}
return false;
}
Demo
You can try this:-
<input type="text" id="nameId" value="Given Name" onkeydown="validate(this.value,event)"/>
<script>
function validate(val,event) {
// have no idea how to do.
if(event.target.selectionStart != undefined && (event.which === 46 ||event.which === 8)){
var startPos = event.target.selectionStart,
endPos = event.target.selectionEnd;
console.log(startPos,endPos);
if(startPos === 0 && startPos != endPos){
var restPart = val.slice(endPos,val.length);
if(restPart){
val = val[0].concat(restPart);
} else{
val = val[0]
}
event.target.value = val;
event.preventDefault();
} else if(startPos === 0 && startPos === endPos && event.which === 46){
event.preventDefault();
} else if(startPos === 1 && event.which === 8){
event.preventDefault();
}
}
}
</script>
Hi use this it do not allow to delete first character ,
$(document).keydown(function(e)
{
var value = $('#nameId').val().length;
if ( e.keyCode == 8 && value < 2)
e.preventDefault();
});

Make a Mention like SO code started

var userNames = $('.username').map(function(index){
return $(this).text().replace(/\s/g,'');
});
userNames = $.unique(userNames).toArray();
var a = document.getElementById('text_editor_textarea');
var sc= $(a).data('sceditor');
var updateText = function() {
sc ? sc.bind('keypress',sc.updateOriginal).blur(sc.updateOriginal) : setTimeout(updateText,200);
};
updateText();
sc.bind('keypress',function(e) {
if(e.shiftKey && e.which === 64){
sc.unbind('keypress');
sc.bind('keyup',function(e) {
var string = e.which;
var stringCase = String.fromCharCode(string);
var word=[];
if(stringCase !== " " || e.which !== 32) {
word.push(stringCase);
} else if(e.which === 8){
word.pop();
} else {
return;
}
console.log(word);
});
}
});
What I am trying to do is when the user presses SHIFT+2 creating the # symbol it then starts adding to an array, multiple problems exist in my code right now. When console.logging the array it does this
["2"]
[" "]
["M"]
["Y"]
[" "]
["W"]
["O"]//.etc
First off in my code I write if(stringCase !== " " || e.which !== 32) { so basically that if it is not a space or blank then to add it (.push(stringCase) ) and then I check if the keycode is backspace 8 and if it is pop the array word. Else return it.
For a quick example http://jsbin.com/erebey/1/edit
Basically I want it to do what it does on SO when typing #USERNAME where the div appears with the usernames name and once you click it it adds that to the textarea.

Convert first letter to uppercase on input box

JS Bin demo
This regex transform each lower case word to upper case. I have a full name input field. I do want the user to see that each word's first letter he/she pressed is converted to uppercase in the input field.
I have no idea how to properly replace the selected characters in the current input field.
$('input').on('keypress', function(event) {
var $this = $(this),
val = $this.val(),
regex = /\b[a-z]/g;
val = val.toLowerCase().replace(regex, function(letter) {
return letter.toUpperCase();
});
// I want this value to be in the input field.
console.log(val);
});
Given i.e: const str = "hello world" to become Hello world
const firstUpper = str.substr(0, 1).toUpperCase() + str.substr(1);
or:
const firstUpper = str.charAt(0).toUpperCase() + str.substr(1);
or:
const firstUpper = str[0] + str.substr(1);
input {
text-transform: capitalize;
}
http://jsfiddle.net/yuMZq/1/
Using text-transform would be better.
You can convert the first letter to Uppercase and still avoid the annoying problem of the cursor jumping to the beginning of the line, by checking the caret position and resetting the caret position. I do this on a form by defining a few functions, one for all Uppercase, one for Proper Case, one for only Initial Uppercase... Then two functions for the Caret Position, one that gets and one that sets:
function ProperCase(el) {
pos = getInputSelection(el);
s = $(el).val();
s = s.toLowerCase().replace(/^(.)|\s(.)|'(.)/g,
function($1) { return $1.toUpperCase(); });
$(el).val(s);
setCaretPosition(el,pos.start);
}
function UpperCase(el) {
pos = getInputSelection(el);
s = $(el).val();
s = s.toUpperCase();
$(el).val(s);
setCaretPosition(el,pos.start);
}
function initialCap(el) {
pos = getInputSelection(el);
s = $(el).val();
s = s.substr(0, 1).toUpperCase() + s.substr(1);
$(el).val(s);
setCaretPosition(el,pos.start);
}
/* GETS CARET POSITION */
function getInputSelection(el) {
var start = 0, end = 0, normalizedValue, range,
textInputRange, len, endRange;
if (typeof el.selectionStart == 'number' && typeof el.selectionEnd == 'number') {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() == el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
}
/* SETS CARET POSITION */
function setCaretPosition(el, caretPos) {
el.value = el.value;
// ^ this is used to not only get "focus", but
// to make sure we don't have it everything -selected-
// (it causes an issue in chrome, and having it doesn't hurt any other browser)
if (el !== null) {
if (el.createTextRange) {
var range = el.createTextRange();
range.move('character', caretPos);
range.select();
return true;
}
else {
// (el.selectionStart === 0 added for Firefox bug)
if (el.selectionStart || el.selectionStart === 0) {
el.focus();
el.setSelectionRange(caretPos, caretPos);
return true;
}
else { // fail city, fortunately this never happens (as far as I've tested) :)
el.focus();
return false;
}
}
}
}
Then on document ready I apply a keyup event listener to the fields I want to be checked, but I only listen for keys that can actually modify the content of the field (I skip "Shift" key for example...), and if user hits "Esc" I restore the original value of the field...
$('.updatablefield', $('#myform')).keyup(function(e) {
myfield=this.id;
myfieldname=this.name;
el = document.getElementById(myfield);
// or the jquery way:
// el = $(this)[0];
if (e.keyCode == 27) { // if esc character is pressed
$('#'+myfield).val(original_field_values[myfield]); // I stored the original value of the fields in an array...
// if you only need to do the initial letter uppercase, you can apply it here directly like this:
initialCap(el);
} // end if (e.keyCode == 27)
// if any other character is pressed that will modify the field (letters, numbers, symbols, space, backspace, del...)
else if (e.keyCode == 8||e.keycode == 32||e.keyCode > 45 && e.keyCode < 91||e.keyCode > 95 && e.keyCode < 112||e.keyCode > 185 && e.keyCode < 223||e.keyCode == 226) {
// if you only need to do the initial letter uppercase, you can apply it here directly like this:
initialCap(el);
} // end else = if any other character is pressed //
}); // end $(document).keyup(function(e)
You can see a working fiddle of this example here: http://jsfiddle.net/ZSDXA/
Simply put:
$this.val(val);
$(document).ready(function() {
$('input').on('keypress', function(event) {
var $this = $(this),
val = $this.val();
val = val.toLowerCase().replace(/\b[a-z]/g, function(letter) {
return letter.toUpperCase();
});
console.log(val);
$this.val(val);
});
});
As #roXon has shown though, this can be simplified:
$(document).ready(function() {
//alert('ready');
$('input').on('keypress', function(event) {
var $this = $(this),
val = $this.val();
val = val.substr(0, 1).toUpperCase() + val.substr(1).toLowerCase();
$this.val(val);
});
});
An alternative, and better solution in my opinion, would be to only style the element as being capitalized, and then do your logic server side.
This removes the overhead of any javascript, and ensures the logic is handled server side (which it should be anyway!)
$('input').on('keyup', function(event) {
$(this).val(function(i, v){
return v.replace(/[a-zA-Z]/, function(c){
return c.toUpperCase();
})
})
});
http://jsfiddle.net/AbxVx/
This will do for every textfield call function on keyup
where id is id of your textfield and value is value you type in textfield
function capitalizeFirstLetter(value,id)
{
if(value.length>0){
var str= value.replace(value.substr(0,1),value.substr(0,1).toUpperCase());
document.getElementById(id).value=str;
}
}
only use this This work for first name in capital char
style="text-transform:capitalize;
Like
<asp:TextBox ID="txtName" style="text-transform:capitalize;" runat="server" placeholder="Your Name" required=""></asp:TextBox>
$('.form-capitalize').keyup(function(event) {
var $this = $(this),
val = $this.val(),
regex = /\b[a-z]/g;
val = val.toLowerCase().replace(regex, function(letter) {
return letter.toUpperCase();
});
this.value = val;
// I want this value to be in the input field.
console.log(val);
});

Block characters from input text field, mirror input into span or div

I have some html
<input type="text" name="name" value="" id="name">
<div id="preview"></div>
The rules for entry into the field:
Letters A-Z a-z 0-9 space and dash, no other characters allowed
Entry of forbidden characters should do nothing
The rules for the div:
Show each characters as it is entered into the input field
Do not show characters that are forbidden
When a space is encountered, show it as a dash
I have had various potions working, not working, or misbehaving. This version seems to work in all cases I can test other than backspace/delete is non functional. Only tested in Safari so far.
There are other "gotcha" areas, like entering in text in-between already entered text, select all, using the arrow keys, all these play a role in this problem.
$(document).ready(function(){
$('#name').keypress(function(e) {
// get key pressed
var c = String.fromCharCode(e.which);
// var d = e.keyCode? e.keyCode : e.charCode; // this seems to catch arrow and delete better than jQuery's way (e.which)
// match against allowed set and fail if no match
var allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ';
if (e.which != 8 && allowed.indexOf(c) < 0) return false; // d !== 37 && d != 39 && d != 46 &&
// just replace spaces in the preview
window.setTimeout(function() {$('#preview').text($('#name').val().replace(/ /g, '-'));}, 1);
});
});
If there is a way to put a monetary bounty on this post, let me know. Yes, that is where I am at with this one :)
I tested the following in Firefox, Safari and Internet Explorer. Unless I didn't fully understand your objective, I believe this should solve your problem.
I ended up writing a jQuery plugin to handle the input caret position. The plugin source is included below, or available on the jQuery plugin site (http://plugins.jquery.com/project/caret-range).
$(document).ready(function () {
var InvalidPattern = /[^a-z0-9\- ]+/gi;
var SpacePattern = / /g;
var name = $("#name");
var preview = $("#preview");
var callback = function (e) {
setTimeout(function () {
// Get range and length to restore caret position
var range = name.caret();
var len = name.val().length;
// Blur element to minimize visibility of caret jumping
name.get(0).blur();
// Remove invalid characters, and update preview
name.val(name.val().replace(InvalidPattern, ""));
preview.text(name.val().replace(SpacePattern, "-"));
// Restore caret position
var diff = len - name.val().length;
name.caret(range.start - diff, range.end - diff);
}, 0);
};
name.keypress(callback);
name.keydown(callback); // Needed by IE to update preview for Delete and Backspace
});
/*
* jQuery Caret Range plugin
* Copyright (c) 2009 Matt Zabriskie
* Released under the MIT and GPL licenses.
*/
(function($) {
$.extend($.fn, {
caret: function (start, end) {
var elem = this[0];
if (elem) {
// get caret range
if (typeof start == "undefined") {
if (elem.selectionStart) {
start = elem.selectionStart;
end = elem.selectionEnd;
}
else if (document.selection) {
var val = this.val();
var range = document.selection.createRange().duplicate();
range.moveEnd("character", val.length)
start = (range.text == "" ? val.length : val.lastIndexOf(range.text));
range = document.selection.createRange().duplicate();
range.moveStart("character", -val.length);
end = range.text.length;
}
}
// set caret range
else {
var val = this.val();
if (typeof start != "number") start = -1;
if (typeof end != "number") end = -1;
if (start < 0) start = 0;
if (end > val.length) end = val.length;
if (end < start) end = start;
if (start > end) start = end;
elem.focus();
if (elem.selectionStart) {
elem.selectionStart = start;
elem.selectionEnd = end;
}
else if (document.selection) {
var range = elem.createTextRange();
range.collapse(true);
range.moveStart("character", start);
range.moveEnd("character", end - start);
range.select();
}
}
return {start:start, end:end};
}
}
});
})(jQuery);
After tinkering around I have refactored my previous solution. This version should behave identical to Twitter. I am keeping my old answer alive simply b/c it is technically valid, and this allows comparing the different approaches.
$(document).ready(function () {
var SpacePattern = / /g;
var name = $("#name");
var preview = $("#preview");
var updatePreview = function () {
preview.text(name.val().replace(SpacePattern, "-"));
};
name.keypress(function (e) {
if (e.which > 0 && // check that key code exists
e.which != 8 && // allow backspace
e.which != 32 && e.which != 45 && // allow space and dash
!(e.which >= 48 && e.which <= 57) && // allow 0-9
!(e.which >= 65 && e.which <= 90) && // allow A-Z
!(e.which >= 97 && e.which <= 122) // allow a-z
) {
e.preventDefault();
}
else {
setTimeout(updatePreview, 0);
}
});
name.keyup(updatePreview); // Needed by IE for Delete and Backspace keys
});
Try this:
1. When key down, copy the previous TextField value.
2. When key up, use RegEx to validate the text (something like /^[a-zA-Z0-9 -]*$/), if unmatch, replace the value with the old one.
Here is the code:
var ValidPattern = /^[a-zA-Z0-9\- ]*$/;
$(document).ready(function(){
$('#name').keydown(function(e) {
var aValue = $('#name').val();
$('#name').attr("oldValue", aValue);
return true;
});
$('#name').keyup(function(e) {
var aValue = $('#name').val();
var aIsMatch = aValue.search(ValidPattern) != -1;
if(aIsMatch) {
$('#preview').text(aValue);
} else {
var aOldValue = $('#name').attr("oldValue");
$('#name') .val (aOldValue);
$('#preview').text(aOldValue);
}
});
});
Try it.
I think the best method will be to keep a button and after entering the text inside the text box and clicking on the button show it in the div. It will be much more easier and user friendly.
It would be better not to try hindering the default actions of a user with the keyboard.

Categories