Extracting Numerica Data Pairs from Text Box

M

Michael Hill

Hi, folks.

I am writing a Javascript program that accepts (x, y) data pairs from
a text box and then analyzes that data in various ways. This is my
first time using text area boxes; in the past, I have used individual
entry fields for each variable. I would now like to use text area
boxes to simplify the data entry (this way, data can be produced by
another program--FORTRAN, "C", etc.--but analyzed online, so long as
it is first converted to plain-text).

In any case, extracting the data from the box is tripping me up. I
would like to prompt the user to input the (x, y) data pairs one per
line:

1 2
2 4
3 9
etc.

Could somebody please direct me to code for extracting these values
from the text box and converting them into meaningful floating-point
numbers?

Thanks,


Michael
 
R

RobG

Michael said:
Hi, folks.

I am writing a Javascript program that accepts (x, y) data pairs from
a text box and then analyzes that data in various ways. This is my
first time using text area boxes; in the past, I have used individual
entry fields for each variable. I would now like to use text area
boxes to simplify the data entry (this way, data can be produced by
another program--FORTRAN, "C", etc.--but analyzed online, so long as
it is first converted to plain-text).

In any case, extracting the data from the box is tripping me up. I
would like to prompt the user to input the (x, y) data pairs one per
line:

1 2
2 4
3 9
etc.

Could somebody please direct me to code for extracting these values
from the text box and converting them into meaningful floating-point
numbers?

You should require your users to enter each pair separately;
otherwise you are making your job really hard. If you allow
multiple lines of input, you must split your lines first, then
test that each line has valid input (or reject the lot if an
error is found). There is no reasonable way of doing this.
Another issues is that of the comma: ",". It is frequently used
as both a thousands separator, a decimal point and a number
delimiter.

For example, is the text "1,200" to be interpreted as one
thousand two hundred, one point two zero zero or a coordinate
pair where x=1 and y=200?

The code below takes the input and checks that only 0-9, ',' and
'.' have been entered. It then replaces the comma with a space,
removes leading and trailing spaces and splits what remains into
an array. It then checks that the first two elements of the
array pass a test as floats. The idea is that whilst alpha
characters may be OK in numbers in some contexts (e.g. 2.0e3),
in this case they aren't.

I have included two tests: the first uses a regular expression
to check for 1 to 4 digits optionally followed by a decimal
point and one or two more digits. The second just converts the
elements to floats, then evaluates if the result matches the
pre-parsed value. The theory is that if they convert OK then
all is well.

Just keep whichever test you feel is better and delete the other
code block.

If you want to include multiple lines of input, include newline
'\n' in the initial test and split the lines using
t.split('\n'). Then use a loop to run the resulting array
elements through the testing currently done on the input, split
the elements into (x y) and do the second set of testing.

Let us know if you want more help, I can post a text area
version if you *really* want it.

--
Rob

<script type="text/javascript">
function getCoords(t) {
var xy;
var eMsg = 'Your input is invalid.'
+ '\nPlease enter coordinates as two values '
+ 'separated by a space or comma. \ne.g. '
+ '23.5 12.2 or 23.5,12.2';

// test input is only digits, spaces or commas
if (t.search(/[^\d\.,]/) == -1) {
alert(eMsg);
return false;
}

// Process input
t = t.replace(/,/g, ' '); // replace comma with space
t = t.replace(/^\s*/, ''); // replace leading spaces
t = t.replace(/\s*$/, ''); // replace trailing spaces
xy = t.split(/\s+/g); // split into x & y

// regular expression test
if ( /^\d{1,4}(\.\d\d?)?$/.test(xy[0])
&& /^\d{1,4}(\.\d\d?)?$/.test(xy[0]) ) {
} else {
alert(eMsg)
return false;
}

// parseFloat test
if (xy[0] == parseFloat(xy[0])
&& xy[1] == parseFloat(xy[1])) {
} else {
alert(eMsg)
return false;
}

return (xy);
}
</script>

<form action="">
<input type="text" name="coords" size="20">
<input type="button" value="click me" onclick="
var xy = getCoords(this.form.coords.value);
if (xy) alert('x = ' + xy[0] + '\ny = ' + xy[1]);
">
</form>
 
M

Michael Hill

Hi, Rob.

Thanks for the help.

Yes, I would like to see a textarea version block of code. If you
could post it, that would be fantastic.

Thanks a lot.


Michael
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated
Fri, 11 Feb 2005 02:26:54, seen in RobG
function getCoords(t) {
var xy;
var eMsg = 'Your input is invalid.'
+ '\nPlease enter coordinates as two values '
+ 'separated by a space or comma. \ne.g. '
+ '23.5 12.2 or 23.5,12.2';

// test input is only digits, spaces or commas
if (t.search(/[^\d\.,]/) == -1) {
alert(eMsg);
return false;
}

// Process input
t = t.replace(/,/g, ' '); // replace comma with space
t = t.replace(/^\s*/, ''); // replace leading spaces
t = t.replace(/\s*$/, ''); // replace trailing spaces
xy = t.split(/\s+/g); // split into x & y

// regular expression test
if ( /^\d{1,4}(\.\d\d?)?$/.test(xy[0])
&& /^\d{1,4}(\.\d\d?)?$/.test(xy[0]) ) {
} else {
alert(eMsg)
return false;
}

// parseFloat test
if (xy[0] == parseFloat(xy[0])
&& xy[1] == parseFloat(xy[1])) {
} else {
alert(eMsg)
return false;
}

return (xy);
}

Or, partly tested, ...

function getCoords(t) {
var eMsg = 'Your input is invalid.'
+ '\nPlease enter co-ordinates as two values '
+ 'separated by a space or comma. \ne.g. '
+ '23.5 12.2 or 23.5,12.2';

A = /^\s*(([+-]?\d{1,4})(\.\d\d?)?)[, ](([+-]?\d{1,4})(\.\d\d?)?)\s*$/.exec(t)
if (!A) { alert(eMsg) ; return false }
return [+A[1], +A[4]] }

?

It would be nice to allow either a comma followed by \s* or \s+ :

A = /^\s*(([+-]?\d{1,4})(\.\d\d?)?)(,\s*|\s+)(([+-]?\d{1,4})(\.\d\d?)?)\s*$/.exec(F.X0.value)
if (!A) { alert(eMsg) ; return false }
return [+A[1],+A[5]] }


I expect A = ... exec(t) to be transmitted as single lines; if you see
them broken, then your end broke them.
 
R

RobG

Michael said:
Hi, Rob.

Thanks for the help.

Yes, I would like to see a textarea version block of code. If you
could post it, that would be fantastic.

I've taken the approach that you want to validate the input, then
send it to your app. The code checks input and writes it back to
the screen. Errors are highlighted for correction, the actual
text in the text area is not modified at all. I think it is much
more user-friendly to let the user modify their own keystrokes.

When the input passes all the tests, the script returns the
coords as an array. Otherwise, it returns false.

I have added a conditional submit button in case you want to to
do that. Of course if you do submit it, you still need to do
full validation on the server, client-side scripting does not
guarantee anything.

I've taken a few shortcuts with styles and layout - hey, it's
just a demo!

There was an error in my original script (cut 'n paste...)

if ( /^\d{1,4}(\.\d\d?)?$/.test(xy[0])
&& /^\d{1,4}(\.\d\d?)?$/.test(xy[0]) ) {

Only tests xy[0] (twice!) - it should have been:

if ( /^\d{1,4}(\.\d\d?)?$/.test(xy[0])
&& /^\d{1,4}(\.\d\d?)?$/.test(xy[1]) ) {


--
Rob

<html>
<head>
<title>play</title>
<style type="text/css">
body {font-family: sans-serif}
..coord {color: black; font: 10pt courier;}
..tip {color: #444477; font-size:80%;
font-family: arial, sans-serif;}
</style>
</head>
<body>

<script type="text/javascript">
function doCoords(xyIn) {
var xyL = xyIn.split('\n');
var xyOut = []; // Array for output
var err = false;
var errM = false;

for (var i=0, len=xyL.length; i<len; i++){
t = xyL;

// test input is only digits, spaces or commas
if (t.search(/[^\d\.,]/) == -1) err = true;

// Process input
t = t.replace(/,/g, ' '); // replace comma with space
t = t.replace(/^\s*/, ''); // replace leading spaces
t = t.replace(/\s*$/, ''); // replace trailing spaces
xy = t.split(/\s+/g); // split into x & y

// regular expression test
if ( !/^\d{1,4}(\.\d\d?)?$/.test(xy[0])
|| !/^\d{1,4}(\.\d\d?)?$/.test(xy[1]) ) {
err = true;
}

// Prepare output list
if (err) {
errM = true;
err = false;
xyOut.push('------');
} else {
xyOut.push(xy[0]+' '+xy[1]);
}
}

showXYout(xyOut,errM);

return (errM)? !errM : xyOut;
}

// Write validated list to preview area
function showXYout(xyOut,errM){
var o = document.getElementById('preview');
var txt = '';

for (var i=0, len=xyOut.length; i<len; i++) {
txt += addZ(i+1) + ': ' + xyOut + '<br>'
}
o.innerHTML = txt;
}

// Add a leading zero to single digit numbers
function addZ(n) {
return (n<10)?'0'+n:n;
}
</script>
<table border="1"><tr>
<td>Input coordinates<br>
<span class="tip">Decimal values separated by a comma<br>
or space, e.g. 12.3 43.8 or 12.3,43.8.<br> Click preview
to check input before submitting.</span>
</td><td valign="top">
<span class="">Results preview</span>
</td></tr><tr>
<td valign="top">
<form action="" onsubmit="
return doCoords(this.coords.value);
">
<textarea name="coords" rows="20" cols="15"></textarea>
<br>
<input type="button" value="Check coords" onclick="
(doCoords(this.form.coords.value))?
alert('List OK'):alert('List has errors');
"><br>
<input type="submit" value="Submit coords">
</form>
</td>
<td style="border: 1px solid red; width:15em" valign="top">
<div id="preview" class="coord"><i>results
will appear here</i></div>
</td>
</tr></table>
</body>
</html>
 
M

Michael Hill

Rob, thanks for your help.

Based on your code, it seemed pretty straightforward; however, my
version does not seem to be working. I include my code at the bottom.
And, if you are curious, the page I am working on is posted here:
http://www3.telus.net/thothworks/CubicSpline.html

The test for the presence of a digit works fine.

However, after altering your code somewhat, the section that tests for
the presence of anything BUT digits, whitespace, "+", "-", and decimal
points does not seem to work. I enter a string in the text box that
includes both digits and letters, but my error condition is not
triggered. Any idea what I am overlooking?

Regards,


Michael

--------

Following is the relevant section of code:

--------
function csSolve(dataForm){

var dataFormElements = dataForm.elements; // Reference to form
elements array.

textareaIndex = 0; // The form array index for the textarea element
textareaString = "";

textareaString = textareaString +
dataFormElements[textareaIndex].value;

if (textareaString.length == 0){
alert("The length of textareaString is 0. No data has been entered.
No further action taken.");
return;
}

alert("textarea is " + textareaString + ".");

// At this point, textareaString is a big long string containing the
entire field entered in the textarea box.
// Must now clean up the data: remove leading and trailing spaces,
break up the data pairs by line, etc.

// Check to see that string contains digits; if not, no point
continuing
if (textareaString.search(/\d/) == -1){
alert("textareaString does not contain any digits. No further action
taken.");
return;
}

// Check to see that string contains only digits, decimal points, "+"
or "-" sign, or white space; if not, no point continuing
if (textareaString.search(/[^\d\.\s\+\-]/) == -1){
alert("textareaString contains a character other than digits,
decimal points, or white space. Please edit data so that it is in the
appropriate format. No further action taken.");
return;
}

alert("Leaving text input section and about to return.");

return;

} //End of csSolve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top