I am stuck in implementing the following:
User starts typing in a textbox.
The javascript on page captures the first character typed, validates that it is an english alphabet (a-z,A-Z) and converts it to lowercase (if necessary).
Make an XMLHttp request based on the input (i.e. if first input character is a, get a.xml, if b get b.xml and so on).
I know how to do the last part (make the xmlhttp request) but am kind of stuck on how to capture the first character and validate it (in a way that works on all browsers). Please guide. Thanks.
Clarification: This is to create a Google Suggest like autocomplete-drop-down menu without the need for server side programs.
Something like this should work:
HTML:
<input type="text" id="myField" />
And in JS:
window.onload = function() {
document.getElementById('myField').onkeyup = function() {
// Validate that the first letter is A-Za-z and capture it
var letter = this.value.match(/^([A-Za-z])/);
// If a letter was found
if(letter !== null) {
// Change it to lowercase and update the value
letter = letter[0].toLowerCase();
this.value = letter + this.value.substring(1);
// Do the request
}
}
}
My vanilla-JS skills are a bit rusty but this should do the trick. Just for the heck of it, here's the same using jQuery:
$(function() {
$('#myField').keyup(function() {
var letter = $(this).val().match(/^([A-Za-z])/);
// If a letter was found
if(letter !== null) {
// Change it to lowercase and update the value
letter = letter[0].toLowerCase();
$(this).val(letter + $(this).val().substring(1);
// Do the request
}
});
});
What part of the problem do you not know how to do? Here's an approach that you can follow. Very likely to need adjustments, but a good starting point
if our text field's id is 'txt'
document.getElementByID('txt').onkeypress = function(e) {
var textInField = this.value;
if (textInField.length == 1) {
var firstChar = textInField.charAt(0);
if (/[a-zA-Z]/.test(firstChar)) {
sendXHR(textInField.value.toLowerCase())
}
} else {
// What do you do if there is one or more chars???
}
}
Note that the other answers here mention onchange, that doesn't fire until the focus leaves the field, which I don't think is what you want
Related
I'm creating a language quiz where users can write down their answers, like a translation for example. But I've noticed, when the answer requires punctuation, like a quotation mark, that some devices use a different style of punctuation and that will result in a wrong answer, because the punctuation used in the correct answer is just a bit different.
Here's the javascript I'm using to check answers:
<script>
var answers = {
q1: ["Auto's"]
};
function markAnswers(id) {
$(`#q${id}`).each(function () {
if ($.inArray(this.value, answers[this.id]) === -1) {
$(this).parent().append(`<br><span class='incorrect'>✗ Correct answer = ${answers[this.id]}</span>`);
} else {
$(this).parent().append("<br><span class='correct'>✓ Correct!</span>");
}
});
}
$("form").on("submit", function (e) {
e.preventDefault();
const id = e.target.id.replace("formId", "");
markAnswers(id);
$(`#submitId${id}`).each(function () {
this.setAttribute("disabled", true);
this.value = "Check answer";
});
});
</script>
As you can see, here I have an answer that requires a single quote ('), but apparently not all single quotes are equal.
I did find some code to replace specific punctuation and it's this: [^\w\s\']|_
But I'm not sure how to implement it and I would rather just accept the different punctuation. My only concerns are quotation marks and whitespace (as autofill on phones and tablets can create space).
Any suggestion on how to implement this is much appreciated. Thanks!
Edit:
Based on #Don't Panic's earlier versions of his code below (without .clean and .display) I want to make a few tweaks to it, but before I can, the code below always shows ✗ Correct answer = no matter if the answer is typed correctly or not. What could be wrong?
And about the tweaks. I've come to understand that Apple uses Smart Punctuation and this is a feature you can turn off. So I will ask my students to do that. Because I've tested it and without this feature toggled on, it will display a more straight/normal apostrophe and the answer will be accepted as correct. But since apostrophes and perhaps some other punctuation like a comma will be important, I want to add those to the existing line of code ^a-zA-Z\d. And I was thinking to at least ignore periods and extra spaces.
Thank you for all the help!
// Write out your answers without punctuation
var answers = {
q1: ["Autos"]
};
function markAnswers(id) {
$(`#q${id}`).each(function () {
// First, strip out any punctuation the user has entered
let userAnswer = this.value.replace(/[^a-zA-Z\d]/g,'');
// Now check if that "cleaned" value matches your answer
if ($.inArray(userAnswer, answers[this.id]) === -1) {
$(this).parent().append(`<br><span class='incorrect'>✗ Correct answer = ${answers[this.id]}</span>`);
} else {
$(this).parent().append("<br><span class='correct'>✓ Correct!</span>");
}
});
}
Take the user's input, strip out all punctuation, do the same to your answer, and compare the two. This way a user can use any punctuation they like, but it will just be stripped out and not part of the comparison.
This won't work if your questions are eg related to grammar, eg if you are testing when and where an apostrophe is correct, of course - in those cases the apostrophe is the answer!
The exact regular expression will depend on what has to be in your questions. Let's say you need all uppper- and lower-case letters and numbers:
$('button').on('click', function() {
markAnswers(1)
});
// Correct answers
var answers = {
"q1": "Auto's"
};
function markAnswers(id) {
$(`#q${id}`).each(function () {
// First, strip out any punctuation the user has entered
let userAnswer = this.value.replace(/[^a-zA-Z\d]/g,'');
// Strip any punctuation from the right answer
let correct = answers[this.id].replace(/[^a-zA-Z\d]/g,'');
// Now check if they match
if (userAnswer !== correct) {
$(this).parent().append(`<br><span class='incorrect'>✗ Correct answer = ${answers[this.id]}</span>`);
} else {
$(this).parent().append("<br><span class='correct'>✓ Correct!</span>");
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
What is the plural of <b>Auto</b>?
<input id='q1' type='text'>
<button>Check!</button>
</div>
To answer your new question - your code works fine for me.
I've added a button handler to actually run the check, but otherwise this is a copy-paste of your code.
If I type asdf, I get "✗ Correct answer = Autos", which is correct;
If I type autos, I get "✗ Correct answer = Autos", which is correct (lower case "a" instead of "A");
If I type Autos, I get "✓ Correct!", which is correct;
If I type "Auto's" (including those quotes), I get "✓ Correct!", which is correct;
$('button').on('click', function() {
markAnswers(1)
});
// Write out your answers without punctuation
var answers = {
q1: ["Autos"]
};
function markAnswers(id) {
$(`#q${id}`).each(function () {
// First, strip out any punctuation the user has entered
let userAnswer = this.value.replace(/[^a-zA-Z\d]/g,'');
// Now check if that "cleaned" value matches your answer
if ($.inArray(userAnswer, answers[this.id]) === -1) {
$(this).parent().append(`<br><span class='incorrect'>✗ Correct answer = ${answers[this.id]}</span>`);
} else {
$(this).parent().append("<br><span class='correct'>✓ Correct!</span>");
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
What is the plural of <b>Auto</b>?
<input id='q1' type='text'>
<button>Check!</button>
</div>
I am stuck with the following problem. On a web page in my current C# / MVC project, I added some control elements to fill a model. Among these control elements is a text area, designed using #Html.TextAreaFor:
<div class="smt-textarea ">
#Html.LabelFor(m => m.Numbers):
#Html.TextAreaFor(m => m. Numbers, new
{
#class = "form-control",
id = "smt-textarea",
rows = 25,
})
</div>
Users should enter a sequence of numbers into that text area. The number sequence follows a specific pattern. The pattern is later evaluated in code-behind methods, which are working well, and which are not part of my question here.
As a new feature, the numbers entered in the text area should now be validated regarding the amount of numbers in the actual sequence. The rule states that only digits from 0-9 can be entered in the text area. A number sequence should consist of exactly 19 digits.
Since I need to directly access the text area, I figured it might be a good idea to opt for Javascript in this particular case. I should note that I am quite new to JS and this might be one part of the problem. Be that as it may, based on some posts here on SO, I came up with the following preliminary solution.
console.log(textArea.value);
var reg = /\d{19,19}/;
let regex = new RegExp(reg);
if (regex.test(textArea.value)) {
console.log(regex.test(textArea.value));
alert("IT'S A MATCH !!!");
} else {
alert("SORRY, NO MATCH.");
}
}
window.onload = function () {
var textArea = document.getElementById("smt-textarea");
textArea.onkeyup = function (evt) {
evt = evt || window.event;
if (evt.keyCode === 13) {
validateTextArea(this);
}
};
};
Unfortunately, the code seems to validate the entire text area, meaning I do get a match whenever there are one more digit sequences matching the pattern, e.g. when entering the following
12345
0276114931111401167
skjfsjgrs
ksgfskgjsgjsrgs
skjfsjgrs and ksgfskgjsgjsrgs are valid because they are preceded by a "valid" number sequence.
What I would like to accomplish is that upon pressing the <ENTER> key, only the current line of the text area should be validated against the regular expression outlined in the sample. If the current line does not match, a warning message should be displayed. Once the user corrected his/her digit sequence, validation should continue moving to the next line until the next error pops up.
At the moment your validation will be passed if your string from text area contains a sequence from 19 numbers. In order to make sure each line is valid you'd better use ^ and $ anchors to match the whole string from start to end. Something like this:
/^(\d{3}\n?)*$/
var textArea = document.getElementById("smt-textarea");
textArea.onkeyup = function(evt) {
evt = evt || window.event;
if (evt.keyCode === 13) {
validateTextArea(this);
}
};
function validateTextArea(textArea) {
let regex = new RegExp(/^(\d{19}\n?)*$/);
if (regex.test(textArea.value)) {
alert("IT'S A MATCH !!!");
} else {
alert("SORRY, NO MATCH.");
}
}
<textarea name="" id="smt-textarea" rows="25"></textarea>
Also it might be a good idea to trim your string value in order to avoid problems with white-space characters in the end.
Update
Here is another version which validate line by line:
var textArea = document.getElementById("smt-textarea");
textArea.onkeyup = function(evt) {
evt = evt || window.event;
if (evt.keyCode === 13) {
validateTextArea(this);
}
};
function validateTextArea(textArea) {
let lines = textArea.value.trim().split('\n');
let regex = new RegExp(/^\d{19}$/);
let invalid = lines.some(function(line, index) {
let lineInvalid = !regex.test(line);
if (lineInvalid) {
alert(`Line ${index+1} is invalid`);
}
return lineInvalid;
});
console.log(`Text area is ${(invalid ? 'invalid' : 'valid')}`);
}
<textarea name="" id="smt-textarea" rows="25"></textarea>
I wanted to know which character the user is typing into an input:
I have an input:
<input maxlength="20"/>
and a script that returns the last typed char:
var eingabe;
$('form').on('keypress', function(event) {
/// if no whitespace:
if (String.fromCharCode(event.keyCode).replace(/\s/g, "").length > 0) {
eingabe = String.fromCharCode(event.keyCode);
$('#eingabe').html("<div>Eingabe : "+ eingabe +"</div>");
}
});
My question is:
because my input has a maxlength attribute, the last typed character on the keyboard is sometimes not the last -real- typed character into the input because the input is "full". How can I get the last character typed into the input?
I haven't tried it, but it must work...
Set onkeypress= or onkeydown= on the Input element and store the key value in a LastChr variable.
I had a similar problem. I wanted to call a function if the user types a specific character into my input field. I solved it with the following:
var input = document.getElementById('myInput');
input.addEventListener('input', function() {
// Get cursor position
var start = this.selectionStart;
// Get last typed character
var lastChar = String.fromCharCode(this.value.charCodeAt(start - 1));
if(lastChar === '[YOURCHARHERE]') {
// do something
}
});
Please keep in mind, that 'input' is only supported down to IE8, but if you don't care about a proprietary browser, you should be fine. I hope this helps.
Inside your function, use the value of the input element to get the last character like $('#input_field').val().substr($('#input_field').val().length - 1) or use your best coding skill to accomplish something similar without accessing the field twice, wink wink.
Use keyup instead:
$('form').on('keyup', function(event) {
var cursorPos = event.target.selectionStart;
var lastTypedChar = elem.target.value[cursorPos - 1];
});
Firstly, This is NOT a repeat question. Most of the similar questions, I've come across, don't preform the desired action interactively (e.g. "onkeydown", "onkeyup", etc.). I need a pure JavaScript (i.e. NO jQuery) function to disallow the first character of a text-based input to be a space or group of spaces given just the elements ID. Here is what I have:
<script type="text/javascript">
/* Don't allow the first character of a "text-based" input element
* (e.g. text-box, text-area, editable-div's) to be a space, given
* the elements ID ([ eID ]). [BEGIN]
*/
function noPrecedingSpace ( eID )
{
var elmt = document.getElementById(eID);
elmt.addEventListener("keydown", function(event)
{
var strg = elmt.value;
var lastChar = strg.charAt(strg.length - 1);
if ((lastChar == " ")||(lastChar == " ")||(strg == ""))
{
return event.which !== 32;
};
});
};
/* Don't allow the first character of a "text-based" input element
* (e.g. text-box, text-area, editable-div's) to be a space, given the
* elements ID ([ eID ]). [END]
*/
</script>
Any ideas as to why this is not working?
What am I doing wrong?
Please Note: "Paste" is already accounted for, and disallowed on the field by another javascript, that, by the way, is working perfectly.
JSFiddle
Returning true/false is the "old" way of managing event propagation. Better now is to use preventDefault()
var elmt = document.getElementById('noSpaces');
elmt.addEventListener('keydown', function (event) {
if (elmt.value.length === 0 && event.which === 32) {
event.preventDefault();
}
});
This just checks... if the current input length is zero then a space is not allowed.
Also see the fiddle.
You can add/modify to check for non-breaking spaces also, if that's really a problem -- match with a regex like Dave's answer, but only if elmt.value.length is > 0
This, however, would let you type non-spaces, then back-up to the start of the field and insert spaces.
A revised fiddle trims leading whitespace as you're typing, but this also won't entirely solve the problem.
var elmt = document.getElementById('noSpaces');
elmt.addEventListener('keydown', function (event) {
if (event.which === 32) {
elmt.value = elmt.value.replace(/^\s+/, '');
if (elmt.value.length === 0) {
event.preventDefault();
}
}
});
You can keep refining it, even taking the current caret position and the currently selected text into account, but ultimately you must .trim() the string you receive on the server, since I (for one) can send you anything I want to send despite all of your javascript efforts to make me enter a "legal" string.
You can test the value of the input with a regular expression to see if it starts with a space and if so remove the spaces from the start of the value;
var input = document.getElementById('noSpaces');
input.addEventListener('keyup', function(event) {
if(/^\s/.test(input.value)) {
input.value = input.value.replace(/^\s+/,'');
}
});
JSFiddle
Thanks to #StephenP, I have come up with this final answer, which is just perfect for my needs ("visitors_name" field):
<script type="text/javascript">
/* Don't allow the first character of a "text-based" input element (e.g. text-box, text-area, editable-div's, etc.) to be a space, given the elements ID ([ eID ]). Also, don't allow more than one space between adjacent words. [BEGIN] */
/* Usage Example: noPrecedingOrDoubleSpace ("visitors_name"); */
function noPrecedingOrDoubleSpace ( eID )
{
var elmt = document.getElementById(eID);
elmt.addEventListener("keydown", function(event)
{
var strg = elmt.value;
var lastChar = strg.charAt(strg.length - 1);
if ((lastChar == " ")||(lastChar == " ")||(strg == ""))
{
if (event.which === 32)
{
event.preventDefault();
};
};
});
};
/* Don't allow the first character of a "text-based" input element (e.g. text-box, text-area, editable-div's, etc.) to be a space, given the elements ID ([ eID ]). Also, don't allow more than one space between adjacent words. [END] */
</script>
Keep in mind that if you just need no space, only at the beginning of the input, #StephenP's answer is probably more practical, and is the real answer to this question, given the title.
Also remember, that just as #StephenP mentioned, real validation is best done in the server-side script (e.g. php). This JavaScript is just to encourage correct input formatting. Nothing more, nothing less.
Big kudos to #StephenP
Thanks!
Final JSFiddle.
I have a question. I'm wanting to run a basic function in Javascript which takes an input field from a form and checks the very first character to ensure it does not have a £ sign (GBP) infront of the value
I can't seem to find the right code anywhere to do this? - Anyone have any idea's... I'm a bit of a noob to all this programming to be honest so any help would be gratefully received.
If you have an input field and you want to get it's value and check the first character of the value, you can do so like this:
<input type="text" id="price">
var str = document.getElementById("price").value;
if (str.charAt(0) == "£") {
// do whatever you need to do if there's a £ sign at the beginning
}
If the £ sign isn't supposed to be there, perhaps you could just safely remove it or ignore it rather than make the end user remove it like this:
var el = document.getElementById("price");
if (el.value.charAt(0) == "£") {
el.value = el.value.substr(1);
}
Assuming your HTML is something like this:
<input type="text" id="my_input" />
<button onClick="checkInput();">Check input</button>
Then you want to build your script like this:
function checkInput() {
var inp = document.getElementById('my_input'); // get the input field
inp = inp.value; // get the value
inp = inp.charAt(0); // get the first character
if( inp == "£") {
// do something
}
}
That can be condensed into:
function checkInput() {
if( document.getElementById('my_input').value.charAt(0) == "£") {
// do something
}
}
The trick to any code-writing is breaking a big problem into smaller ones. Step by step.
charAt should do it
var str = "Foo";
var firstChar = str.charAt(0);