I'm trying to implement snippets into an html textarea. You write a certain word and it will look through key value object and expand the text if it exists. Here is what I have done:
var textarea = document.getElementById("whatever");
var snippets = {
'hello': 'Hello and welcome to my great site'
}
var prepend = "";
var checkCaps = function(e){
if (e.keyCode != 9) return;
e.preventDefault();
var string = "";
var pos = textarea.selectionStart;
var text = textarea.value.split("");
while (pos) {
char = text.pop(pos);
prepend = (char == " ") ? " ": "";
if (char == " ") break;
string += char
pos -= 1;
}
if (snippets[string.reverse()]) {
textarea.value = text.join("")
textarea.value += prepend + snippets[string.reverse()]
}
}
textarea.addEventListener("keydown", checkCaps, false);
String.prototype.reverse=function(){return this.split("").reverse().join("");}
http://jsfiddle.net/JjTmd/
The problem is that the snippet only works in the last word of the textarea's value, and I can't seem to pinpoint where the problem is.
Array.pop doesn't accept a parameter. It removes and returns the last item from the array. Use splice to remove an item at a particular index.
I modified your function as follows and it seems to have the desired behavior:
var checkCaps = function(e){
if (e.keyCode != 9) return;
e.preventDefault();
var string = "";
var pos = textarea.selectionStart;
var text = textarea.value.split("");
while (pos) {
char = text.splice(pos-1,1);
prepend = (char == " ") ? " ": "";
if (char == " ") break;
string += char
pos -= 1;
}
if (snippets[string.reverse()]) {
var start = text.splice(0, pos);
var end = text.splice(pos + string.length);
textarea.value = start.join("") + snippets[string.reverse()] + prepend + text.join("") + end.join("");
}
}
http://jsfiddle.net/JjTmd/1/
Also, you'll probably want to check for new line characters as well:
while (pos) {
char = text.splice(pos-1,1);
if (char == " " || char == "\n") {
prepend = char;
break;
}
string += char
pos -= 1;
}
http://jsfiddle.net/JjTmd/2/
Related
I want to enter a "/" when user enters MM(2 digit) so it will be like MM/YYYY.
I have done similar for credit card number input which insert a space after 4 digit on keypress.
let ccNumber = e.target.value.split(" ").join("");
if (ccNumber.length > 0) {
ccNumber = ccNumber.match(new RegExp('.{1,4}', 'g')).join(" ");
}
e.target.value = ccNumber;
Fiddle
This works with
Regular keyboard input
Copy/Cut/Paste
Selected text
Adding the /
Because you're programmatically adding the / character, you have to update the cursor position whenever that affects the new input value. This can be more than one character if the user is pasting something. Most of the code complexity revolves around this issue.
There are a lot of comments in the code explaining the various situations that come up because of the /.
Full Code
var date = document.getElementById('date');
date.addEventListener('keypress', updateInput);
date.addEventListener('change', updateInput);
date.addEventListener('paste', updateInput);
date.addEventListener('keydown', removeText);
date.addEventListener('cut', removeText);
function updateInput(event) {
event.preventDefault();
var string = getString(event);
var selectionStart = this.selectionStart;
var selectionEnd = this.selectionEnd;
var selectionLength = selectionEnd - selectionStart;
var sanitizedString = string.replace(/[^0-9]+/g, '');
// Do nothing if nothing is added after sanitization
if (sanitizedString.length === 0) {
return;
}
// Only paste numbers that will fit
var valLength = date.value.replace(/[^0-9]+/g, '').length;
var availableSpace = 6 - valLength + selectionLength;
// If `/` is selected it should not count as available space
if (selectionStart <= 2 && selectionEnd >= 3) {
availableSpace -= 1;
}
// Remove numbers that don't fit
if (sanitizedString.length > availableSpace) {
sanitizedString = sanitizedString.substring(0, availableSpace);
}
var newCursorPosition = selectionEnd + sanitizedString.length - selectionLength;
// Add one to cursor position if a `/` gets inserted
if (selectionStart <= 2 && newCursorPosition >= 2) {
newCursorPosition += 1;
}
// Previous input value before current cursor position
var valueStart = date.value.substring(0, this.selectionStart);
// Previous input value after current cursor position
var valueEnd = date.value.substring(this.selectionEnd, date.value.length);
var proposedValue = valueStart + sanitizedString + valueEnd;
// Remove anything that's not a number
var sanitized = proposedValue.replace(/[^0-9]+/g, '');
format(sanitized);
this.setSelectionRange(newCursorPosition, newCursorPosition);
}
function removeText(event) {
if (event.key === 'Backspace' || event.type === 'cut') {
event.preventDefault();
var selectionStart = this.selectionStart;
var selectionEnd = this.selectionEnd;
var selectionLength = selectionEnd - selectionStart;
// If pressing backspace with no selected text
if (selectionLength === 0 && event.type !== 'cut') {
selectionStart -= 1;
// Remove number from before `/` if attempting to delete `/`
if (selectionStart === 2) {
selectionStart -= 1;
}
}
var valueStart = date.value.substring(0, selectionStart);
var valueEnd = date.value.substring(selectionEnd, date.value.length);
// Account for added `/`
if (selectionStart === 2) {
selectionStart += 1;
}
var proposedValue = valueStart + valueEnd;
var sanitized = proposedValue.replace(/[^0-9]+/g, '');
format(sanitized);
this.setSelectionRange(selectionStart, selectionStart);
}
}
function getString(event) {
if (event.type === 'paste') {
var clipboardData = event.clipboardData || window.clipboardData;
return clipboardData.getData('Text');
} else {
return String.fromCharCode(event.which);
}
}
function format(sanitized) {
var newValue;
var month = sanitized.substring(0, 2);
if (sanitized.length < 2) {
newValue = month;
} else {
var year = sanitized.substring(2, 6);
newValue = month + '/' + year;
}
date.value = newValue;
}
<input id="date" type="text" maxlength="7">
Try:
var date = document.getElementById('date');
date.addEventListener('keypress', function (event) {
var char = String.fromCharCode(event.which),
offset = date.selectionStart;
console.log(offset)
if (/\d/.test(char) && offset < 7) {
if (offset === 2) {
offset += 1;
}
date.value = date.value.substr(0, offset) + char + date.value.substr(offset + 1);
date.selectionStart = date.selectionEnd = offset + 1;
}
if (!event.keyCode) {
event.preventDefault();
}
});
<input id="date" type="text" value="mm/yyyy" maxlength="6" size="6">
function keypress(elem) { // get Input
if (typeof elem == 'string') {
if (document.getElementById(elem)) elem = document.getElementById(elem);
if (typeof elem == 'string') elem = document.getElementsByName(elem).item(0);
}
const el = elem; //handle error if not found input
el.maxLength = 19;
el.addEventListener('keypress', function (e) {
const t = e.keyCode || e.which
if (t == 8 || (t > 47 && t < 58)) { // limit numeric characters and backspace
if (t != 8) {
if (el.value.length == 2) el.value += '/';
if (el.value.length == 5) el.value += '/';
if (el.value.length == 10) el.value += ' ';
if (el.value.length == 13) el.value += ':';
if (el.value.length == 16) el.value += ':';
}
} else {
e.preventDefault();
}
});}
Here is the javascript code:
I need help getting the word to display after the player looses.
var can_play = true;
//this is the array of words
var words = new Array("VALIDATE", "DESIGN", "INPUT", "ARRAY", "OBJECT", "DOCUMENTATION", "JQUERY", "CALCULATE", "ABSOLUTE", "DREAMWEAVER", "BROWSER", "HTML", "CONCATINATION");
var display_word = "";
var used_letters = "";
var wrong_guesses = 0;
//this will allow the letters to be entered in only 1 time
function selectLetter(l) {
if (can_play == false) {
return;
}
if (used_letters.indexOf(l) != -1) {
return;
}
used_letters += l;
document.game.usedLetters.value = used_letters;
if (to_guess.indexOf(l) != -1) {
// this will display the correct letter guesses
pos = 0;
temp_mask = display_word;
while (to_guess.indexOf(l, pos) != -1) {
pos = to_guess.indexOf(l, pos);
end = pos + 1;
start_text = temp_mask.substring(0, pos);
end_text = temp_mask.substring(end, temp_mask.length);
temp_mask = start_text + l + end_text;
pos = end;
}
display_word = temp_mask;
document.game.displayWord.value = display_word;
if (display_word.indexOf("*") == -1) {
// this will display a message if you win
$('#win').html("Well done, you won!");
can_play = false;
}
} else {
// this will display the incorrect letter guesses
wrong_guesses += 1;
$('#wrong_guesses').html(wrong_guesses);
if (wrong_guesses == 6) {
// this will display a message if you loose
$('#win').html("Sorry, you have lost!");
can_play = false;
}
}
}
//this will reset the game to play again
function reset() {
selectWord();
document.game.usedLetters.value = "";
guessed_letters = "";
wrong_guesses = 0;
$('#win').html("");
$('#wrong_guesses').html("");
}
//this will have the computer select a word from my array
function selectWord() {
can_play = true;
random_number = Math.round(Math.random() * (words.length - 1));
to_guess = words[random_number];
// this will display mask
masked_word = createMask(to_guess);
document.game.displayWord.value = masked_word;
display_word = masked_word;
}
function createMask(m) {
mask = "";
word_length = m.length;
for (i = 0; i < word_length; i++) {
mask += "*";
}
return mask;
}
$('#win').html("Sorry, you have lost, the word was " + to_guess + "!");
You assigned the to be guessed word here:
to_guess = words[random_number];
You would learn much from posting your code to Code Review.
I am trying to get it so that if I type in a name that ends with a space, the textfield will go red. Most of the code works its just one method does not seem to be working.
The issue must be somewhere in the last index part?
var NamePass = true;
function ValidateName() {
var BlankPass = true;
var GreaterThan6Pass = true;
var FirstBlankPass = true;
var BlankMiddleName = true;
if (document.getElementById('Name').value == "") {
BlankPass = false;
}
var Size = document.getElementById('Name').value.length;
console.log("Size = " + Size);
if (Size < 7) {
GreaterThan6Pass = false;
}
if (document.getElementById('Name').value.substring(0, 1) == " ") {
FirstBlankPass = false;
}
var LastIndex = document.getElementById('Name').value.lastIndexOf();
if (document.getElementById('Name').value.substring((LastIndex - 1), 1) == " ") {
FirstBlankPass = false;
}
string = document.getElementById('Name').value;
chars = string.split(' ');
if (chars.length > 1) {} else
BlankMiddleName = false;
if (BlankPass == false || GreaterThan6Pass == false || FirstBlankPass == false || BlankMiddleName == false) {
console.log("BlankPass = " + BlankPass);
console.log("GreaterThan6Pass = " + GreaterThan6Pass);
console.log("FirstBlankPass = " + FirstBlankPass);
console.log("BlankMiddleName = " + BlankMiddleName);
NamePass = false;
document.getElementById('Name').style.background = "red";
} else {
document.getElementById('Name').style.background = "white";
}
}
http://jsfiddle.net/UTtxA/10/
lastIndexOf gets the last index of a character, not the last index in a string. I think you meant to use length instead:
var lastIndex = document.getElementById('Name').value.length;
Another problem with that, though, is that substring takes a start and end index, not a start index and a substring length. You could use substr instead, but charAt is easier:
if (document.getElementById('Name').value.charAt(lastIndex - 1) == " ") {
FirstBlankPass = false;
}
Now, for some general code improvement. Instead of starting with all your variables at true and conditionally setting them to false, just set them to the condition:
var NamePass = true;
function ValidateName() {
var value = document.getElementById('Name').value;
var BlankPass = value == "";
var GreaterThan6Pass = value.length > 6;
var FirstBlankPass = value.charAt(0) == " ";
var LastBlankPass = value.charAt(value.length - 1) == " ";
var BlankMiddleName = value.split(" ").length <= 1;
if (BlankPass || GreaterThan6Pass || FirstBlankPass || LastBlankPass || BlankMiddleName) {
console.log("BlankPass = " + BlankPass);
console.log("GreaterThan6Pass = " + GreaterThan6Pass);
console.log("FirstBlankPass = " + FirstBlankPass);
console.log("BlankMiddleName = " + BlankMiddleName);
NamePass = false;
document.getElementById('Name').style.background = "red";
} else {
document.getElementById('Name').style.background = "white";
}
}
A couple more points of note:
It’s probably a good idea to use camelCase variable names instead of PascalCase ones, the latter usually being reserved for constructors
blah == false should really be written as !blah
An empty if followed by an else can also be replaced with if (!someCondition)
That function looks like it should return true or false, not set the global variable NamePass
Penultimately, you can sum this all up in one regular expression, but if you intend to provide more specific error messages to the user based on what’s actually wrong, then I wouldn’t do that.
function validateName() {
return /^(?=.{6})(\S+(\s|$)){2,}$/.test(document.getElementById('name').value);
}
And finally — please keep in mind that not everyone has a middle name, or even a name longer than 6 characters, as #poke points out.
I have a string that I want to check if it has words longer than or equal to 15 chars. If so, split that word to 5 chars by blank spaces, then return the same string with splitted words.
My code works but the problem is that my string could also contain HTML tags and I would like to not touch them.
function space_that(_e){
var w = [];
var t = $(_e).text();
w = t.split(" ");
for(var s in w)
if(w[s].length >= 15)
w[s] = w[s].substr(0,10) + " ";
$(_e).text(w.join(" "));
return true;
}
Just check if that part begins with an <, then it is an HTML tag.
function space_that(_e){
var w = [];
var t = $(_e).text();
w = t.split(" ");
for(var s in w) {
if(w[s].length >= 15
&& w[s].substring(0, 1) != "<"
&& w[s].substring(w[s].length-1, 1) != ">")
w[s] = w[s].substr(0,10) + " ";
}
$(_e).text(w.join(" "));
return true;
}
Edit: Corrected mistake (old answer affected ONLY html tags) and added check for opening and closing tags.
Following version should work for tags with space inside.
function space_that(_e){
var w = [];
var t = $(_e).text();
w = t.split(" ");
var inTag = false;
for(var s in w) {
if(w[s].substring(0, 1) == "<") inTag = true;
if(w[s].substring(w[s].length-1, 1) == ">") inTag = false;
if(inTag) continue;
if(w[s].length >= 15
&& w[s].substring(w[s].length-1, 1) != ">")
w[s] = w[s].substr(0,10) + " ";
}
$(_e).text(w.join(" "));
return true;
}
I want to make user control to get number like this:
125.00
125
125.27
125.20
1231545.25
2566.66
I have tried with mask textbox but its length can be anything.
I have used textbox with Javascript that accepts a number
like this:
click here
If a Javascript plugin is available for this let me know,
or any code to accept value in price format.
Restrict user to insert only number and two decimal spaces while entering.
If number is not well formatted then cut and format number after text change.
Like if 125.2 then 125.20 or if 125 then 125.00 or 135156. then 135156
I have search on internet but no plugin or script was found for this.
I have a plugin like numeric.js but it doesn't restrict decimal spaces.
Post if any Javascript available.
I don't want to do validation to check for entered values; I want to accept values with restriction.
Please help me.
You can use Ajax Control Toolkit MaskedEdit control:
MaskedEdit is an ASP.NET AJAX extender that attaches to a TextBox control to restrict the kind of text that can be entered. MaskedEdit applies a "mask" to the input that permits only certain types of characters/text to be entered. The supported data formats are: Number, Date, Time, and DateTime. MaskedEdit uses the culture settings specified in the CultureName property. If none is specified the culture setting will be the same as the page: English (United States).
Sample Code:
<ajaxToolkit:MaskedEditExtender
TargetControlID="TextBox2"
Mask="9,999,999.99"
MessageValidatorTip="true"
OnFocusCssClass="MaskedEditFocus"
OnInvalidCssClass="MaskedEditError"
MaskType="Number"
InputDirection="RightToLeft"
AcceptNegative="Left"
DisplayMoney="Left"
ErrorTooltipEnabled="True"/>
See Working Demo
I also having same problem.This code has solved my problem.This solution is exactly what u want.It's not only foramt yous decimal number but also will eliminate blank spaces. Try this.As in my condition i was allowing user to enter '+' or '-' so i check for this validation also.
<script type="text/javascript">
function checkforvalidation() {
var txtvalue = document.getElementById('<%=txtspherical.ClientID %>').value;
var leftstr = "";
var rightstr = "";
var tempstr = "";
var operator = "";
txtvalue = txtvalue.replace(/\s/g, '');
document.getElementById('<%=txtspherical.ClientID %>').value = txtvalue;
if (txtvalue.indexOf(".") != -1) {
leftstr = txtvalue.split(".")[0];
rightstr = txtvalue.split(".")[1];
if (leftstr.indexOf("-") == 0 || leftstr.indexOf("+") == 0) {
operator = leftstr.substr(0, 1);
tempstr = leftstr.substr(1, leftstr.length - 1);
leftstr = ltrim(tempstr, '0');
if (leftstr.length == 0) {
leftstr = '0';
}
if (rightstr.indexOf("-") == -1 || rightstr.indexOf("+") == -1) {
rightstr = ltrim(rightstr, '0');
rightstr = chkdecimalpoints(rightstr);
if (operator != null || operator != "") {
txtvalue = operator + leftstr + "." + rightstr;
}
else {
txtvalue = leftstr + "." + rightstr;
}
document.getElementById('<%=txtspherical.ClientID %>').value = txtvalue;
}
else {
document.getElementById('<%=txtspherical.ClientID %>').value = "";
}
}
else {
tempstr = leftstr.substr(0, leftstr.length);
leftstr = ltrim(tempstr, '0');
if (leftstr.length == 0) {
leftstr = '0';
}
if (rightstr.indexOf("-") == -1 || rightstr.indexOf("+") == -1) {
rightstr = rtrim(rightstr, '0');
rightstr = chkdecimalpoints(rightstr);
txtvalue = leftstr + "." + rightstr;
document.getElementById('<%=txtspherical.ClientID %>').value = txtvalue;
}
}
}
else if (txtvalue.indexOf("-") == -1 || txtvalue.indexOf("+") == -1) {
txtvalue = ltrim(txtvalue, '0');
if (txtvalue.length == 0) {
txtvalue = '0';
}
if (operator != null || operator != "") {
txtvalue = operator + txtvalue + ".00";
}
// txtvalue = leftstr + "." + rightstr;
document.getElementById('<%=txtspherical.ClientID %>').value = txtvalue;
}
else if (txtvalue.indexOf("-") == 0 || txtvalue.indexOf("+") == 0) {
operator = txtvalue.substr(0, 1);
tempstr = txtvalue.substr(1, leftstr.length - 1);
txtvalue = alltrim(tempstr, '0');
if (operator != null || operator != "") {
txtvalue = operator + txtvalue + ".00";
document.getElementById('<%=txtspherical.ClientID %>').value = txtvalue;
}
}
}
function chkdecimalpoints(rightstr) {
if (rightstr.length == 0) {
rightstr = '00';
return rightstr;
}
else if (rightstr.length == 1) {
rightstr = rightstr + '0';
return rightstr;
}
else if (rightstr.length > 2) {
var tempvar = rightstr.substr(2, 1);
if (tempvar >= 5) {
tempvar = parseInt(rightstr.substr(1, 1)) + 1;
tempvar = rightstr.substr(0, 1) + tempvar.toString();
if (tempvar.length > 2) {
tempvar = tempvar.substr(0, 2);
}
return tempvar;
}
else {
tempvar = rightstr.substr(0, 2);
return tempvar;
}
}
else {
return rightstr;
}
}
function ltrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
function rtrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}
function alltrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("^[" + chars + "]+$", "g"), "");
}
</script>
HTML Source:
<asp:TextBox ID="txtspherical" runat="server" OnBlur="javascript:checkforvalidation();">
</asp:TextBox>
function validNumber(input){
input=input.replace(/\s+/g," ").replace(/^\s+|\s+$/g,"");
if( input.match(/\d+\.*\d*/i) ){
input=input.match(/(\d+\.*\d*)/i)[1].replace(/\.$/i, "");
if(!input.match(/\./i)) input+=".00";
if(input.match(/\.(\d+)/i)[1].length<2) input+="0";
return input;
}else{
return "0.00";
}
}