ng-pattern for mobile number validation - angularjs

I am trying to implement mobile number validation on a Visualforce page using Angular JS, but am having problems getting my head around how to write the regex expression.
The requirements, as given to me, are fairly simple:
The number should be 10 digits long (I've already set the maxlength attribute on the field so this one is kind of taken care of already)
It should start with 04 (as it is an Australian mobile)
Only numbers should be allowed.
The regex expression I am using (in the ng-pattern attribute for my phone number input field) is:
^/(04)[0-9]{10}/$
This works up to a point - it does not allow anything other than numbers and does let me enter a 10 digit number starting with 04. However it also lets me enter numbers starting with, for example, 02, 03 etc....
Probably quite a simple thing I'm missing but I've had a look at quite a few sites, including this one, and can't find the answer.
Any help would be hugely appreciated as this one has caused me a few grey hairs already.

Try using this pattern
Use this in ur HTML file:
<input type="text" (keypress)="keyPress($event)" minlength=10 maxlength=10>
Use this in ur JS file:
keyPress(event: any) {
const pattern = /[0-9\+\-\ ]/;
let inputChar = String.fromCharCode(event.charCode);
if (event.keyCode != 8 && !pattern.test(inputChar)) {
event.preventDefault();
}
}

Try this one:
Mobile Number :
//inside view:
<input type="text" class="form-control" ng-model="mobileNo" name="mobileNo" ng-pattern="regEx" />
//inside controller:
$scope.regEx="/^[0-9]{10,10}$/";

For starters I had to create a whole js function for it... and it does validates as you type. here is my full code I hope this can help you get where you need.
This function gets the string every time a key is beign pressed and it allows the carrete to move front, back, delete and backspace. check it out and let me know if it helps you. you can run it on any situation and this is how I would add the "04" validation
//phone validation 10 digits and parenthesis (344)567-0011
function validatePhone(inputId) {
let validKey = false;
const input = document.getElementById(inputId);
let enteredDigits = input.value;
//switch to remove the country code added by default on autoComplete forms.
if (enteredDigits.length > 10 && enteredDigits[0] == '+') {
switch (enteredDigits.length) {
case 12:
enteredDigits = enteredDigits.slice(2);
break;
case 13:
enteredDigits = enteredDigits.slice(3);
break;
case 14:
enteredDigits = enteredDigits.slice(4);
break;
default:
enteredDigits = enteredDigits.replace(/\D+/g, '');
}
}
let newPhone = enteredDigits.replace(/\D+/g, ''); // This replace any character that is not a number.
const key = event.keyCode || event.charCode; // Get the pressed key.
let caretPosition = input.selectionStart; // get the carret position.
// splits, removes the "-" and converts from array to string and gives the needed digits.
const areaCode = newPhone.split('').splice(0, 3).toString().replace(/,/g, '');
const threeDigit = newPhone.split('').splice(3, 3).toString().replace(/,/g, '');
const fourDigit = newPhone.split('').splice(6, 8).toString().replace(/,/g, '');
// Moving carret on different positions. when the numeric keys are being pressed.
// Key >= 48 && key <= 58 number keys.
// Key >= 96 && key <= 105 numeric path number keys.
if ((key >= 48 && key <= 58) || (key >= 96 && key <= 105)) {
validKey = true;
if (threeDigit.length > 0) {
if (caretPosition == 1) {
caretPosition = caretPosition + 1;
} else if (caretPosition == 4 && newPhone.length == 4) {
caretPosition = caretPosition + 2;
} else if (caretPosition == 4 && newPhone.length >= 5) {
caretPosition = caretPosition + 1;
} else if (caretPosition == 5) {
caretPosition = caretPosition + 1;
} else if (caretPosition >= 2 && caretPosition <= 3 && newPhone.length <= 4) {
caretPosition = caretPosition + 1;
}
}
if (fourDigit.length > 0 && caretPosition == 9) {
caretPosition = caretPosition + 1;
}
}
// Key = 8 = Backspace.
else if (key == 8) {
validKey = true;
if (caretPosition == 3 && newPhone.length == 3) {
caretPosition = caretPosition - 1;
} else if (caretPosition == 2 && newPhone.length == 3) {
caretPosition = caretPosition - 1;
} else if (caretPosition == 1 && newPhone.length == 3 && threeDigit.length == 0) {
caretPosition = caretPosition - 1;
}
}
// Key = 46 = Delete. Key =37 = ArrowLeft. Key = 39 = ArrowRight.
else if (key == 46 || key == 39 || key == 37) {
validKey = true;
// Delete
if (key == 46) {
if (caretPosition == 0 && newPhone.length > 3) {
caretPosition = caretPosition + 1;
} else if (caretPosition == 1 && newPhone.length == 3) {
caretPosition = caretPosition - 1;
} else if (caretPosition == 2 && newPhone.length == 3) {
caretPosition = caretPosition - 1;
} else if (caretPosition == 3 && newPhone.length == 3) {
caretPosition = caretPosition - 1;
} else if ((newPhone.length >= 4 && caretPosition == 4) || (newPhone.length >= 4 && caretPosition == 8)) {
caretPosition = caretPosition + 1;
}
}
}
//here is the validation for the country that you need.
if ((newPhone.length == 1 && newPhone[0] != '0') || (newPhone.length >= 2 && newPhone[1] != '4')) {
alert('Must start with 04');
newPhone = '';
}
// Adding the special character for formatting.
if (threeDigit.length > 0 && fourDigit.length == 0) {
newPhone = '(' + areaCode + ')' + threeDigit;
} else if (fourDigit.length > 0 && threeDigit.length == 3) {
newPhone = '(' + areaCode + ')' + threeDigit + '-' + fourDigit;
}
if (!validKey) {
caretPosition = caretPosition - 1;
}
// Set new values.
newPhone = newPhone.substring(0, 13);
input.value = newPhone;
input.focus();
input.setSelectionRange(caretPosition, caretPosition);
}
<form name="myForm"
onsubmit="return validateForm()"
method="post">
Phone number: <input type="text"
id="phoneNumber"
name="fPhone"
onkeyup="validatePhone('phoneNumber')">
<input type="submit"
value="Submit">
</form>

Related

Flutter/Dart Disable Multiple Week Days using enabledDayPredicate of Calendar API / TableCalendar package

At this point, I'm spinning my wheels, but going nowhere and could use some help. I have an array/List of weekdays that I want to disable on my calendar using the enabledPredicateDay function. for example ['sunday', 'monday', 'tuesday'].
return TableCalendar(
calendarBuilders: CalendarBuilders(dowBuilder: (context, day) {
if (day.weekday == DateTime.sunday) {
final text = DateFormat.E().format(day);
return Center(
child: Text(
text,
style: TextStyle(color: Colors.red),
),
);
}
}),
firstDay: kFirstDay,
lastDay: kLastDay,
focusedDay: _focusedDay,
calendarFormat: _calendarFormat,
enabledDayPredicate: (date) {
// this is where we disable any days that the user is not available OR is booked up
var disabledDays = "";
unavailableDays.asMap().forEach((index, value) {
if (index == 0) {
disabledDays = disabledDays + "date.weekday != DateTime.$value";
} else {
disabledDays = disabledDays + " && date.weekday != DateTime.$value";
}
});
date.weekday != disabledDays; // here I'm trying to get some sort of boolean back.
return date.weekday != disabledDays;
}
The problem I'm running into is that I can either only return one day programmatically, let's say in a 'for in' loop, or I need to hardcode it. This is because the return value needs to be a boolean.
I tried combining everything into a string and then converting it to a method so that each day I need disabled can be the return statement like this:
return date.weekday != DateTime.$value && date.weekday != DateTime.$value && date.weekday != DateTime.$value
Everything works fine if I hardcode it like this:
return date.weekday != DateTime.sunday && date.weekday != DateTime.monday && date.weekday != DateTime.tuesday
But I haven't been able to get to this point because I'm getting a string back, but I need a bool.
How do I return multiple days to this particular function?
I figured it out...seems very hacky and maybe this can be improved. What I did here was instantiated a variable for each day. And then, as I go through the weekdays to check which is unavailable with conditional statements, I assign the weekday to the variable if and only if it's unavailable.
var unavailableDay1;
var unavailableDay2;
var unavailableDay3;
var unavailableDay4;
var unavailableDay5;
var unavailableDay6;
var unavailableDay7;
for (var day in daysOfWeek) {
// print(widget.data[day]);
if (widget.data[day] == null) {
unavailableDays.add(day);
}
}
for (var day in unavailableDays) {
if (day == "monday") {
unavailableDay1 = 1;
} else if (day == "tuesday") {
unavailableDay2 = 2;
} else if (day == "wednesday") {
unavailableDay3 = 3;
} else if (day == "thursday") {
unavailableDay4 = 4;
} else if (day == "friday") {
unavailableDay5 = 5;
} else if (day == "saturday") {
unavailableDay6 = 6;
} else if (day == "sunday") {
unavailableDay7 = 7;
}
}
Finally, I check if each of the 7 days has a value, if not null is returned. Thus, it gives me back only days that are enabled! I hope this helps someone! Please help me improve this!
enabledDayPredicate: (date) {
// this is where we disable any days that the user is not available OR is booked up
return date.weekday != unavailableDay1 &&
date.weekday != unavailableDay2 &&
date.weekday != unavailableDay3 &&
date.weekday != unavailableDay4 &&
date.weekday != unavailableDay5 &&
date.weekday != unavailableDay6 &&
date.weekday != unavailableDay7;
},

convert amount in words in angularjs

I need to convert amount in words. For example, the amount I will get it from service is 9876, I need to display in a table "Nine Thousand Eight Hundred and Seventy Six" in a table.
I need to do this using angularjs. Please help me how can I do this.
JSFIDDLE
function convertNumberToWords(amount) {
var words = new Array();
words[0] = '';
words[1] = 'One';
words[2] = 'Two';
words[3] = 'Three';
words[4] = 'Four';
words[5] = 'Five';
words[6] = 'Six';
words[7] = 'Seven';
words[8] = 'Eight';
words[9] = 'Nine';
words[10] = 'Ten';
words[11] = 'Eleven';
words[12] = 'Twelve';
words[13] = 'Thirteen';
words[14] = 'Fourteen';
words[15] = 'Fifteen';
words[16] = 'Sixteen';
words[17] = 'Seventeen';
words[18] = 'Eighteen';
words[19] = 'Nineteen';
words[20] = 'Twenty';
words[30] = 'Thirty';
words[40] = 'Forty';
words[50] = 'Fifty';
words[60] = 'Sixty';
words[70] = 'Seventy';
words[80] = 'Eighty';
words[90] = 'Ninety';
amount = amount.toString();
var atemp = amount.split(".");
var number = atemp[0].split(",").join("");
var n_length = number.length;
var words_string = "";
if (n_length <= 9) {
var n_array = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0);
var received_n_array = new Array();
for (var i = 0; i < n_length; i++) {
received_n_array[i] = number.substr(i, 1);
}
for (var i = 9 - n_length, j = 0; i < 9; i++, j++) {
n_array[i] = received_n_array[j];
}
for (var i = 0, j = 1; i < 9; i++, j++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
if (n_array[i] == 1) {
n_array[j] = 10 + parseInt(n_array[j]);
n_array[i] = 0;
}
}
}
value = "";
for (var i = 0; i < 9; i++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
value = n_array[i] * 10;
} else {
value = n_array[i];
}
if (value != 0) {
words_string += words[value] + " ";
}
if ((i == 1 && value != 0) || (i == 0 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Crores ";
}
if ((i == 3 && value != 0) || (i == 2 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Lakhs ";
}
if ((i == 5 && value != 0) || (i == 4 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Thousand ";
}
if (i == 6 && value != 0 && (n_array[i + 1] != 0 && n_array[i + 2] != 0)) {
words_string += "Hundred and ";
} else if (i == 6 && value != 0) {
words_string += "Hundred ";
}
}
words_string = words_string.split(" ").join(" ");
}
return words_string;
}
<input type="text" name="number" placeholder="Number OR Amount" onkeyup="word.innerHTML=convertNumberToWords(this.value)" />
<div id="word"></div>
I refered this javascript fiddle. But I want to it in a angularjs.
I used this for Angular 8.
Input : 123456789.09 Output : twelve crore thirty four lakh fifty six thousand seven eighty nine point zero nine
n: string;
a = ['zero ', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine ', 'ten ', 'eleven ', 'twelve ', 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen '];
b = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
ngOnInit(): void {
console.log(this.inWords(123456789.09));
}
inWords (num): string {
num = Math.floor(num * 100);
if ((num = num.toString()).length > 11) { return 'overflow'; }
let n;
n = ('00000000' + num).substr(-11).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})(\d{1})(\d{1})$/);
if (!n) { return; } let str = '';
// tslint:disable-next-line:triple-equals
str += (n[1] != 0) ? (this.a[Number(n[1])] || this.b[n[1][0]] + ' ' + this.a[n[1][1]]) + 'crore ' : '';
// tslint:disable-next-line:triple-equals
str += (n[2] != 0) ? (this.a[Number(n[2])] || this.b[n[2][0]] + ' ' + this.a[n[2][1]]) + 'lakh ' : '';
// tslint:disable-next-line:triple-equals
str += (n[3] != 0) ? (this.a[Number(n[3])] || this.b[n[3][0]] + ' ' + this.a[n[3][1]]) + 'thousand ' : '';
// tslint:disable-next-line:triple-equals
str += (n[4] != 0) ? (this.a[Number(n[4])] || this.b[n[4][0]] + ' ' + this.a[n[4][1]]) : 'hundred';
// tslint:disable-next-line:triple-equals
str += (n[5]) ? (this.a[Number(n[5])] || this.b[n[5][0]] + ' ' + this.a[n[5][1]]) : '';
// tslint:disable-next-line:triple-equals
str += (n[6]) ? ((str != '') ? 'point ' : '') + (this.a[Number(n[6])] || this.b[n[6][0]] + ' ' + this.a[n[6][1]]) : '';
// tslint:disable-next-line:triple-equals
str += (n[7] != 0) ? (this.a[Number(n[7])] || this.b[n[7][0]] + ' ' + this.a[n[7][1]]) : '';
return str;
}
Define a filter to convert number to word such as following code:
angular.module('myModuleName')
.filter('convertToWord', function() {
return function(amount) {
var words = new Array();
words[0] = '';
words[1] = 'One';
words[2] = 'Two';
words[3] = 'Three';
words[4] = 'Four';
words[5] = 'Five';
words[6] = 'Six';
words[7] = 'Seven';
words[8] = 'Eight';
words[9] = 'Nine';
words[10] = 'Ten';
words[11] = 'Eleven';
words[12] = 'Twelve';
words[13] = 'Thirteen';
words[14] = 'Fourteen';
words[15] = 'Fifteen';
words[16] = 'Sixteen';
words[17] = 'Seventeen';
words[18] = 'Eighteen';
words[19] = 'Nineteen';
words[20] = 'Twenty';
words[30] = 'Thirty';
words[40] = 'Forty';
words[50] = 'Fifty';
words[60] = 'Sixty';
words[70] = 'Seventy';
words[80] = 'Eighty';
words[90] = 'Ninety';
amount = amount.toString();
var atemp = amount.split(".");
var number = atemp[0].split(",").join("");
var n_length = number.length;
var words_string = "";
if (n_length <= 9) {
var n_array = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0);
var received_n_array = new Array();
for (var i = 0; i < n_length; i++) {
received_n_array[i] = number.substr(i, 1);
}
for (var i = 9 - n_length, j = 0; i < 9; i++, j++) {
n_array[i] = received_n_array[j];
}
for (var i = 0, j = 1; i < 9; i++, j++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
if (n_array[i] == 1) {
n_array[j] = 10 + parseInt(n_array[j]);
n_array[i] = 0;
}
}
}
value = "";
for (var i = 0; i < 9; i++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
value = n_array[i] * 10;
} else {
value = n_array[i];
}
if (value != 0) {
words_string += words[value] + " ";
}
if ((i == 1 && value != 0) || (i == 0 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Crores ";
}
if ((i == 3 && value != 0) || (i == 2 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Lakhs ";
}
if ((i == 5 && value != 0) || (i == 4 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Thousand ";
}
if (i == 6 && value != 0 && (n_array[i + 1] != 0 && n_array[i + 2] != 0)) {
words_string += "Hundred and ";
} else if (i == 6 && value != 0) {
words_string += "Hundred ";
}
}
words_string = words_string.split(" ").join(" ");
}
return words_string;
};
});
Then in your templates (views) use this filter as follow:
{{amount | converToWord}}
For example to show inserted value in an input field:
<input type="text" name="number" placeholder="Number OR Amount" ng-model="myValue" />
<div id="word">{{myValue | convertToWord}}</div>

Trouble implementing a recursive call in C

So I'm I've been working with C for the very first time, and I think I'm having trouble using recursion. For instance, to return a value for a recursive call in C#, I might use return methodRecursiveCall(parameter). In C, I have this statement, which is a part of a roman numeral converter:
int convert(char *s)
{
int val = 0;
int index = 0;
int length = strlen(s);
while (length >1)
{
if (s[index] == 'I')
{
if(s[index + 1] == 'V' || s[index + 1] == 'X' || s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
{
val--;
index++;
length--;
convert(&(s[index]));
}
else
{
val++;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'V')
{
if(s[index + 1] == 'X' || s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
{
val = val - 5;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 5;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'X')
{
if(s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
{
val = val - 10;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 10;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'C')
{
if((s[index + 1]) == 'D' || (s[index + 1]) == 'M')
{
val = val - 100;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 100;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'D')
{
if(s[index + 1] == 'M')
{
val = val - 500;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 500;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'M')
{
val = val + 500;
index++;
length--;
convert(&(s[index]));
}
}
return val;
}
My question specifically is about the convert(&(s[index]));, which is meant to be a recursive call. It is meant to convert an entire Roman numeral to decimal, however it only converts the first character. That is normally where I would put a 'return'. I'm not sure how to pull this off in C, however.
For this fragment from near the end:
if (s[index] == 'M')
{
val = val + 500;
index++;
length--;
convert(&(s[index]));
}
You probably want something like:
if (s[index] == 'M')
val = 1000 + convert(&s[index+1]);
You know that the M maps to 1,000; the total value will be 1000 + the value of what follows the M, which is what the expression states. Note that the parentheses around s[index+1] are not necessary.
You'll need to make similar changes throughout the code. You also need to review why you have iteration mixed in with recursion; you should use one or the other.
Note that your code doesn't seem to cover L aka 50.
Personally, I think this is not the best way to do the conversion. All else apart, it will be hard to spot that MXMC is invalid. My code uses an array of structures containing a string and the corresponding value (M and 1000; CM and 900) etc, and once one of the values has been used up (CM can only be used once; M can be used multiple times; CD can be used once; C can be used multiple times — that's coded too), then it can't appear again later. And it uses iteration rather than recursion.
Here's a moderately simple adaptation and fix to your code. It works OK for converting 'known to be valid' Roman numbers; it doesn't work well for validating them.
#include <stdio.h>
int convert(const char *s);
int convert(const char *s)
{
int val = 0;
int i = 0;
if (s[i] == '\0')
return 0;
if (s[i] == 'I')
{
if (s[i + 1] != 'I' && s[i + 1] != '\0')
val = convert(&s[i + 1]) - 1;
else
val = 1 + convert(&s[i + 1]);
}
if (s[i] == 'V')
val = 5 + convert(&s[i + 1]);
if (s[i] == 'X')
{
if (s[i + 1] == 'L' || s[i + 1] == 'C' || s[i + 1] == 'D' || s[i + 1] == 'M')
val = convert(&s[i + 1]) - 10;
else
val = 10 + convert(&s[i + 1]);
}
if (s[i] == 'L')
val = 50 + convert(&s[i + 1]);
if (s[i] == 'C')
{
if ((s[i + 1]) == 'D' || (s[i + 1]) == 'M')
val = convert(&s[i + 1]) - 100;
else
val = 100 + convert(&s[i + 1]);
}
if (s[i] == 'D')
val = 500 + convert(&s[i + 1]);
if (s[i] == 'M')
val = 1000 + convert(&s[i + 1]);
return val;
}
int main(void)
{
const struct roman
{
const char *str;
int num;
} test[] =
{
{ "I", 1 },
{ "II", 2 },
{ "III", 3 },
{ "IV", 4 },
{ "V", 5 },
{ "VI", 6 },
{ "VII", 7 },
{ "VIII", 8 },
{ "VIIII", 9 },
{ "IX", 9 },
{ "X", 10 },
{ "XI", 11 },
{ "XII", 12 },
{ "XIII", 13 },
{ "XIV", 14 },
{ "XV", 15 },
{ "XVI", 16 },
{ "XVII", 17 },
{ "XVIII", 18 },
{ "XIX", 19 },
{ "XVIIII", 19 },
{ "XX", 20 },
{ "XXI", 21 },
{ "XXX", 30 },
{ "XL", 40 },
{ "L", 50 },
{ "LXXVIII", 78 },
{ "XCVIII", 98 },
{ "IC", 99 },
{ "XCIX", 99 },
{ "C", 100 },
{ "D", 500 },
{ "M", 1000 },
{ "MMMDCCCLXXXVIII", 3888 },
{ "MDCMMCCLXIIIIII", 3666 }, // Not good for validating!
};
enum { NUM_TEST = sizeof(test) / sizeof(test[0]) };
for (int i = 0; i < NUM_TEST; i++)
{
int value = convert(test[i].str);
printf("%s %15s = %4d vs %4d\n", (value == test[i].num) ? "== PASS ==" : "!! FAIL !!",
test[i].str, value, test[i].num);
}
return 0;
}
Sample output:
== PASS == I = 1 vs 1
== PASS == II = 2 vs 2
== PASS == III = 3 vs 3
== PASS == IV = 4 vs 4
== PASS == V = 5 vs 5
== PASS == VI = 6 vs 6
== PASS == VII = 7 vs 7
== PASS == VIII = 8 vs 8
== PASS == VIIII = 9 vs 9
== PASS == IX = 9 vs 9
== PASS == X = 10 vs 10
== PASS == XI = 11 vs 11
== PASS == XII = 12 vs 12
== PASS == XIII = 13 vs 13
== PASS == XIV = 14 vs 14
== PASS == XV = 15 vs 15
== PASS == XVI = 16 vs 16
== PASS == XVII = 17 vs 17
== PASS == XVIII = 18 vs 18
== PASS == XIX = 19 vs 19
== PASS == XVIIII = 19 vs 19
== PASS == XX = 20 vs 20
== PASS == XXI = 21 vs 21
== PASS == XXX = 30 vs 30
== PASS == XL = 40 vs 40
== PASS == L = 50 vs 50
== PASS == LXXVIII = 78 vs 78
== PASS == XCVIII = 98 vs 98
== PASS == IC = 99 vs 99
== PASS == XCIX = 99 vs 99
== PASS == C = 100 vs 100
== PASS == D = 500 vs 500
== PASS == M = 1000 vs 1000
== PASS == MMMDCCCLXXXVIII = 3888 vs 3888
== PASS == MDCMMCCLXIIIIII = 3666 vs 3666
Note that the last 'number' is horribly bogus (1000 + 500 + 900 + 1000 + 100 + 100 + 50 + 10 + 1 + 1 + 1 + 1 + 1 + 1).

Validating table rows in a LiveCycle form

I am developing a LiveCycle form that has a table on it that can have a variable amount of rows. I want to only validate it if there is data in one of the columns but not all of them. So I would skip the validation if the row is blank or all the columns in that row are filled in.
Any ideas how to do this. How would I loop through the rows of a table.
Thanks in advance,
Paul
I would tweat your answer a little bit by replacing resolveNodes that is quite slow.
In order to get row count you can use instanceManager TrainerForm._TrainerTable.count
To get a specific item from row list use <RowName>.all.item(index). Be carefull while using this construct because it requires a least one row. Row is a shourtcat for Row[0].
Here is your code with with my upgrades:
var rowCount = TrainerForm.TrainerTable._TrainerData.count;
for (var i=0;i<rowCount;i++)
{
if (TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerName.rawValue == null &&
TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerPrepHrs.rawValue == null &&
TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerArea.selectedIndex == -1 &&
TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerActivity.rawValue == null )
;//check the case where all rows are blank which is valid
else
{
if (TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerName.rawValue == null)
{
TrainerTableValid = false;
TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerName.ui.#textEdit.border.fill.color").value = "255,0,0";
}
if (TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerPrepHrs.rawValue == null)
{
TrainerTableValid = false;
TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerPrepHrs.ui.#numericEdit.border.fill.color").value = "255,0,0";
}
if (TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerArea.selectedIndex == -1)
{
TrainerTableValid = false;
TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerArea.ui.#choiceList.border.fill.color").value = "255,0,0";
}
if (TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerActivity.rawValue == null)
{
TrainerTableValid = false;
TrainerForm.TrainerTable.TrainerData.all.item(i).TrainerActivity.ui.#textEdit.border.fill.color").value = "255,0,0";
}
}
}
You can put your script in validate event of your cells or whole row. The result of validation script is determined by the last line result (true or false); To make validations failure visible you can set form level validation (File->Form Properties->Form Validation->Color Failed Fields).
Another approach (that I personally prefer) is setting field as required using code fieldName.manadatory = "error" when some conditions are met. In order to make field optional just put fieldName.manadatory = "disabled".
Here is what I ended up doing. First I made all fields optional. Then I execute this code from a click event of a button.
var fields = xfa.resolveNodes("TrainerForm.TrainerTable.TrainerData[*]");
for (var i=0;i<fields.length;i++)
{
if (TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerName.rawValue == null &&
TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerPrepHrs.rawValue == null &&
TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerArea.selectedIndex == -1 &&
TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerActivity.rawValue == null )
;//check the case where all rows are blank which is valid
else
{
if (TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerName.rawValue == null)
{
TrainerTableValid = false;
xfa.resolveNode("TrainerForm.TrainerTable.TrainerData[" + i + "].TrainerName.ui.#textEdit.border.fill.color").value = "255,0,0";
}
if (TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerPrepHrs.rawValue == null)
{
TrainerTableValid = false;
xfa.resolveNode("TrainerForm.TrainerTable.TrainerData[" + i + "].TrainerPrepHrs.ui.#numericEdit.border.fill.color").value = "255,0,0";
}
if (TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerArea.selectedIndex == -1)
{
TrainerTableValid = false;
xfa.resolveNode("TrainerForm.TrainerTable.TrainerData[" + i + "].TrainerArea.ui.#choiceList.border.fill.color").value = "255,0,0";
}
if (TrainerForm.TrainerTable.resolveNode("TrainerData[" + i + "]").TrainerActivity.rawValue == null)
{
TrainerTableValid = false;
xfa.resolveNode("TrainerForm.TrainerTable.TrainerData[" + i + "].TrainerActivity.ui.#textEdit.border.fill.color").value = "255,0,0";
}
}
}

datagridview and NumericUpDown?

I have a NumericUpDown box and depending on its value, I want to insert the letter into a DataGridView. Here is my code, but it does not insert into the column I want.
if (MarkNumericUpDown.Value < 50)
{
//dataGridView1.Rows.Add("F");
}
else if (MarkNumericUpDown.Value > 50 && MarkNumericUpDown.Value <= 64)
{
//dataGridView1.Rows.Add("D");
}
else if (MarkNumericUpDown.Value > 64 && MarkNumericUpDown.Value <= 68)
{
//dataGridView1.Rows.Add("D+");
}
else if (MarkNumericUpDown.Value > 68 && MarkNumericUpDown.Value <= 72)
{
//dataGridView1.Rows.Add("C-");
}
else if (MarkNumericUpDown.Value > 72 && MarkNumericUpDown.Value <= 76)
{
//dataGridView1.Rows.Add("C");
}
else if (MarkNumericUpDown.Value > 76 && MarkNumericUpDown.Value <= 80)
{
//dataGridView1.Rows.Add("C+");
}
else if (MarkNumericUpDown.Value > 80 && MarkNumericUpDown.Value <= 84)
{
//dataGridView1.Rows.Add("B-");
}
else if (MarkNumericUpDown.Value > 88 && MarkNumericUpDown.Value <= 92)
{
//dataGridView1.Rows.Add("B");
}
else if (MarkNumericUpDown.Value > 92 && MarkNumericUpDown.Value <= 96)
{
//dataGridView1.Rows.Add("B+");
}
else if (MarkNumericUpDown.Value > 96 && MarkNumericUpDown.Value <= 100)
{
//dataGridView1.Rows.Add("A-");
}
I suspect you are more interested in the Cells values rather than the Rows values. Try something like this:
if (MarkNumericUpDown.Value < 50)
{
int index = dataGridView1.Rows.Add();
dataGridView1.Rows[index].Cells[1].Value = "F";
}
else if (MarkNumericUpDown.Value > 50 && MarkNumericUpDown.Value <= 64)
{
int index = dataGridView1.Rows.Add();
dataGridView1.Rows[index].Cells[2].Value = "D";
}
Update:
Judging by your picture, it looks like you are only concerned about EDITING a row and not ADDING a row. If this is the case, you need to keep track of which row you are concerned with and which column you are concerned with (please change the variable names to something that makes more sense for your application):
int indexOfRowICareAbout = 0;
int indexOfColumnIStoreLettersIn = 4; //Judging by your picture
if (MarkNumericUpDown.Value < 50)
{
dataGridView1.Rows[indexOfRowICareAbout].Cells[indexOfColumnIStoreLettersIn].Value = "F";
}
else if (MarkNumericUpDown.Value > 50 && MarkNumericUpDown.Value <= 64)
{
dataGridView1.Rows[indexOfRowICareAbout].Cells[indexOfColumnIStoreLettersIn].Value = "D";
}

Resources