I have an upcoming project.
I have a validation program to write, beginner's level.
I've written the code most part, but in case the user inputs the year in 2 digit form I need to convert it into 4-digit form.
Then I need to declare a new variable and extract using '.subscript' the 4-digits from the National Identification Number which is a 13 digit number.
I've written most of the code so far ( I won't post it all of it here), but the code won't execute when it reaches yearString = yearString.substring(2,4).
function cnpVal() {
var cnpString = document.getElementById('lblcnp').value; //13 digit number
var dayString = document.getElementById('txtday').value;
var monthString = document.getElementById('txtmonth').value;
var yearString = document.getElementById('txtyear').value; //2 or 4 digit number
arrayCnp = cnpString.split('');
if (yearString.length != 4) {
alert("Year format requires you to enter 4 digits");
return false;
}
else {
yearString = yearString.substring(2,4);
}
Basically I need the yearString variable declared and working for a 4 digit year, i.e. 1987.
Obviously it won't work as 1987 = ["1", "9", "8", "7"] is a 4 string array, but I don't have a string at index 4.
I hope I've made myself understood and sorry for the ignorance. I stand to be corrected.
Greets.
yearString = yearString.substring(2,4); will extract the last 2 digits from yearString. String.prototype.substring accepts a start index as the first argument and an optional end index which is not included in the extraction, so yearString.substring(2,4) will take the character at index 2 and 3, and does not include the character at index 4.
Documentation for substring is available HERE
You could also try String.prototype.substr(start, length) which takes the start index of the sub string you need as the first argument and how many characters you want to extract as the second argument.
Documentation for substr is available HERE
Related
I want to grab the user input from an input tag including everything after the # symbol and up to a space if the space exists. For example:
If the user input is "hello#yourname"
I want to grab "yourname"
If the user input is "hello#yourname hisname"
I want to grab "yourname" because it is after the # symbol and ends at the space.
I have some code written that attempts to grab the user input based on these rules, but there is a bug present that I can't figure out how to fix. Right now if I type "hello#yourname hisname"
My code will return "yourname hisn"
I don't know why the space and four characters "hisn" are being returned. Please help me figure out where the bug is.
Here is my function which performs the user input extraction.
handleSearch(event) {
let rawName, nameToSearch;
rawName = event.target.value.toLowerCase();
if (rawName.indexOf('#') >= 0 && rawName.indexOf(' ') >= 0) {
nameToSearch = rawName.substr(rawName.indexOf('#') + 1, rawName.indexOf(' ') - 1);
} else if (rawName.indexOf('#') >= 0 && rawName.indexOf(' ') < 0) {
nameToSearch = rawName.substr(rawName.indexOf('#') + 1);
} else {
nameToSearch = '';
}
return nameToSearch;
}
Working example:
handleSearch(event) {
let rawName = event.target.value.toLowerCase();
if (rawName.indexOf("#") === -1) {
return '';
}
return (rawName.split("#")[1].split(" "))[0];
}
You have to handle a lack of "#", but you don't need to handle the case where there is a space or not after the "#". The split function will still behave correctly in either of those scenarios.
Edit: The specific reason why OP's code doesn't work is because the substr method's second argument is not the end index, but the number of characters to return after the start index. You can use the similar SUBSTRING method instead of SUBSTR to make this easier. Change the line after the first if statement as follows:
nameToSearch = rawName.substring(rawName.indexOf('#') + 1, rawName.indexOf(' '));
const testCases = [
"hello#yourname",
"hello#yourname hisname"
];
for (let test of testCases) {
let re = /#(.*?)(?:\s|$)/g;
let result = re.exec(test);
console.log(result[1]);
}
Use regex instead if you know how the string will be created.
You could do something like this--
var string = "me#somename yourname";
var parts = string.split("#");
var parts2 = parts[1];
var yourPart = parts2.split(" ");
console.log(yourPart[0]);
NOTE:
I am suggesting it just because you know your string structure.
Suggestion
For your Piece of code I think you have some white space after hisn that is why it is returning this output. Try to replace all the white spaces with some character see if you are getting any white space after hisn.
I'm not sure of the language your code is in (there are several it 'could be', probably Javascript), but in most languages (including Javascript) a substring function 'starts at' the position of the first parameter, and then 'ends at' that position plus the second parameter. So when your second parameter is 'the position of the first space - 1', you can substitute 'the position of the first space - 1' with the number 13. Thus, you're saying 'get a substring by starting one after the position of the first # character i.e. position 6 in a zero-based system. Then return me the next 13 characters.'
In other words, you seem to be trying to say 'give me the characters between position 6 and position 12 (inclusive)', but you're really saying 'give me the characters between position 6 and position 18 (inclusive)'.
This is
y o u r n a m e h i s n
1 2 3 4 5 6 7 8 9 10 11 12 13
(For some reason I can't get my spaces and newlines to get preserved in this answer; but if you count the letters in 'yourname hisn' it should make sense :) )
This is why you could use Neophyte's code so long as you can presume what the string would be. To expand on Neophyte's answer, here's the code I would use (in the true branch of the conditional - you could also probably rename the variables based on this logic, etc.):
nameToSearch = rawName.substr(rawName.indexOf('#') + 1;
var nameFromNameToSearch = nameToSearch.substr(nameToSearch.indexof(' ') - 1;
nameFromNameToSearch would contain the string you're looking for. I haven't completely tested this code, but I hope it 'conceptually' gives you the answer you're looking for. Also, 'conceptually', it should work whether there are more than one '#' sign, etc.
P.S. In that first 'rawName.substr' I'm not giving a second parameter, which in Javascript et al. effectively says 'start at the first position and give me every character up to the end of the string'.
I need to validate a textbox field that will contain a range (separated by -). Following are the requirements:
Need to validate year & month ranges, and have values like 0.5 - 3.11 for denoting 5 months to 3 years and 11 months
The decimal places can be max 2 and 11 is max value in decimal place while 0 is minimum.
Both parts separated by hyphen -, may or may not include 1 blank space (only before and after hyphen).
The left part must always be less than right part.
Should validate values like:
1
2.3
2.3 - 4.6
2.3-4.6
2.4-2.1 is invalid
No negative required for the float values
I tried to generate some regex but the closest was:
(0|([1-9][0-9]{0,9}))(\.[0-9]{1,2})?(-)(0|([1-9][0-9]{0,9}))(\.[0-9]{1,2})?
but it can only validate values like 1.3-1.9 but does not compares the left and right part. And only a single digit value is also not validated.
You could do most of the validation with a regex, but checking that the first value is less than the second value would have to be done in code rather than a regex.
function isRangeStringValid(r) {
if (!r.match(/(0|[1-9]\d*)\.(\d|1[01]) ?- ?(0|[1-9]\d*)\.(\d|1[01])/)) {
return false;
}
var y1 = parseInt(RegExp.$1);
var m1 = parseInt(RegExp.$2);
var y2 = parseInt(RegExp.$3);
var m2 = parseInt(RegExp.$4);
return (y1<y2 || (y1==y2 && m1<m2));
}
yet another variant function with regexp for solution
function israngev(r){
var res = r.match(/^\d+$|^\d+\.(\d|1[01])$|^(\d+\.(\d|1[01])) ?- ?(\d+\.(\d|1[01]))$/);
return res!=null &&
(!(res[1]||res[2]||res[4]) ||
(res[1]!=null ||
(res[4]-res[2]>0)))}
What I'm trying to achieve is a code checker. Only the first 4 numbers are important, the other numbers can be any number. The form will be used for users to put in productcodes.
The problem is that if the variable changes to say, 5 numbers the variable is false.
See below example:
http://jsfiddle.net/MZfxs/3/
If the user puts in the numbers 3541 the box changes color, but if the user put in the remaining numbers the value is set to false.
Additionally I'm trying to make the box only change color when 13 numbers are inserted AND the first 4 numbers are matching, in that order.
Solved!
Working Example:
http://jsfiddle.net/MZfxs/8/
If I understood correctly, you need a field value validation and the requirement is the value should start from 4 numbers like 7514 or 9268. Here you can use a regular expression to validate input value like:
// Will work for " 123433 " or "12345634 ", etc.
var value = $(this).val(),
re = /^\s*(\d{4})(\d+)\s*$/, // better to initialize only once somewhere in parent scope
matches = re.exec(value),
expectedCode = 3541,
expectedLength = 13;
if(!!matches) {
var code = matches[1]; // first group is exactly first 4 digits
// in matches[2] you'll find the rest numbers.
if(value.length == expectedLength && code == expectedCode) {
// Change the color...
}
}
Also if your requirement is strict to length of 13 than you can modify the regular epression to
var re = /^(\d{4})(\d{9})$/;
and retrieve first 4 numbers in first group and rest 9 in second group:
var matches = re.exec(value);
if(!!matches) {
var first4Digits = matches[1],
rest9Digits = matches[2];
// ...
// Also in this way you'll not need to check value.length to be 13.
}
You can break the string each time on key event fires. You can do this by calling js substring() method and take the first four characters and check it.
Try to use this:
<script>
$("input").keyup(function () {
var value = $(this).val();
$("p").text(value);
var value2 = $(this).val().substr(0,4);
if(value2 == 3541){
$(".square").css("background-color","#D6D6FF");
}else{
$(".square").css("background-color","yellow");
}
})
</script>
Using Jquery TableSorter, I am creating a custom parser to sort elapsed time <td>s that contain "'#' year(s) * '#' month(s)". When I use the function
$('.techtable td:nth-child(6)').each(function(){
// console.log($(this));
var that = $(this).text();
var myRegexp = /([\d]+) ([\w]+)(?: ([\d]+) ([\w]+))?/;
var match = myRegexp.exec($(this).text());
console.log(match);
});
from the command line, each index contains an array of length 5, looking like this:
["7 months", "7", "months", undefined, undefined]
to this:
["3 years 3 months", "3", "years", "3", "months"]
depending on whether or not the elapsed time has just a month or year element, and then the other. To parse the text, I use regex to gather each element, and then use JS to test whether there are multiple elements or not, and if 1 element only, then wheher it begins with "y" or "m", and return the number of months, so the parser can sort the <td>s by number of months in integer form.
The parser passes in each element into the function as parameter "s". when i try regex on "s" directly, it is not returning an array of length 5, it is truncating it to 3 (whether or not I am running the line that truncates it if index 3 is typeof 'undefined'). When I use the console to directly use this function:
$('.techtable td:nth-child(6)').each(function(){
// console.log($(this));
var that = $(this).text();
var myRegexp = /([\d]+) ([\w]+)(?: ([\d]+) ([\w]+))?/;
var match = myRegexp.exec($(this).text());
if (typeof match[3] == 'undefined') {match.length = 3;};
console.log(match);
});
the regex returns the arrays properly, with the array truncated if it only has 1 element (year or month). Here is the code for the custom parser:
var myRegexp = /([\d]+) ([\w]+)(?: ([\d]+) ([\w]+))?/;
var match = myRegexp.exec(s);
var order = [];
console.log(match);
if (typeof match[3] == 'undefined') {match.length = 3;};
// 1 element case:
// month
if (match.length = 3) {
if (match[2][0] == "m") {
order.push(match[1]);
}
// year
if (match[2][0] == "y") {
order.push(match[1]*12);
}
// both elements
} else {
order.push(match[1]*12 + match[3]);
}
s = order;
return s;
},
The fiddle is here. The Elapsed parser is second from the bottom of the JS panel. As you can see, since I can't get the months from the array (indices 4 and 5), I can not calculate the months, and thus the sorting only incorporates years, and the months are sorted by their original HTML placement. What am I missing? (I'm learning.... so direction is appreciated more than an fix, but I won't turn it down.)
Yes I realize the JS fiddle is loaded (first part is TableSorter, to maintain functionality for verification(click on headers to sort), but all you need to focus on is the last part of the code (reference the '//Table Sorter dateSorter' to see how a correct parser should look). The section '//Table Sorter elapsedSorter' is where my two attempts are, the first part is the working code I use in the console, and the seconde part is the parser, which is somehow deleting the last two indices in the array, thus loosing the month information to calculate.
Guess I'll have to add Regex, and a personal rating of 1, since I've wasted almost an entire day on this.
if (match.length = 3) {
You meant this?
if (match.length == 3) {
To help you further, when you write conditions with one constant and a variable, you can write them like this instead:
if (3 = match.length) {
This would now cause a JavaScript error instead of silently getting turned into an assignment that always yields true.
In JavaScript, 12 + '4' == '124', so you have to be careful with numbers and the + operator. In languages such as PHP you don't have this problem, because they have an operator for string concatenations ;-)
var myRegexp = /([\d]+) ([\w]+)(?: ([\d]+) ([\w]+))?/;
var match = myRegexp.exec(s);
var order = [];
if (typeof match[3] == 'undefined') {
if (match[2][0] == "m") {
order.push(parseInt(match[1]));
}
// year
if (match[2][0] == "y") {
order.push(parseInt(match[1])*12);
}
// both elements
} else {
order.push(parseInt(match[1])*12 + parseInt(match[3]));
}
s = order;
return s;
Btw use parseInt(x, 10) if you expect fields to have leading zeroes (which would otherwise result in 0 being returned). Thanks fudgey!
First of all,
What am i doing ?
I have to set the limit of emails in our product in webpage.It's handled with the javascript for validation.It handles upto 8 digit numbers fine. But in our QA team enters the more than 17 digit number in the text box of other email field.It throw the negative message.What can i do ???
My sample code is:
if(form.otherEmails) {
if(validEmailArray.endsWith(',')){
var otherEmailLength = validEmailArray.substring(0,validEmailArray.length-1).split(",");
var setLimitOtherEmail = window.parent.document.getElementById('setLimitOtherEmail').value;
if(setLimitOtherEmail == '-1'){
form.otherEmails.value = otherEmailLength;
}
else if(otherEmailLength.length <= setLimitOtherEmail){
form.otherEmails.value = otherEmailLength;
}
else{
alert("More than "+setLimitOtherEmail+ " " +"Recipient emailIds not allowed in this section.\nIf you want to send it to more recipients, Please create a Bulk Contact Group.");
form.otherEmails.focus();
return false;
}
}
else
form.otherEmails.value = validEmailArray;
}
This is due to the limit being a string, and when a string is being compared to a number (length) the number is coerced into a string, not the other way around.
These are then compared lexicographically - and lexicographically "9" is more (>) than "19".
You need to use parseInt(setLimitOtherEmail, 10) to get the value as a number before comparing them.
Try parsing each of the numbers into Integers before performing any comparison operations on them.
var setLimitOtherEmail = parseInt(window.parent.document.getElementById('setLimitOtherEmail').value);
Other than that are you certain otherEmailLength is actually the number that you want? From the looks of it you are taking the substring of validEmail array and splitting it on "," but it doesn't look like you actually get the length of the array. Try adding .length to the end of the value of otherEmailLength.
var otherEmailLength = validEmailArray.substring(0,validEmailArray.length-1).split(",").length;