Link to home
Start Free TrialLog in
Avatar of melg1958
melg1958

asked on

For Maneshr: Perl script help to post and retrieve from a database.

Maneshr,

Here is the description of the Perl script needed.

I need to create a PERL script that will search (two) flat file databases (using an HTML form page to initiate the call to the Perl script).  Then, the script needs to read the appropriate flat file .. and then based on the manner in which the search is initiated from the HTML form, it needs to return that information back to the user.

There will be an HTML page (that I'll prepare) that will have 2 radio buttons which will allow for one of the TWO FLAT FILES we will be using - to be searched.  Then, after selecting which flat file will be searched, there will need to be FOUR ways in which the selected list will be searched and sorted for output.


One way - SEARCH THE ENTIRE LIST.  (The list will be sorted alphabetically - by COURSE TITLE);

Second way - BY INSTRUCTOR (The user will enter in a minimum of one letter (but with no limit) to begin their search (based on the LAST NAME of the Instructor) and the list will be sorted alphabetically - by INSTRUCTOR'S LAST NAME);

Third way - DEPARTMENT NAME (which is an abreviation) (The user will select from a list provided in a "DROP DOWN FIELD" of Department Names) and the list will be sorted alphabetically by COURSE TITLE.);

Fourth way - CATALOG COURSE NUMBER (The user will enter in a maximum of 4 digits (typically 3 or 4 numbers are used) to begin their search to find out what COURSE NAME matches up with that COURSE NUMBER. The list will sort alphabetically and display all of the COURSE NAMES the correspond with the course number that was entered.


There should be one submit button for the form (if this is possible), regardless of which FLAT FILE (FORM DETAILS) are to be searched and then displayed.  (LET ME KNOW.)

The information needs to be displayed in a table (with or without borders), but if possible, I would like each of the lines (horizontally) to alternate between a white background and a 10% gray shaded background.  Alternating back and forth to make it easier on the eyes when they are reading through the information that comes up.   (So, the lines going from left to right will either be in white or a 10% shade of gray - as they stack one on top of another. These lines are horizontal.  Ask me if you have any question.)

I would like to be able to add the HEADER (graphics, text, banner) section to the page that is returned to the browser containing the output of the searched information ... falling just below it.  Also, I would like it to provide at the bottom of the information that is returned from the search, to include  1)  The name of the flat file database that was searched.   2)  What word or letters they entered or selected to be searched.   3)  The number of results that were returned.  4) And a place for me to add some footer content, such as 'click here to go back to search again, etc.'



Also, I would like to be able to add the HEADER (graphics, text, banner) section to a page that is displayed if an error is encountered or if the user doesn't enter in the necessary information.  Then, below the header that I put in, the ERROR message (that tells them what they did wrong) would fall beneath the header.  And, give them a link to go back to the search page and 'try again.'


IMPORTANT, there is a field for PRE-REQUISITE information and COMMENTS.  The amount of information in this field may vary from Instructor to Instructor.  So, we need to allow this information to wrap and expand (if necessary) within a designated field.


NOTE:  I also need to make sure that the script is written as securely as possible.  Meaning I don't want anyone to be able to enter any type of information other than what we are expecting.  I also don't want hackers to get into our server, etc.  So, please set this up with as much security as possible.

Please .... comment the code out (in as much detail as possible) so I can follow along with what you did, how, why, etc.


Thank you!!!!
Gary
:-)


Let me know what else you need.
Avatar of maneshr
maneshr

melg1958,

"...Let me know what else you need....."

to start with i would need the HTML page that will have 2 radio buttons.

Also i would need the sample flat files with at least one line of data in it.
in addition, if you could add the name of each column in the file that would be great.

i have broken the whole stuff into 3 distinct parts.

1) getting the basic info (data, structure of the data file etc...), user interface & broad working/process flow.

2) The actual code which will be called from the user interface and which will work on the underlying data file

3) The look and feel of the output, including header, footer, error page, messages etc..

Let me know your thoughts on the same.
Avatar of ozo
<listening...but my internet connection is down>
Avatar of melg1958

ASKER

Manesh,

Sounds good.

Let me put together a sample of the HTML page with the radio buttons.  As soon as I have this, I'll email you a link to the page.

I sent you, via email, the sample flat files.  (2 of them - one for the master course list and the other for the canceled course list.)  Did you get them, or would you like me to put that info here.

Gary

Please post ur Database Structure, i.e the format of ur flat files.
Here is the FLAT FILE information.

There are 2 different lists need to be searched, depending upon what the user is searching for.  For example, there is a Master Course List (mcl.txt) ... and a Canceled Course List (canceled_courses.txt).  




1)  MASTER COURSE LIST


Flat file is provided as:   mcl.txt



SAMPLE (six samples):

D    ,ACI , 250  ,1864     ,Education Challenge            ,3.00,R   ,10:00            ,12:50            ,S225     ,Smith         ,2.75 GPA Reqd       ,
D    ,ACI , 250  ,1865     ,Education Challenge            ,3.00,F   ,13:00            ,15:50            ,P201     ,Johnson           ,                    ,
D    ,ACI , 250  ,2305     ,Education Challenge            ,3.00,R   ,14:00            ,16:50            ,R201     ,Fish         ,2.75 GPA Reqd       ,
D    ,ACI , 330  ,2306     ,Focus: Dev Behav Lrng          ,3.00,T   ,14:00            ,15:50            ,R306     ,Harris            ,See Footnote        ,
D    ,ACI , 330  ,2306     ,Focus: Dev Behav Lrng          ,3.00,R   ,14:00            ,14:50            ,R306     ,Harris            ,See Footnote        ,
D    ,ACI , 330  ,1867     ,Focus: Dev Behav Lrng          ,3.00,F   ,10:00            ,12:50            ,P201     ,Hirshberg        ,Co[req ACI 331      ,




Fields correspond and should be titled as shown below:


FIELD            REPRESENTS ... and HOW FIELDS SHOULD BE TITLED:


D            DAY/EVE/SAT   (D  - Day,  E  - Evening   and   S  - Saturday)

ACI            DEPARTMENT NAME   (The INITIALS - which would be a maximum of 4 letters, prepresent the department name.)

250            CATALOG COURSE NUMBER   (Maximum of 4 digits.)

1864            CLASS SECTION NUMBER   (Always 4 digits.)

EDUCATION CHALLENGE      COURSE TITLE   (Maximum of 35 characters - including letters, spaces forward slashes, colons, ampersand '&' signs, etc.)

3.00            SEMESTER HOURS

R            DAY(S)
(M - Monday, T - Tuesday, W - Wednesday, R - Thursday, F - Friday, S, Saturday.)   No Sunday classes, so we don't worry about Sunday.

10:00            TIME CLASS BEGINS

12:50            TIME CLASS ENDS

S225            BUILDING/ROOM LOCATION

SMITH            INSTRUCTOR'S LAST NAME

2.75 GPA Reqd      PRE-REQUISITES/DETAILS/COMMENTS


NOTE:   There is an extra field at the end (between the last two commas) that will .. at this moment ... do nothing.  We couldn't easily get rid of the commas, so, please (if it can be easily done) ignore that last field between the last two commas.





2)    CANCELED COURSE LIST

NOTE:  This list doesn't have the extra field between the extra commas.



SAMPLE:   (six samples.)

ACI, 250,Education Challenge,1864,A,Fall 2000
ACI, 250,Education Challenge,1865,A,Fall 2000
ACI, 250,Education Challenge,1874,A,Fall 2000
ACI, 250,Education Challenge,1875,A,Fall 2000
ACI, 313,Dev Educational Thought,2731,X,Fall 2000
ACI, 450,Classroom Management Wksp,1870,X,Fall 2000



Fields correspond and should be titled as shown below:


FIELD            REPRESENTS ... and HOW FIELDS SHOULD BE TITLED:

ACI            DEPARTMENT NAME   (The INITIALS - which would be a maximum of 4 letters, prepresent the department name.)

250            CATALOG COURSE NUMBER   (Maximum of 4 digits.)

EDUCATION CHALLENGE      COURSE TITLE   (Maximum of 35 characters - including letters, spaces forward slashes, colons, ampersand '&' signs, etc.)

1864            CLASS SECTION NUMBER   (Always 4 digits.)

A            STATUS            (A means   'ACITVE'.    X means   'NOT ACTIVE' .)

FALL 2000      TERM            (FALL 2000 is the term period that the class is running.)




If you have other questions, just let me know.

Thanks,
Gary

melg1958,

"..Here is the FLAT FILE information. ."

excellent! i will let you know in case i have any further questions.

i will start working on the code, as soon as i have the HTML file.
Here is some more details ... and a link to the HTML FORM page.

http://web.njcu.edu/registrar/mcl_online.html


Now, what I need is a PERL script that will search (two) flat file (.txt  file) databases (using an HTML form page to initiate the call to the Perl script).  Then, the script needs to read the appropriate flat file .. and then based on the manner in which the search is initiated from the HTML form, it needs to return that information back to the user.

There will be an HTML page (that I'll prepare) that will have 2 radio buttons which will allow for one of the TWO FLAT FILES we will be using - to be searched.  Then, after selecting which flat file will be searched, there will need to be FOUR ways (4 radio buttons) in which the selected list will be searched and sorted for output - and further searched.


(If possible, for example when someone is searching for courses offered by a particular instructor, ... I'd like to only have those courses returned in the output, as opposed to all courses in the entire list.  And, this would be the same for courses offered by a particular department and for courses that match with a particular catalog course number.)



One way - SEARCH THE ENTIRE LIST.  (The list will be sorted alphabetically - by COURSE TITLE);

Second way - BY INSTRUCTOR (The user will enter in a minimum of one letter (but with no limit) to begin their search (based on the LAST NAME of the Instructor) and the list will be sorted alphabetically - by INSTRUCTOR'S LAST NAME);

Third way - DEPARTMENT NAME (which is an abbreviation) (The user will select from a list provided in a "DROP DOWN FIELD" of Department Names) and the list will be sorted alphabetically by COURSE TITLE.);

Fourth way - CATALOG COURSE NUMBER (The user will enter in a maximum of 4 digits (typically 3 or 4 numbers are used) to begin their search to find out what COURSE NAME matches up with that COURSE NUMBER. The list will sort alphabetically and display all of the COURSE NAMES the correspond with the course number that was entered.




Then, there will be an INPUT FIELD for them to enter the text (that they want to search by), such as 'one or more letters' of an Instuctor's Last Name, or of a Department, etc.





There should be one submit button for the form (if this is possible), regardless of which FLAT FILE (FORM DETAILS) are to be searched and then displayed.  (LET ME KNOW.)

The information needs to be displayed in a table (with or without borders), but if possible, I would like each of the lines (horizontally) to alternate between a white background and a 10% gray shaded background.  Alternating back and forth to make it easier on the eyes when they are reading through the information that comes up.   (So, the lines going from left to right will either be in white or a 10% shade of gray - as they stack one on top of another. These lines are horizontal.  Ask me if you have any question.)

I would like to be able to add the HEADER (graphics, text, banner) section to the page that is returned to the browser containing the output of the searched information ... falling just below it.  Also, I would like it to provide at the bottom of the information that is returned from the search, to include  1)  The name of the flat file database that was searched.   2)  What word or letters they entered or selected to be searched.   3)  The number of results that were returned.  4) And a place for me to add some footer content, such as 'click here to go back to search again, etc.'



Also, I would like to be able to add the HEADER (graphics, text, banner) section to a page that is displayed if an error is encountered or if the user doesn't enter in the necessary information.  Then, below the header that I put in, the ERROR message (that tells them what they did wrong) would fall beneath the header.  And, give them a link to go back to the search page and 'try again.'


IMPORTANT, there is a field for PRE-REQUISITE information and COMMENTS.  The amount of information in this field may vary from Instructor to Instructor.  So, we need to allow this information to wrap and expand (if necessary) within a designated field.


NOTE:  I also need to make sure that the script is written as securely as possible.  Meaning I don't want anyone to be able to enter any type of information other than what we are expecting.  I also don't want hackers to get into our server, etc.  So, please set this up with as much security as possible.

ALSO:  The information entered by the user for their search ... SHOULD NOT BE case sensitive. Please set it up so it will search through the database regardless of how they enter the letters in (meaning uppercase or lowercase).

Please .... comment the code out (in as much detail as possible) so I can follow along with what you did, how, why, etc.



Thank you!!!!
Gary
:-)



Let me know if I made any mistakes in the HTML page or in any of the information I provided you with.

(In advance, ... I apologize for any blunders on my part.)

Gary
melg1958,

"..and a link to the HTML FORM page. .."

i checked out the page.


"....There will be an HTML page (that I'll prepare) that will have 2 radio buttons which will allow for one of the TWO FLAT FILES we will be using -..."

is this HTML page in anyway related to the "SECTION ONE:" part of the URL you posted above??

let me know.
Maneshr,

http://web.njcu.edu/registrar/mcl_online.html

This url will take you to the HTML page that I wanted to use for the search.

Is it possible to have the one form, and based upon which database they choose to search ... by making their selections using the two radio buttons ... to pick either ( 'All Currently Available Courses'   or the  'Recently Cancelled Courses' ) ???   Or, do I need to handle this another way?

This HTML page (if it is possible and based upon which choice they make in SECTION ONE  - in the HTML form) I wanted it to search the appropriate FLAT FILE.

Can we use the one HTML page ... and then in the Perl Script - have it search the appropriate database - depending upon which form field they select (in SECTION ONE - of the HTML form)???

Please let me know.

Thanks,
Gary
Hi,

I checked ur site, the form seems ok, but the only problem I can see while search is when the user selects the Cancelled courses(in Section One), by Instructors name(in Section Two). The cancelled courses does not have the Instructors name. Anyway I have ignored that at the moment, check the script below and let me know.

Here goes your mcl.pl file :


#!/usr/bin/perl

use CGI;
$cgi=new CGI;

$mcl=$cgi->param('mcl');
$category=$cgi->param('category');
$search=$cgi->param('search');
$referer=$cgi->referer;


%courselistFile=('current'=>'mcl.txt', 'cancelled'=>'ccl.txt');

## In the mcl.txt the curse title is 5th column, Instructor is in 11th column and so on...

%column_current=('entire'=>5, 'instructor'=>11, 'department'=>2, 'number'=>3);
%column_cancelled=('entire'=>3, 'department'=>1, 'number'=>2);

$sortField=$column_current{$category} if ($mcl eq "current");
$sortField=$column_cancelled{$category} if ($mcl eq "cancelled");
$database=$courselistFile{$mcl};

print $cgi->header;
print $cgi->start_html;

my @records;
my %data=();

## pushing the records in @records & copying the key field as the first field for sorting.

open(DATA,"$database");
while(<DATA>) {
      chomp;
      $sortKey=(split(/,/,$_))[$sortField-1];
      if($search) {
            push(@records,"$sortKey:$_") if ($sortKey=~/^$search/i);            
      }
      else {
            push(@records,"$sortKey:$_");
      }
}
close(DATA);

$type=($sortKey=~/[a-zA-Z]/)?"char":"num"; ## Checking the key to be Numeric or Character..

if($type eq "num") {
      @sortedRecords=sort { ($a=~/^([^:]*):/)[0]  <=>  ($b=~/^([^:]*):/)[0] } @records;
}
else {
      @sortedRecords=sort { ($a=~/^([^:]*):/)[0]  cmp  ($b=~/^([^:]*):/)[0] } @records;
}

print "<h2 align='center'>Search Result</h2>";


$ctr=1;
foreach (@sortedRecords) {
      my ($rec) = /:(.*)/ ;
      print $ctr++,' &nbsp;',$rec,'<br>';          ## Here $rec can be further splitted and formatted to display in a table
}

$ctr--;

print "<hr>";
print "Database Searched : $database <br>";
print "Category  : $category <br>";
print "Keyword : $search <br>";
print "Total Records : $ctr <br>";
print "<a href='$referer'>Click here to go back to the Search Page..</a>";
print $cgi->end_html;
melg1958,

"...This HTML page (if it is possible and based upon which choice they make in SECTION ONE  - in the HTML form) I wanted it to search the appropriate FLAT FILE.

 Can we use the one HTML page ... and then in the Perl Script - have it search the appropriate database - depending upon which form field they select (in SECTION ONE - of the HTML form)??? .."

Excellent!! that is exactly what i had in mind. So i will take the HTML form that you have given, via the URL, extract only the "SECTION ONE" part of it
& take that as the first/starting page for all the other scripts and/or HTML files.

here is the HTML file that will the base for all the subsequent scripts.

Let me know if the file is ok or you need to add/modify it.

<html>

<head>

<title>NJCU REGISTRAR DEPARTMENT</title>

<form method="post" action="/cgi-bin/mcl.pl" name="SearchForm">

<table border="0" summary="body of page" width="640" cellpadding="10">

<b>SECTION ONE:</b> &nbsp; &nbsp; (Choose one.)

<br>

<br>

<div align="center">

<table border="0" width="460" cellspacing="0" cellpadding="0">

<tr>

<td align="left">

<font color="#006633"><b>Please select the 'general type of list' you would like to search:</b></font>

<br><br>

<input type=radio name="mcl" value="current" checked>All Currently Available Courses  &nbsp;

<input type=radio name="mcl" value="cancelled">Recently Cancelled Courses

</td>

</tr>

</table>

<input type="submit" value="Click Here To Search Now">&nbsp;&nbsp;&nbsp;&nbsp;
<input type="reset" value="Reset Form">
</form>
Are we going to combine all of the 3 SECTIONS on the one HTML page??


And, would you be using the choice made by the user in SECTION ONE, to determine which Perl script (or where in the one Perl script) it would go to???



Or, will we be needing to create and break up the 3 SECTIONS into 2 or three individual HTML pages??


How will this work best?

I guess if you could explain this initial process, I might get on the same page with you.  :-)

Thanks,
Gary
And, ... with your perl script ... should I set it up and give it a shot at this point??

:-)
Gary
Well, I set it up.

I got back the following ... which is probably GOOD ... right??



Search Result

--------------------------------------------------------------------------------
Database Searched : mcl.txt
Category :
Keyword :
Total Records : 0
Click here to go back to the Search Page..


Let me know if this is what I should be getting back.

Gary

melg1958,

"..Are we going to combine all of the 3 SECTIONS on the one HTML page?? .."

a couple of questions here.

you have 2 data files with you.

will the search that is done on each of the following sections work on these 2 data files only??

SECTION ONE:

SECTION TWO:

SECTION THREE:

if so, then the answer to your above question is yes, i will update the HTML file i posted earlier to have all the three sections in it.

Also let me know what text file will be queried for each of the sections.

This is the info i have so far.

SECTION ONE:

both files will be referred to

SECTION TWO
??

SECTION THREE
??
Good question.

Let me ask you this.

All 4 of the search OPTIONS in SECTION TWO are applicable to the Master Course List.

Only 3 of the search OPTIONS in SECTION TWO are applicable to the Canceled Course List.

Now presuming that I can get the 4 field (which is the Instructor's Last Name) that is included in the Master Course List ... to also be included in the Cancelled Course List ... that should make things better ... correct??

Or, doesn't it matter.

The (3) three common search parameters in SECTION TWO that are shared by both lists are:

1)  DEPARTMENT NAME (Initials), and I think it would be good if I provided a drop down list of the initials (somehow) for the user to select from if they want to search by Department Name (initials).

2)  COURSE TITLE

3)  CATALOG COURSE NUMBER

The fourth (which is not shared) is:

the INSTRUCTOR'S LAST NAME.

Now ... also ... does it matter that the 'other fields' are not the same in both lists????  Meaning that when you search the Master Course List, you'll have information ... such as:  Semester Hours ... which you don't have in the Canceled Course List.

How will this effect the way you're writing the script??

WAIT ... I just spoke to someone that said they'll be able to add the INSTRUCTOR'S LAST NAME to the Canceled Course List ... so all 4 fields will be applicable to both lists.  I HOPE THIS HELPS.  Let me know..

Please let me know if this is important ... because if not, I'll tell them not to worry about it.

Gary
melq,

if u are not getting the result, then check the path of ur txt files. Currently the script is reading the database files from the same directory where the script resides. It works at my end.
Thank you.

I did it and ... I was able to pull up the ccl.txt file - which is only   22kb in size.  But, when I tried pulling up the  mcl.txt file - which is  243kb ... I got a message  "Out of memory!".

So, it is now finding the files ... Thanks!

But, Manesh, ... how do we handle the memory problem?

Gary

PS:  Manesh, also ... please answer my previous question as well.

Amandeep,

Again .. thank you for your input.

Gary



"...Now ... also ... does it matter that the 'other fields' are not the same in both lists???...."

no. not at this time. right now i just wanted to know if all the three sections referred to the 2 flat text files. as per your explanation they do, so i have my first step clear.

"..how do we handle the memory problem? .."

i dont know at what point you got the error, which script (if any) caused the error etc.

since i am writing the code from ground up, i dont think i should have that problem.

meanwhile, can you email me the 2 data files at maneshr@hotmail.com?

Thanks,
I got the memory error "Out of memory!" immediately after I hit the submit button on the form ... for the Master Course List.  When I tried the Canceled Course List, it was find ... and displayed the text file.

So, that's when I got the error .. and it was with the Master Course List only.  I guess it had to do with the size of the file????

I'll email you the full text flat files.

Thanks,
Gary
"..I guess it had to do with the size of the file???? .."

probably. but i am sure we can work around that.

"..I'll email you the full text flat files. .."

got the email, but the text files were merged with the actual email itself.

can you pl. re-send th same files with a different extension (like .dat) so that they are not merged with the actual email?

thanks,
I'll resend the files in the morning.

Thanks,

Gary

PS:  I'll zip up the two text files and send it to you.

melg1958,

"..PS:  I'll zip up the two text files and send it to you. ."
Excellent idea!! sounds good.

Rgds
Melq,

send the zip file to me as well, I'll test it and let u know. my email add is amandeep_sachdev@yahoo.com.

Let me know of any other errors u find.
Thanx, I got ur files.

I have tested them at my end, both the files are being read properly at my end. The only problem in the script was that it was not sorting the records properly, so I have modified the code a little. Now even the results are being displayed in a table. I dont think any memory error should come cos mcl.txt file is not so big that it cannot be handled. 243kb is not much melq. I would suggest you to check ur server in that case.

Try this again and let me know. Hope it works this time ;-)


Here goes the code :
--------------------------------------------------------

#!/usr/bin/perl

use CGI;
$cgi=new CGI;

$mcl=$cgi->param('mcl');
$category=$cgi->param('category');
$search=$cgi->param('search');
$referer=$cgi->referer;


%courselistFile=('current'=>'mcl.txt', 'cancelled'=>'ccl.txt');

## In the mcl.txt the curse title is 5th column, Instructor is in 11th column and so on...

%column_current=('entire'=>5, 'instructor'=>11, 'department'=>2, 'number'=>3);
%column_cancelled=('entire'=>3, 'department'=>1, 'number'=>2);

$sortField=$column_current{$category} if ($mcl eq "current");
$sortField=$column_cancelled{$category} if ($mcl eq "cancelled");
$database=$courselistFile{$mcl};

print $cgi->header;
print $cgi->start_html;

my @records;
my %data=();

## pushing the records in @records & copying the key field as the first field for sorting.
my $sortKey='';
my $key;

open(DATA,"$database");
while(<DATA>) {
      chomp;
      $sortKey=(split(/,/,$_))[$sortField-1];
      $sortKey=~s/^\s+//;
      if($search) {
            push(@records,"$sortKey:$_") if ($sortKey=~/^$search/i);            
      }
      else {
            push(@records,"$sortKey:$_");
      }
      $key=$sortKey if ($sortKey);
}
close(DATA);

$type=($key=~/[a-zA-Z]/)?"char":"num"; ## Checking the key to be Numeric or Character..
if($type eq "num") {
      @sortedRecords=sort { ($a=~/^([^:]*):/)[0]  <=>  ($b=~/^([^:]*):/)[0] } @records;
}
else {
      @sortedRecords=sort { ($a=~/^([^:]*):/)[0]  cmp  ($b=~/^([^:]*):/)[0] } @records;
}

print "<h2 align='center'>Search Result</h2>";


$ctr=1;
print qq{
      <table width='100%' border='1' bgcolor='#dddddd' align='center'>
};

foreach (@sortedRecords) {
      my ($rec) = /:(.*)/ ;
      my @recs=split(/,/,$rec);
      $rec=join('</td><td>',@recs);
      print "<tr><td>$ctr</td><td>$rec</td></tr>\n";
      $ctr++;
}

print "</table>\n";

$ctr--;

print "<hr>";
print "Database Searched : $database <br>";
print "Category  : $category <br>";
print "Keyword : $search <br>";
print "Total Records : $ctr <br>";
print "<a href='$referer'>Click here to go back to the Search Page..</a>";
print $cgi->end_html;


Did my solution work melq? Pl. let me know.
melg1958,

here is the HTML file and the PERL script that will work with the HTML file.

The data file is the same as you has used earlier.

NOTE: i have extensively commented the PERL code to make it easier for you to understand it. Also right now i have focused on the solution.

That done we can complete the look-and-feel part of the question.

intially try with a small search (eg instructors name with search string as man) & then go to higher searches.

let me know how it goes and if you still get the memory error.

=========mcl_online.html
<html>

<head>

        <title>NJCU REGISTRAR DEPARTMENT</title>
<table border="0" summary="body of page" width="640" cellpadding="10">

        <tr>

                <td>
<form method="post" action="/webtraining/mcl.pl" name="SearchForm">

<br>

Please complete the following <b>THREE SECTIONS</b>.<br>

<hr width="290" size="5" align="left">

<br>

<br>

<b>SECTION ONE:</b> &nbsp; &nbsp; (Choose one.)

<br>

<br>

<div align="center">

        <table border="0" width="460" cellspacing="0" cellpadding="0">

        <tr>

        <td align="left">

<font color="#006633"><b>Please select the 'general type of list' you would like to search:</b></font>

<br><br>

<input type=radio name="mcl" value="current" checked>All Currently Available Courses  &nbsp;

<input type=radio name="mcl" value="cancelled">Recently Cancelled Courses

        </td>

        </tr>

        </table>

</div>

<br>

<br>

<br>

<b>SECTION TWO:</b> &nbsp; &nbsp;(Choose one.)

<br>

<br>

<div align="center">

        <table border="0" width="460" cellspacing="0" cellpadding="0">

        <tr>

        <td align="left">

<font color="#006633"><b>Please select a category (from the choices shown below):</b></font>

<br>

<br>

<input type=radio name="category" value="entire" checked>Search the entire Master Course List &nbsp; (Sorted by:&nbsp;  Course Title)<br>

<input type=radio name="category" value="instructor">Search for courses by an Instructor's 'Last' Name<br>

<input type=radio name="category" value="department">Search for courses offered by a specific Department<br>

<input type=radio name="category" value="number">Search for course information by entering in a Catalog Course Number<br>

        </td>

        </tr>

        </table>

</div>

<br>

<br>

<b>SECTION THREE:</b>

<br>

<br>

<div align="center">

        <table border="0" width="450" cellspacing="0" cellpadding="0">

        <tr>

        <td align="left">

<font color="#006633"><b>Please enter the 'text' information you want to search for:</b></font><br>

<br>

<b><font color="#ff0000">LEAVE THE FOLLOWING FIELD 'BLANK' to retrieve the ENTIRE LIST</font></b>.<br>

<br>

<div align="justify">(Or, you can search by entering in one or more letters (and/or) numbers. For example,

if you enter the letter <b>S</b>, and select to search the 'Currently Available Courses' as well as

'Courses Offered By A Specific Department', your search will return every 'Currently Available Course'

offered by <b>every department that starts with the letter</b> - <b>S</b> &nbsp; (such as Sociology/Anthropology, Special Education, etc.).</div><br>

<br>

Enter text here: &nbsp; <input name="search" type="text" maxlength="40" size="35">

<br>

<br>

<input type="submit" value="Click Here To Search Now">&nbsp;&nbsp;&nbsp;&nbsp;

<input type="reset" value="Reset Form">

        </td>

        </tr>

        </table>

</div>



</form>

                </td>

        </tr>

</table>
</body>

</html>

==========mcl.pl
#!/usr/local/bin/perl

use CGI;
$|++;

$query=new CGI;
$DEBUG=0;      ##      Debug flag 1 = on, 0 = off.
$current="/home/manrao/mcl.txt";
$cancelled="/home/manrao/ccl.txt";
$sort_on=5;      ##      Sort will always be on Course Title.
@header=("Days","Department Name","Course Catalog number","Class section number","Course Title","Semester Hours","Day(s)","Start time","End time","Building/Room Location","Instructors Last Name","GPA Required");

##      Print the MIME header.
print "Content-type: text/html\n\n";

if (!$query->param){      ##      The script was called directly. Invalid!!
      print "<FONT COLOR=RED>Invalid access!</FONT>";
      exit;
}

##      Hash which maps the name of the HTML variables to
##      ... their corresponding value.
##      NOTE:      The names are case sensitive.
%config=("current", "/home/manrao/mcl.txt"
,"cancelled", "/home/manrao/ccl.txt"
,"entire","*"
,"instructor","10"
,"department","1"
,"number","2"
,"delimiter",","
);

$search_col="all";      ##      Default search is on all columns.

$search_string=$query->param('search');      ##      Get the search string.

foreach($query->param){
      print "<FONT COLOR=GREEN>",$_," => ",$query->param($_)," = ",$config{$query->param($_)},"</FONT><br>\n" if $DEBUG;

      ##      For the search category, decide which column needs to be searched.
      ##      NOTE: The column numbers start from 0, to accomodate PERL array
      ##      ...subscript.
      $search_col=$config{$query->param($_)} if (/^category$/ && $query->param($_) && $config{$query->param($_)}=~ /^\d+$/);
}

$search_string="" if ($search_string=~ /^\s+$/);      ##      Search text cannot have only white spaces.

##      Untaint the search string.
$search_string=~ s/[\?\[\]\;\<\>\*\|\'\&\$\!\#\(\)\{\}\:\`\"\%\\\n\r\^]//g;

##      The search string cannot be empty!!
##      NOTE: The search string can have leading and trailing spaces.
if (!$search_string){
      print qq{<FONT COLOR=RED>An empty search string is not valid.
      <P>Please enter a search string!</FONT>};
      exit;
}

print "<FONT COLOR=GREEN>","Search Column is $search_col</FONT><BR>\n" if $DEBUG;

##      Print the statistics of the search
print "<B>","Search for courses by ",$header[$search_col],"<B><BR>\n" if $search_col!~ /^all$/;
print "<B>","Search the entire Master Course List<B><BR>\n" if $search_col=~ /^all$/;
print "<B>","Search for <I>",$search_string,"</I><B><BR>\n";

print "<FONT COLOR=GREEN>","Search condition is $condition</FONT><BR>\n" if $DEBUG;

##      Open the file for reading. If open is unsuccessfull...
##      ... show the reason and exit the program
open(MYFILE,$current) || die $!;
##      "Slurp" the ENTIRE file, so that every line in the ...
##      ... file is stored as an element in the array
@lines=<MYFILE>;
close(MYFILE);      ##      Close the file

$start_col=0 if $search_col=~ /^all$/;
$end_col=12 if $search_col=~ /^all$/;

$start_col=$search_col if $search_col!~ /^all$/;
$end_col=$search_col if $search_col!~ /^all$/;

print qq{<FONT COLOR=GREEN>Start is $start_col, End is $end_col</FONT><BR>\n} if $DEBUG;

##      Apply the search condition to each line of the file
foreach(@lines){
      chomp;
      @record=split(/$config{'delimiter'}/,$_,12);
      pop(@record);      ##      Discard the last column, for now!!
      print "<FONT COLOR=GREEN>",$record[$search_col]," = ",$search_string      ,"<FONT><br>\n" if $DEBUG;

      foreach $col ($start_col .. $end_col){
            if ($record[$col]=~ /$search_string/i){
                  push(@recs,$_);
                  last;
            }
      }
}

##      If the user selected general type of list as cancelled...
##      ...then we filter the results again.
if ($query->param('mcl')=~ /^cancelled$/){
      print "<FONT COLOR=GREEN>2nd level filter for cancelled courses</FONT><BR>\n" if $DEBUG;
      ##      Open the file for reading. If open is unsuccessfull...
      ##      ... show the reason and exit the program
      open(MYFILE,$cancelled) || die $!;
      ##      "Slurp" the ENTIRE file, so that every line in the ...
      ##      ... file is stored as an element in the array
      @lines=<MYFILE>;
      shift(@lines);      ##      Remove the column header.
      close(MYFILE);      ##      Close the file
      
      foreach(@lines){
            chomp;
            @records=split(/$config{'delimiter'}/,$_);

            ##      create a hash using the 1st,2nd and 4th cols
            ##      as the keys with :: as the delimiter between each field.
            ##      A sample key, from the ccl.txt file will look like..
            ##      ACI::250::1864
            $records[1]=~ s/^\s+//;      ##      Remove leading space.
            $key=join('::',@records[0,1,3]);
            print "<FONT COLOR=GREEN>Key in Cancelled file is $key</FONT><BR>\n" if $DEBUG;
            $canc{$key}=$_;
      }

      undef @records;
      undef $key;
      foreach $line ($[ .. $#recs){
            @records=split(/$config{'delimiter'}/,$recs[$line]);
            ##      create a hash using the 1st,2nd and 3rd cols
            ##      as the keys with :: as the delimiter between each field.
            ##      A sample key, from the mcl.txt file will look like..
            ##      ACI::250::1864
            $records[1]=~ s/^\s+//;      ##      Remove leading space(s).
            $records[1]=~ s/\s+$//;      ##      Remove trailing space(s).
            $records[2]=~ s/^\s+//;      ##      Remove leading space(s).
            $records[2]=~ s/\s+$//;      ##      Remove trailing space(s).
            $records[3]=~ s/^\s+//;      ##      Remove leading space(s).
            $records[3]=~ s/\s+$//;      ##      Remove trailing space(s).
            $key=join('::',@records[1,2,3]);

            print "<FONT COLOR=GREEN>Key in Master file is $key</FONT><BR>\n" if $DEBUG;
            if ($canc{$key}){      ##      This key was found in the cancelled file. Save it!!
                  print "<FONT COLOR=GREEN>Match in Cancelled file is $canc{$key}</FONT><BR>\n" if $DEBUG;
                  push(@new,$recs[$line]);
            }
      }
      undef @recs;
      @recs=@new;
      undef @new;
}

##      Column num (starting from 1), type of sort
##      n = numeric, a = alphabetic ...
##      ... Sort order "a" = ascending, "d"= descending,
##      ... reference to the array that needs to be sorted & ...
##      ...      the delimiter between the different column.
@new=&my_sort($sort_on,"a","a",\@recs,$config{'delimiter'});

print "<B>",scalar(@new)," matches found<B><P>\n";

if (scalar (@new)){      ##      Some results were found!!
      print "<TABLE BORDER=1>\n";
      ##      Print out the array after the sorting has been done.
      foreach(@header){
            print qq{<TD ALIGN=CENTER><B>$_</B></TD>};
      }
      print "<TR>\n";

      foreach(@new){
            chomp;
            ##      We only want the first 12 columns.
            @which_cols=split(/$config{'delimiter'}/,$_,12);
            foreach($[ .. $#which_cols){
                  print "<TD>",$which_cols[$_],"&nbsp;</TD>";
            }
            print "<TR>\n";
      }
      print "</TABLE>\n";
}

##      Subroutine that does the actual sort.
##      Accepts 5 params viz..
##      1. The column number to sort. Column no. start from 1.
##      2. The type of sort numeric or alphabetic. Default is Alphabetic.
##      3. The order of sort. Default order is ascending
##      4. The referrence of the array that needs to be sorted.
##      5. The delimiter between the different column of the array.
sub my_sort{
      my ($col,$type,$sort_order,$arr,$delimiter)=@_;

      $esc_delimiter=$delimiter;

      ##      Deduct 1 from the column.
      ##      We do this because in PERL array subscript starts with 0.
      ##      So in human terms when we say column 2 it means column 1 in PERL terms!!
      $col--;

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "n" or "N". Eg. if the user has said &my_sort(3,"z",@array,"a"), we ignore the z and perform an alphabetic sort ("a").
      $type="a" if $type!~ /^n$/i;      ##      Default Alphabetic sort

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "d" or "D". Eg. if the user has said &my_sort(3,"z",@array,"q"), we ignore the q and sort in ascending order("a").
      $sort_order="a" if $sort_order!~ /^d$/i;      ##      Default Ascending Sort order

      ##      For future use. Possibly for delimiter validation and escaping.
      $esc_delimiter=~ s/(\\|\/|\||\.|\*)/\\$1/g;

      ##      Process every element of the array
      foreach(@$arr){
            ##      Split every line using the delimiter that the user has specified.
            @tmp=split(/$esc_delimiter/,$_);

            ##      After we split we know how many columns are ..
            ##      ... present in every record. Now we have to ...
            ##      ... take care of situations where the user might want ..
            ##      ... to sort on non-existant or invalid columns.
            ##      Eg. Each record has 6 columns and the user has passed 7 or 8
            ##      ... or -1 etc...

            return null if ($col<0 || $col>(scalar @tmp));      ## Invalid col no.

            ##      This is important. We take the column that the user wants ...
            ##      ... to sort on and pre-pend it to the record itself.

            ##      Let's say the record is ...
            # Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      and , is the delimiter ...
            ##      ...& the user wants to sort on the 2nd column (PERL subscript 1).
            $new_arr=join($delimiter,$tmp[$col],$_);

            ##      After the above the record will be...
            # Jeff|Toronto|Jeff|jeff@hyrum.net|98|571803

            ##      Store this new record in an array
            push(@new_arr,$new_arr);
      }

      ##      Determine the type of sort
      if ($type=~ /^n$/i){            ##      Numeric Sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by number using the bynum subroutine
                  @new_arr=reverse sort bynum @new_arr;
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort bynum @new_arr;
            }
      }else{      ##      Alphabetic sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by alphabets using the byalp subroutine
                  @new_arr=reverse sort byalp @new_arr
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort byalp @new_arr
            }
      }

      undef @arr;      ##      Re initialize the array
      ##      Remember our sort is done, but we still have that...
      ##      ...extra column at the beggining that we must remove!!
      foreach(@new_arr){
            ##      Split every line using | as the delimiter.
            @tmp=split(/$esc_delimiter/,$_);
            shift(@tmp);      ##      Remove that 1st column
            ##      So before the shift if we had....
            # Jeff,Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      After th shift we will have...
            # Toronto,Jeff,jeff@hyrum.net,98,571803

            ##      Join the array as one record...
            $new_arr=join($delimiter,@tmp);
            ##      ...& store it in another array.
            push(@arr,$new_arr);
      }

      ##      Return the final array (in sorted order)
      return @arr;
}

sub bynum{ $a <=> $b;}

sub byalp{ $a cmp $b;}



amandeep,

Excellent.  The sort worked very good - in what I would like to call - its initial phase.  :-)

I also still am getting an OUT OF MEMORY error when I try to search for the ENTIRE list, as well as if I search by Catalog Course Number ... and enter either a '1' or 'nothing in the field'.  So, I'm still having a problem with this.  Any ideas??

Thanks,

Gary

PS:  Now, I just found a problem with the .txt flat file.  In the last field for   PRE-REQUISITES/DETAILS/COMMENTS ... some times they use  a  ' , '  (comma) to separate things in there.  I spoke to the people who generate the list and they said they can replace the  ' , ' (comma) with a  ' ~ ' (tilda) ... so if  commas come up inbetween the fields, ... it won't cause a problem. So, please just make that change so it will look for a   ~  as the separator between fields.

:-)))

Gary
amandeep,

By the way, you can see the results of your current script - at:

http://web.njcu.edu/registrar/misc/mcl_online_amandeep.html

Gary
Manesh,

I emailed you a reply to your code ... and what I found after trying it.

I will post a copy of it below.

Thanks.

PS:    I just found a problem with the .txt flat file.  In the last field for   PRE-REQUISITES/DETAILS/COMMENTS ... some  times the people used  a  ' , '  (comma) to separate things within that field.  I spoke to the people who generate the list and they said they
can replace the  ' , ' (comma) with a  ' ~ ' (tilda) ... so if  commas come up inbetween the fields, ... it won't cause a problem.  So, please just make that change so it will look for a   ~  as the separator between fields.   I have already had the change made on my end with the .txt flat file.

COMMENTS I EMAILED YOU:

Here is what I found after I got it up and running.

I performed a search using only the Master Course
List, since that is the only file we are evidently
looking at right now.

I did a search for all 4 categories under Section 2.

Here was the result.

1)  When I searched the master course list, and didn't
enter any information (such as including at least one
letter or number in Section 3) - I should have gotten
the ENTIRE list - in alphabetical order by COURSE
TITLE, ... but I got nothing.  It looks as though you
set it up to require SOMETHING in that field.  I'd
like to have it where ... if they don't enter
anything, by default, they would get the entire list -
sorted by Course Title - in alphabetical order.

2)  When I searched the master course list, and 'did'
include a letter ... such as   'a', ... it looked ok.
But, when I searched for    'g' , ... it gave me a
similar list - still (for the most part sorted by  'a'
.... not 'g') yet a little different than the first
list I got when I searched for  'a'.  So, I don't know
what happened??

PLUS ... when I searched in Internet Explorer 5.5, I
got a lot of garbaley-goop at the top of the page
before the table showed up.

You can see it at:

http://web.njcu.edu/registrar/misc/mcl_online.html

Look at it for yourself.

(Note:  Netscape gives me a third line from the top
that says ...   xxx matches found.   IE gives me the
garbage instead of that line.)


The goal, when someone searches for:



Search the entire Master Course List   (Sorted by:
Course Title)

GOAL:  Entire list comes sorted out in alphabetical
order by COURSE TITLE ... 1) either the entire list
(in alphabetical order by COURSE TITLE) if nothing is
included in Section 3, or   2)  starting with COURSE
TITLES that begin with the letter or letters that were
entered in Section 3 ... and ending with COURSE TITLES
that begin with the letter or letters that were
entered in Section 3.  I want to limit the list that
comes up to only the COURSE TITLES that match what
they were looking for.  For example, if they enter in
the letter 'a'  (upper or lower case - shouldn't
matter) ... then all of the list will be displayed in
alphabetical order  .... and limited to course titles
that start with the letter 'a'.  If they included 'ab'
in  Section 3, then the list would only display an
alphabetical listing by COURSE TITLES that begin with
the letters 'ab' and also limited to those course
titles.



Search for courses by an Instructor's 'Last' Name

Entire list comes sorted out in alphabetical order by
INSTRUCTOR'S LAST NAME ... 1) either the entire list
(in alphabetical order by INSTRUCTOR'S LAST NAME) if
nothing is included in Section 3, or   2)  starting
with the INSTRUCTOR'S LAST NAME that begin with the
letter or letters that were entered in Section 3 ...
and ending with INSTRUCTOR'S LAST NAME that begin with
the letter or letters that were entered in Section 3.
I want to limit the list that comes up to only the
INSTRUCTORS that match what they were looking for.
For example, if they enter in the letter 'a'  (upper
or lower case - shouldn't matter) ... then all of the
list will be displayed in alphabetical order  .... and
limited to INSTRUCTOR'S LAST NAMES that start with the
letter 'a'.  If they included 'ab' in  Section 3, then
the list would only display an alphabetical listing by
INSTRUCTOR'S LAST NAMES that begin with the letters
'ab' and also limited to those instructors.




Search for courses offered by a specific Department

Entire list comes sorted out in alphabetical order by
DEPARTMENT ... 1) either the entire list (in
alphabetical order by DEPARTMENT INITIALS) if nothing
is included in Section 3, or   2)  starting with the
DEPARMENT INITIALS that begin with the letter or
letters that were entered in Section 3 ... and ending
with DEPARTMENT that begin with the letter or letters
that were entered in Section 3.  I want to limit the
list that comes up to only the DEPARTMENTS that match
what they were looking for.  For example, if they
enter in the letter 'a'  (upper or lower case -
shouldn't matter) ... then all of the list will be
displayed in alphabetical order  .... and limited to
DEPARTMENTS that start with the letter 'a'.  If they
included 'ab' in  Section 3, then the list would only
display an alphabetical listing by DEPARTMENT that
begin with the letters 'ab' and also limited to those
instructors.




Search for course information by entering in a Catalog
Course Number

Entire list comes sorted out in numerical order by
CATALOG COURSE NUMBER ... 1) either the entire list
(in alphabetical order by Catalog Course Number) if
nothing is included in Section 3, or   2)  starting
with the Catalog Course Number that begin with the
NUMBER(s) that were entered in Section 3 ... and
ending with Catalog Course Number that begin with the
number(s) that were entered in Section 3.  I want to
limit the list that comes up to only the Catalog
Course Number that matches with what they were looking
for.  For example, if they enter in the number '1'
.... then all of the list will be displayed in
numerical order  .... and limited to Catalog Course
Number that start with the number '1'.  If they
included '12' in  Section 3, then the list would only
display a numerical listing by Catalog Course Number
that begin with the numbers '12' and also limited to
those course numbers.


I hope this is also what you had understood from my
previous instructions.

Please let me know.

If not, I hope I have clarified it.

Everything is looking great.

Just get back to me and let me know if we're on the
same page.  :-)

Thanks again,
Gary
melg1958,

i have replied to your email.

two new things that have come out of the above comments are

1) the search string that the user enters should occur in the beginning of the field being searched, and not anywhere (like i am  searching right now)

2) the results should be sorted on the columns being searched for, not on the course title as i am doing now.

melg1958,

here is the updated script with the changes made.

The changes are:

* Accept empty strings for searching. Display all the results when no search string is entered. the results will then be sorted on the column/category on which you are searching.
* the search string will be searched for only from the beginning of each column
* search performed using the 1st radio button of "SECTION TWO" will now be only on the course title and not on all the columns of the data file.

let me know how it goes.

#!/usr/local/bin/perl

use CGI;
$|++;

$query=new CGI;
$DEBUG=0;      ##      Debug flag 1 = on, 0 = off.
$current="/home/manrao/mcl.txt";
$cancelled="/home/manrao/ccl.txt";

@header=("Days","Department Name","Course Catalog number","Class section number","Course Title","Semester Hours","Day(s)","Start time","End time","Building/Room Location","Instructors Last Name","GPA Required");

##      Print the MIME header.
print "Content-type: text/html\n\n";

if (!$query->param){      ##      The script was called directly. Invalid!!
      print "<FONT COLOR=RED>Invalid access!</FONT>";
      exit;
}

##      Hash which maps the name of the HTML variables to
##      ... their corresponding value.
##      NOTE:      The names are case sensitive.
%config=("current", "/home/manrao/mcl.txt"
,"cancelled", "/home/manrao/ccl.txt"
,"entire","4"
,"instructor","10"
,"department","1"
,"number","2"
,"delimiter",","
);

$search_col="5";      ##      Default search is on Course Title column.

$search_string=$query->param('search');      ##      Get the search string.

foreach($query->param){
      print "<FONT COLOR=GREEN>",$_," => ",$query->param($_)," = ",$config{$query->param($_)},"</FONT><br>\n" if $DEBUG;

      ##      For the search category, decide which column needs to be searched.
      ##      NOTE: The column numbers start from 0, to accomodate PERL array
      ##      ...subscript.
      if (/^category$/ && $query->param($_) && $config{$query->param($_)}=~ /^\d+$/){
            $search_col=$config{$query->param($_)};
            $sort_on=$config{$query->param($_)};
            ++$sort_on;
      }
}

$search_string="" if ($search_string=~ /^\s+$/);      ##      Search text cannot have only white spaces.

##      Untaint the search string.
$search_string=~ s/[\?\[\]\;\<\>\*\|\'\&\$\!\#\(\)\{\}\:\`\"\%\\\n\r\^]//g;

##      The search string cannot be empty!!
##      NOTE: The search string can have leading and trailing spaces.
#if (!$search_string){
#      print qq{<FONT COLOR=RED>An empty search string is not valid.
#      <P>Please enter a search string!</FONT>};
#      exit;
#}

print "<FONT COLOR=GREEN>","Search Column is $search_col</FONT><BR>\n" if $DEBUG;

##      Print the statistics of the search
print "<B>","Search for courses by ",$header[$search_col],"<B><BR>\n";
print "<B>","Search results sorted by ",$header[$search_col],"<B><BR>\n";
print "<B>","Search for <I>",$search_string,"</I><B><BR>\n";

print "<FONT COLOR=GREEN>","Search condition is $condition</FONT><BR>\n" if $DEBUG;

##      Open the file for reading. If open is unsuccessfull...
##      ... show the reason and exit the program
open(MYFILE,$current) || die $!;
##      "Slurp" the ENTIRE file, so that every line in the ...
##      ... file is stored as an element in the array
@lines=<MYFILE>;
close(MYFILE);      ##      Close the file

$start_col=$search_col;
$end_col=$search_col;

print qq{<FONT COLOR=GREEN>Start is $start_col, End is $end_col</FONT><BR>\n} if $DEBUG;

##      Apply the search condition to each line of the file
foreach(@lines){
      chomp;
      @record=split(/$config{'delimiter'}/,$_,12);
      pop(@record);      ##      Discard the last column, for now!!
      print "<FONT COLOR=GREEN>",$record[$search_col]," = ",$search_string      ,"<FONT><br>\n" if $DEBUG;

      foreach $col ($start_col .. $end_col){
            $record[$col]=~ s/^\s+//;
            if ($record[$col]=~ /^$search_string/i){
                  push(@recs,$_);
                  last;
            }
      }
}

##      If the user selected general type of list as cancelled...
##      ...then we filter the results again.
if ($query->param('mcl')=~ /^cancelled$/){
      print "<FONT COLOR=GREEN>2nd level filter for cancelled courses</FONT><BR>\n" if $DEBUG;
      ##      Open the file for reading. If open is unsuccessfull...
      ##      ... show the reason and exit the program
      open(MYFILE,$cancelled) || die $!;
      ##      "Slurp" the ENTIRE file, so that every line in the ...
      ##      ... file is stored as an element in the array
      @lines=<MYFILE>;
      shift(@lines);      ##      Remove the column header.
      close(MYFILE);      ##      Close the file
      
      foreach(@lines){
            chomp;
            @records=split(/$config{'delimiter'}/,$_);

            ##      create a hash using the 1st,2nd and 4th cols
            ##      as the keys with :: as the delimiter between each field.
            ##      A sample key, from the ccl.txt file will look like..
            ##      ACI::250::1864
            $records[1]=~ s/^\s+//;      ##      Remove leading space.
            $key=join('::',@records[0,1,3]);
            print "<FONT COLOR=GREEN>Key in Cancelled file is $key</FONT><BR>\n" if $DEBUG;
            $canc{$key}=$_;
      }

      undef @records;
      undef $key;
      foreach $line ($[ .. $#recs){
            @records=split(/$config{'delimiter'}/,$recs[$line]);
            ##      create a hash using the 1st,2nd and 3rd cols
            ##      as the keys with :: as the delimiter between each field.
            ##      A sample key, from the mcl.txt file will look like..
            ##      ACI::250::1864
            $records[1]=~ s/^\s+//;      ##      Remove leading space(s).
            $records[1]=~ s/\s+$//;      ##      Remove trailing space(s).
            $records[2]=~ s/^\s+//;      ##      Remove leading space(s).
            $records[2]=~ s/\s+$//;      ##      Remove trailing space(s).
            $records[3]=~ s/^\s+//;      ##      Remove leading space(s).
            $records[3]=~ s/\s+$//;      ##      Remove trailing space(s).
            $key=join('::',@records[1,2,3]);

            print "<FONT COLOR=GREEN>Key in Master file is $key</FONT><BR>\n" if $DEBUG;
            if ($canc{$key}){      ##      This key was found in the cancelled file. Save it!!
                  print "<FONT COLOR=GREEN>Match in Cancelled file is $canc{$key}</FONT><BR>\n" if $DEBUG;
                  push(@new,$recs[$line]);
            }
      }
      undef @recs;
      @recs=@new;
      undef @new;
}

##      Column num (starting from 1), type of sort
##      n = numeric, a = alphabetic ...
##      ... Sort order "a" = ascending, "d"= descending,
##      ... reference to the array that needs to be sorted & ...
##      ...      the delimiter between the different column.
@new=&my_sort($sort_on,"a","a",\@recs,$config{'delimiter'});

print "<B>",scalar(@new)," matches found<B><P>\n";

if (scalar (@new)){      ##      Some results were found!!
      print "<TABLE BORDER=1>\n";
      ##      Print out the array after the sorting has been done.
      foreach(@header){
            print qq{<TD ALIGN=CENTER><B>$_</B></TD>};
      }
      print "<TR>\n";

      foreach(@new){
            chomp;
            ##      We only want the first 12 columns.
            @which_cols=split(/$config{'delimiter'}/,$_,12);
            foreach($[ .. $#which_cols){
                  print "<TD>",$which_cols[$_],"&nbsp;</TD>";
            }
            print "<TR>\n";
      }
      print "</TABLE>\n";
}

##      Subroutine that does the actual sort.
##      Accepts 5 params viz..
##      1. The column number to sort. Column no. start from 1.
##      2. The type of sort numeric or alphabetic. Default is Alphabetic.
##      3. The order of sort. Default order is ascending
##      4. The referrence of the array that needs to be sorted.
##      5. The delimiter between the different column of the array.
sub my_sort{
      my ($col,$type,$sort_order,$arr,$delimiter)=@_;

      $esc_delimiter=$delimiter;

      ##      Deduct 1 from the column.
      ##      We do this because in PERL array subscript starts with 0.
      ##      So in human terms when we say column 2 it means column 1 in PERL terms!!
      $col--;

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "n" or "N". Eg. if the user has said &my_sort(3,"z",@array,"a"), we ignore the z and perform an alphabetic sort ("a").
      $type="a" if $type!~ /^n$/i;      ##      Default Alphabetic sort

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "d" or "D". Eg. if the user has said &my_sort(3,"z",@array,"q"), we ignore the q and sort in ascending order("a").
      $sort_order="a" if $sort_order!~ /^d$/i;      ##      Default Ascending Sort order

      ##      For future use. Possibly for delimiter validation and escaping.
      $esc_delimiter=~ s/(\\|\/|\||\.|\*)/\\$1/g;

      ##      Process every element of the array
      foreach(@$arr){
            ##      Split every line using the delimiter that the user has specified.
            @tmp=split(/$esc_delimiter/,$_);

            ##      After we split we know how many columns are ..
            ##      ... present in every record. Now we have to ...
            ##      ... take care of situations where the user might want ..
            ##      ... to sort on non-existant or invalid columns.
            ##      Eg. Each record has 6 columns and the user has passed 7 or 8
            ##      ... or -1 etc...

            return null if ($col<0 || $col>(scalar @tmp));      ## Invalid col no.

            ##      This is important. We take the column that the user wants ...
            ##      ... to sort on and pre-pend it to the record itself.

            ##      Let's say the record is ...
            # Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      and , is the delimiter ...
            ##      ...& the user wants to sort on the 2nd column (PERL subscript 1).
            $new_arr=join($delimiter,$tmp[$col],$_);

            ##      After the above the record will be...
            # Jeff|Toronto|Jeff|jeff@hyrum.net|98|571803

            ##      Store this new record in an array
            push(@new_arr,$new_arr);
      }

      ##      Determine the type of sort
      if ($type=~ /^n$/i){            ##      Numeric Sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by number using the bynum subroutine
                  @new_arr=reverse sort bynum @new_arr;
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort bynum @new_arr;
            }
      }else{      ##      Alphabetic sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by alphabets using the byalp subroutine
                  @new_arr=reverse sort byalp @new_arr
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort byalp @new_arr
            }
      }

      undef @arr;      ##      Re initialize the array
      ##      Remember our sort is done, but we still have that...
      ##      ...extra column at the beggining that we must remove!!
      foreach(@new_arr){
            ##      Split every line using | as the delimiter.
            @tmp=split(/$esc_delimiter/,$_);
            shift(@tmp);      ##      Remove that 1st column
            ##      So before the shift if we had....
            # Jeff,Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      After th shift we will have...
            # Toronto,Jeff,jeff@hyrum.net,98,571803

            ##      Join the array as one record...
            $new_arr=join($delimiter,@tmp);
            ##      ...& store it in another array.
            push(@arr,$new_arr);
      }

      ##      Return the final array (in sorted order)
      return @arr;
}

sub bynum{ $a <=> $b;}

sub byalp{ $a cmp $b;}
Hi melq,

I have made the necessary changes in the code. This will handle the files with '~' as the field seperator, so test it with those files only. In the code u can change the $delimiter variable to whatever field-seperator u have. I have also modified the code considering ur memory problem, but let me tell u again it is running fine at my end. So kindly check ur server configuration also.

pl. try this code and let me know..

--------------------------------

#!/usr/bin/perl

use CGI;
$cgi=new CGI;

$|++;

$mcl=$cgi->param('mcl');
$category=$cgi->param('category');
$search=$cgi->param('search');
$referer=$cgi->referer;

$delimiter='~';

%courselistFile=('current'=>'mcl.txt', 'cancelled'=>'ccl.txt');

## In the mcl.txt the curse title is 5th column, Instructor is in 11th column and so on...

%column_current=('entire'=>5, 'instructor'=>11, 'department'=>2, 'number'=>3);
%column_cancelled=('entire'=>3, 'department'=>1, 'number'=>2);

$sortField=$column_current{$category} if ($mcl eq "current");
$sortField=$column_cancelled{$category} if ($mcl eq "cancelled");
$database=$courselistFile{$mcl};

print $cgi->header;
print $cgi->start_html(-title=>"Search Result");

my @records;
my %data=();

## pushing the records in @records & copying the key field as the first field for sorting.
my $sortKey='';
my $key;

open(DATA,"$database");
while(<DATA>) {
      chomp;
      $sortKey=(split(/$delimiter/,$_))[$sortField-1];
      $sortKey=~s/^\s+//;
      if($search) {
            push(@records,"$sortKey:$_") if ($sortKey=~/^$search/i);            
      }
      else {
            push(@records,"$sortKey:$_");
      }
      $key=$sortKey if ($sortKey);
}
close(DATA);

$type=($key=~/[a-zA-Z]/)?"char":"num"; ## Checking the key to be Numeric or Character..
if($type eq "num") {
      @records=sort { ($a=~/^([^:]*):/)[0]  <=>  ($b=~/^([^:]*):/)[0] } @records;
}
else {
      @records=sort { ($a=~/^([^:]*):/)[0]  cmp  ($b=~/^([^:]*):/)[0] } @records;
}

print "<h2 align='center'>Search Result</h2>";


$ctr=1;
print qq{
      <table width='100%' border='1' bgcolor='#dddddd' align='center'>
};

foreach (@records) {
      my ($rec) = /:(.*)/ ;
      my @recs=split(/$delimiter/,$rec);
      $rec=join('</td><td>',@recs);
      print "<tr><td>$ctr</td><td>$rec</td></tr>\n";
      $ctr++;
}

print "</table>\n";

$ctr--;

print "<hr>";
print "Database Searched : $database <br>";
print "Category  : $category <br>";
print "Keyword : $search <br>";
print "Total Records : $ctr <br>";
print "<a href='$referer'>Click here to go back to the Search Page..</a>";
print $cgi->end_html;
Amandeep,

I tried your script.

I got results (and did not get the Memory Overflow Error) when I searched    mcl.txt   using a flat file that still had a comma as the delimiter.

But, when I searched the file (which I changed) to   mclamandeep.txt   - that has a  ~  (tilda) as the delimiter, I did not get any results.  I got your return page ... but nothing came up in the list.

Any ideas what is happening??

Thanks,
Gary
melg1958,

here is the final script that does the search as per your latest requirements.

the search is done for each individual file seperately.

as a result the code size has been reduced by a lot.

let me know how it goes.
=====mcl.pl
#!/usr/local/bin/perl

use CGI;
$|++;

$query=new CGI;
$DEBUG=0;      ##      Debug flag 1 = on, 0 = off.

##      Print the MIME header.
print "Content-type: text/html\n\n";

if (!$query->param){      ##      The script was called directly. Invalid!!
      print "<FONT COLOR=RED>Invalid access!</FONT>";
      exit;
}

##      Hash which maps the name of the HTML variables to
##      ... their corresponding value.
##      NOTE:      The names are case sensitive.
%current=(
"data_file","/home/manrao/mcl.txt"
,"entire","4"
,"instructor","10"
,"department","1"
,"number","2"
,"delimiter",","
,"default","5"
);

@current=("Days","Department Name","Course Catalog number","Class section number","Course Title","Semester Hours","Day(s)","Start time","End time","Building/Room Location","Instructors Last Name","GPA Required");

%cancelled=(
"data_file","/home/manrao/ccl.txt"
,"entire","2"
,"department","0"
,"number","1"
,"delimiter",","
,"default","2"
);

@cancelled=("Department Name","Course Catalog number","Course Title","Class section number","Status","Terms");

$mcl=$query->param('mcl');
$search_string=$query->param('search');
$category=$query->param('category');

$search_col= $$mcl{'default'};      ##      Get the column for Default search.
@header=@$mcl;

foreach($query->param){
      print "<FONT COLOR=GREEN>",$_," => ",$query->param($_)," = ",$$mcl{$query->param($_)},"</FONT><br>\n" if $DEBUG;

      ##      For the search category, decide which column needs to be searched.
      ##      NOTE: The column numbers start from 0, to accomodate PERL array
      ##      ...subscript.
      if ($category && $$mcl{$query->param($_)}=~ /^\d+$/){
            $search_col=$$mcl{$query->param($_)};
            $start_col=$search_col;
            $end_col=$search_col;
            $sort_on=$$mcl{$query->param($_)};
            ++$sort_on;
      }
}

if (!$sort_on){      ##      Invalid column selected for search
      print "<FONT COLOR=RED>This category cannot be searched for this list!!</FONT>";
      exit;
}

if ($DEBUG){
      print "<B>Search Column = >$search_col<</B>\n";
      print "<B>Sort on = >$sort_on<</B>\n";
      print "<BR>Headers are @header<BR>\n";
}

$search_string="" if ($search_string=~ /^\s+$/);      ##      Search text cannot have only white spaces.

##      Untaint the search string.
$search_string=~ s/[\?\[\]\;\<\>\*\|\'\&\$\!\#\(\)\{\}\:\`\"\%\\\n\r\^]//g;

print "<FONT COLOR=GREEN>","Search Column is $search_col</FONT><BR>\n" if $DEBUG;

##      Print the statistics of the search
print "<B>","Search for courses by ",$header[$search_col],"<B><BR>\n";
print "<B>","Search results sorted by ",$header[$search_col],"<B><BR>\n";
print "<B>","Search for <I>",$search_string,"</I><B><BR>\n";

$data_file=$$mcl{'data_file'};

if ($DEBUG){
      print "<FONT COLOR=GREEN><B>Opening Data file $data_file</B></FONT><BR>\n";
}

##      Open the file for reading. If open is unsuccessfull...
##      ... show the reason and exit the program
open(MYFILE,$data_file) || die $!;
##      "Slurp" the ENTIRE file, so that every line in the ...
##      ... file is stored as an element in the array
@lines=<MYFILE>;
close(MYFILE);      ##      Close the file

print qq{<FONT COLOR=GREEN>Start is $start_col, End is $end_col</FONT><BR>\n} if $DEBUG;

foreach(@lines){
      chomp;
      @record=split(/$$mcl{'delimiter'}/,$_,12);
      pop(@record);      ##      Discard the last column, for now!!
      print "<FONT COLOR=GREEN>",$record[$search_col]," = ",$search_string      ,"<FONT><br>\n" if $DEBUG;

      foreach $col ($start_col .. $end_col){
            $record[$col]=~ s/^\s+//;      ##      Remove leading &...
            $record[$col]=~ s/\s+$//;      ##      ... trailing spaces.
            if ($record[$col]=~ /^$search_string/i){
                  push(@recs,$_);
                  last;
            }
      }
}

##      Column num (starting from 1), type of sort
##      n = numeric, a = alphabetic ...
##      ... Sort order "a" = ascending, "d"= descending,
##      ... reference to the array that needs to be sorted & ...
##      ...      the delimiter between the different column.
@new=&my_sort($sort_on,"a","a",\@recs,$$mcl{'delimiter'});

print "<B>",scalar(@new)," matches found<B><P>\n";

if (scalar (@new)){      ##      Some results were found!!
      print "<TABLE BORDER=1>\n";
      ##      Print out the array after the sorting has been done.
      foreach(@header){
            print qq{<TD ALIGN=CENTER><B>$_</B></TD>};
      }
      print "<TR>\n";

      foreach(@new){
            chomp;
            ##      We only want the first 12 columns.
            @which_cols=split(/$$mcl{'delimiter'}/,$_,12);
            foreach($[ .. $#which_cols){
                  print "<TD>",$which_cols[$_],"&nbsp;</TD>";
            }
            print "<TR>\n";
      }
      print "</TABLE>\n";
}

##      Subroutine that does the actual sort.
##      Accepts 5 params viz..
##      1. The column number to sort. Column no. start from 1.
##      2. The type of sort numeric or alphabetic. Default is Alphabetic.
##      3. The order of sort. Default order is ascending
##      4. The referrence of the array that needs to be sorted.
##      5. The delimiter between the different column of the array.
sub my_sort{
      my ($col,$type,$sort_order,$arr,$delimiter)=@_;

      $esc_delimiter=$delimiter;

      ##      Deduct 1 from the column.
      ##      We do this because in PERL array subscript starts with 0.
      ##      So in human terms when we say column 2 it means column 1 in PERL terms!!
      $col--;

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "n" or "N". Eg. if the user has said &my_sort(3,"z",@array,"a"), we ignore the z and perform an alphabetic sort ("a").
      $type="a" if $type!~ /^n$/i;      ##      Default Alphabetic sort

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "d" or "D". Eg. if the user has said &my_sort(3,"z",@array,"q"), we ignore the q and sort in ascending order("a").
      $sort_order="a" if $sort_order!~ /^d$/i;      ##      Default Ascending Sort order

      ##      For future use. Possibly for delimiter validation and escaping.
      $esc_delimiter=~ s/(\\|\/|\||\.|\*)/\\$1/g;

      ##      Process every element of the array
      foreach(@$arr){
            ##      Split every line using the delimiter that the user has specified.
            @tmp=split(/$esc_delimiter/,$_);

            ##      After we split we know how many columns are ..
            ##      ... present in every record. Now we have to ...
            ##      ... take care of situations where the user might want ..
            ##      ... to sort on non-existant or invalid columns.
            ##      Eg. Each record has 6 columns and the user has passed 7 or 8
            ##      ... or -1 etc...

            return null if ($col<0 || $col>(scalar @tmp));      ## Invalid col no.

            ##      This is important. We take the column that the user wants ...
            ##      ... to sort on and pre-pend it to the record itself.

            ##      Let's say the record is ...
            # Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      and , is the delimiter ...
            ##      ...& the user wants to sort on the 2nd column (PERL subscript 1).
            $new_arr=join($delimiter,$tmp[$col],$_);

            ##      After the above the record will be...
            # Jeff|Toronto|Jeff|jeff@hyrum.net|98|571803

            ##      Store this new record in an array
            push(@new_arr,$new_arr);
      }

      ##      Determine the type of sort
      if ($type=~ /^n$/i){            ##      Numeric Sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by number using the bynum subroutine
                  @new_arr=reverse sort bynum @new_arr;
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort bynum @new_arr;
            }
      }else{      ##      Alphabetic sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by alphabets using the byalp subroutine
                  @new_arr=reverse sort byalp @new_arr
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort byalp @new_arr
            }
      }

      undef @arr;      ##      Re initialize the array
      ##      Remember our sort is done, but we still have that...
      ##      ...extra column at the beggining that we must remove!!
      foreach(@new_arr){
            ##      Split every line using | as the delimiter.
            @tmp=split(/$esc_delimiter/,$_);
            shift(@tmp);      ##      Remove that 1st column
            ##      So before the shift if we had....
            # Jeff,Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      After th shift we will have...
            # Toronto,Jeff,jeff@hyrum.net,98,571803

            ##      Join the array as one record...
            $new_arr=join($delimiter,@tmp);
            ##      ...& store it in another array.
            push(@arr,$new_arr);
      }

      ##      Return the final array (in sorted order)
      return @arr;
}

sub bynum{ $a <=> $b;}

sub byalp{ $a cmp $b;}
Manesh,

Ok.  Well, here is what I have happening.

1)  Good fix regarding the problem we were having if someone tried to search the ccl.txt file, and by accident checked off Instructor's Last Name.  Thanks.

2)  When I search the ccl.txt file, I am getting a weird result like the following. (In Netscape.  It might be happening in IE, but I can't tell due to the other garbage I am seeing.)

Here's the link if you want to try it.
http://web.njcu.edu/registrar/misc/mcl_online_final.html

OUTPUT LOOKS LIKE THIS:

Search for courses by Course Title
Search results sorted by Course Title
Search for a
40

(Then the list of info.)


Search for courses by Course Catalog number
Search results sorted by Course Catalog number
Search for a
0Qé­î­Ç‚

(Then the list of info.)


Search for courses by Department Name
Search results sorted by Department Name
Search for a
44‰JöwH

(Then the list of info.)


3)  I guess I am not sure as to what I need to do or check regarding the garbage problem with IE.  I am using another script (that you helped me with) that isn't giving me this error.

You can see the use of the other script at:
http://web.njcu.edu/mis/directory.html

Look at Faculty and Staff Database.  It comes out fine. So, why would this be ok, ... and the one we are working on now ... having trouble.  It is on the exact same server.

Do you want a copy of the prior script you did for this project??



Now ... aside from the above (IE Garbage and the new 'little' garbage in Netscape) ... the script appears to be working fine.

Let me know what we need to do.

Thanks,
Gary


melq,

Pl make sure u were testing with these values in the code if mclamandeep.txt is '~' seperated :

$delimiter='~';

%courselistFile=('current'=>'mclamandeep.txt', 'cancelled'=>'ccl.txt');




If mcl.txt is comma seperated it should be :

$delimiter=',';

%courselistFile=('current'=>'mcl.txt', 'cancelled'=>'ccl.txt');





If it still doesnt work kindly send the file ( '~' seperated )  to my email add amandeep_sachdev@yahoo.com. Pl. zip it and send. I'll check it and let u know.
:-)

>Manesh,
>
>Ok.  Well, here is what I have happening.
>
>1)  Good fix regarding the problem we were having if
>someone tried to search the ccl.txt file, and by
>accident checked off Instructor's Last Name.  Thanks.

Glad to know you like it.

>2)  When I search the ccl.txt file, I am getting a
>weird result like the following. (In Netscape.  It
>might be happening in IE, but I can't tell due to the
>other garbage I am seeing.)
>
>Here's the link if you want to try it.
>http://web.njcu.edu/registrar/misc/mcl_online_final.html
>
>OUTPUT LOOKS LIKE THIS:
>
>Search for courses by Course Title
>Search results sorted by Course Title
>Search for a
>40
>
>(Then the list of info.)
>
>
>Search for courses by Course Catalog number
>Search results sorted by Course Catalog number
>Search for a
>0Qé­î­Ç‚
>
>(Then the list of info.)
>
>
>Search for courses by Department Name
>Search results sorted by Department Name
>Search for a
>44‰JöwH
>
>(Then the list of info.)

the more i think of it the more i am convinced that the problem is with the web server. the only factor common in the entire search process, if i use IE or Netscape, is the web server because it is the same webserver that serves my request each time.

Also each time this garbled text appears, regardless of the browser.

>
>3)  I guess I am not sure as to what I need to do or
>check regarding the garbage problem with IE.  I am
>using another script (that you helped me with) that
>isn't giving me this error.

i dont know how your system is configured, therefore i cant be of much help, other than in coming up with hints and suggestions.

>You can see the use of the other script at:
>http://web.njcu.edu/mis/directory.html
>
>Look at Faculty and Staff Database.  It comes out
>fine. So, why would this be ok, ... and the one we are
>working on now ... having trouble.  It is on the exact
>same server.
>
>Do you want a copy of the prior script you did for
>this project??

i dont think the problem is with the script itself and even if i had the script, i would run it in a different environment.

from the entire discussion i think you are working on a Windows NT server, whereas i am on a Unix box.

>
>

Melq1958, did u get the solution?

Pl. let me know?

Thanx
Amandeep,

I didn't get the solution yet.  I am having a problem on our server to get Perl working correctly.  Hopefully this will be fixed soon.  The network administrator needs to correct the problem and re-install Perl.  So, I am his beck and call at the moment.

I can't test it out until he fixes it.

Thanks for asking, but I'll let you know when he fixes me up.

:-)
Gary


Well, I now have Perl reinstalled and working.

Here is the current script.  ONLY ONE PROBLEM ... in IE (version 5.5 ... and I am not sure about other versions of IE) ... I am getting a lot of garbage on the output.  You can see it by running it at:  

http://web.njcu.edu/registrar/misc/mcl_online_final.html

The script is working fine in Netscape.  The output results are fine in both Netscape and IE, ... except for the extra garbage that we're getting near the top of the output.  (You'll see it when you run it.)

I am running the script on an NT server.  (This is giving us the trouble at the moment.)  When I take the identical script  (that is shown below) and put it on a Unix server ... it runs fine on both Netscape and IE.

So, the current question is ... what needs to be changed in the code so it will work on NT (and not give me the garbage in the output when using IE)???



#!/usr/local/bin/perl -T

use CGI;
$|++;

$query=new CGI;
$DEBUG=0;      ##      Debug flag 1 = on, 0 = off.

##      Print the MIME header.
print "Content-type: text/html\n\n";

if (!$query->param){      ##      The script was called directly. Invalid!!
      print "<FONT COLOR=RED>Invalid access!</FONT>";
      exit;
}

##      Hash which maps the name of the HTML variables to
##      ... their corresponding value.
##      NOTE:      The names are case sensitive.
%current=(
#"data_file","/home/manrao/mcl.txt"
"data_file","/InetPub/database/registrar/mcl.txt"
,"entire","4"
,"instructor","10"
,"department","1"
,"number","2"
,"delimiter",","
,"default","5"
);

@current=("Days","Department Name","Course Catalog number","Class section number","Course Title","Semester Hours","Day(s)","Start time","End time","Building/Room Location","Instructors Last Name","GPA Required");

%cancelled=(
#"data_file","/home/manrao/ccl.txt"
"data_file","/InetPub/database/registrar/ccl.txt"
,"entire","2"
,"department","0"
,"number","1"
,"delimiter",","
,"default","2"
);

@cancelled=("Department Name","Course Catalog number","Course Title","Class section number","Status","Terms");

$mcl=$query->param('mcl');
$search_string=$query->param('search');
$category=$query->param('category');

$search_col= $$mcl{'default'};      ##      Get the column for Default search.
@header=@$mcl;

foreach($query->param){
      print "<FONT COLOR=GREEN>",$_," => ",$query->param($_)," = ",$$mcl{$query->param($_)},"</FONT><br>\n" if $DEBUG;

      ##      For the search category, decide which column needs to be searched.
      ##      NOTE: The column numbers start from 0, to accomodate PERL array
      ##      ...subscript.
      if ($category && $$mcl{$query->param($_)}=~ /^\d+$/){
            $search_col=$$mcl{$query->param($_)};
            $start_col=$search_col;
            $end_col=$search_col;
            $sort_on=$$mcl{$query->param($_)};
            ++$sort_on;
      }
}

if (!$sort_on){      ##      Invalid column selected for search
      print "<FONT COLOR=RED>This category cannot be searched for this list!!</FONT>";
      exit;
}

if ($DEBUG){
      print "<B>Search Column = >$search_col<</B>\n";
      print "<B>Sort on = >$sort_on<</B>\n";
      print "<BR>Headers are @header<BR>\n";
}

$search_string="" if ($search_string=~ /^\s+$/);      ##      Search text cannot have only white spaces.

##      Untaint the search string.
$search_string=~ s/[\?\[\]\;\<\>\*\|\'\&\$\!\#\(\)\{\}\:\`\"\%\\\n\r\^]//g;

print "<FONT COLOR=GREEN>","Search Column is $search_col</FONT><BR>\n" if $DEBUG;

##      Print the statistics of the search
print "<B>","Search for courses by ",$header[$search_col],"<B><BR>\n";
print "<B>","Search results sorted by ",$header[$search_col],"<B><BR>\n";
print "<B>","Search for <I>",$search_string,"</I><B><BR>\n";

$data_file=$$mcl{'data_file'};

if ($DEBUG){
      print "<FONT COLOR=GREEN><B>Opening Data file $data_file</B></FONT><BR>\n";
}

##      Open the file for reading. If open is unsuccessfull...
##      ... show the reason and exit the program
open(MYFILE,$data_file) || die $!;
##      "Slurp" the ENTIRE file, so that every line in the ...
##      ... file is stored as an element in the array
@lines=<MYFILE>;
close(MYFILE);      ##      Close the file

print qq{<FONT COLOR=GREEN>Start is $start_col, End is $end_col</FONT><BR>\n} if $DEBUG;

foreach(@lines){
      chomp;
      @record=split(/$$mcl{'delimiter'}/,$_,12);
      pop(@record);      ##      Discard the last column, for now!!
      print "<FONT COLOR=GREEN>",$record[$search_col]," = ",$search_string      ,"<FONT><br>\n" if $DEBUG;

      foreach $col ($start_col .. $end_col){
            $record[$col]=~ s/^\s+//;      ##      Remove leading &...
            $record[$col]=~ s/\s+$//;      ##      ... trailing spaces.
            if ($record[$col]=~ /^$search_string/i){
                  push(@recs,$_);
                  last;
            }
      }
}

##      Column num (starting from 1), type of sort
##      n = numeric, a = alphabetic ...
##      ... Sort order "a" = ascending, "d"= descending,
##      ... reference to the array that needs to be sorted & ...
##      ...      the delimiter between the different column.
@new=&my_sort($sort_on,"a","a",\@recs,$$mcl{'delimiter'});


my ($no_of_matches) = scalar(@new);
print "<B>",$no_of_matches," matches found</B></P>\n";


if (scalar (@new)){      ##      Some results were found!!
      print "<TABLE BORDER=1>\n";
      ##      Print out the array after the sorting has been done.
      foreach(@header){
            print qq{<TD ALIGN=CENTER><B>$_</B></TD>};
      }
      print "<TR>\n";

      foreach(@new){
            chomp;
            ##      We only want the first 12 columns.
            @which_cols=split(/$$mcl{'delimiter'}/,$_,12);
            foreach($[ .. $#which_cols){
                  print "<TD>",$which_cols[$_],"&nbsp;</TD>";
            }
            print "<TR>\n";
      }
      print "</TABLE>\n";
}

##      Subroutine that does the actual sort.
##      Accepts 5 params viz..
##      1. The column number to sort. Column no. start from 1.
##      2. The type of sort numeric or alphabetic. Default is Alphabetic.
##      3. The order of sort. Default order is ascending
##      4. The referrence of the array that needs to be sorted.
##      5. The delimiter between the different column of the array.
sub my_sort{
      my ($col,$type,$sort_order,$arr,$delimiter)=@_;

      $esc_delimiter=$delimiter;

      ##      Deduct 1 from the column.
      ##      We do this because in PERL array subscript starts with 0.
      ##      So in human terms when we say column 2 it means column 1 in PERL terms!!
      $col--;

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "n" or "N". Eg. if the user has said &my_sort(3,"z",@array,"a"), we ignore the z and perform an alphabetic sort ("a").
      $type="a" if $type!~ /^n$/i;      ##      Default Alphabetic sort

      ##      To take care of conditions where user has passed anything other
      ##      ... than a "d" or "D". Eg. if the user has said &my_sort(3,"z",@array,"q"), we ignore the q and sort in ascending order("a").
      $sort_order="a" if $sort_order!~ /^d$/i;      ##      Default Ascending Sort order

      ##      For future use. Possibly for delimiter validation and escaping.
      $esc_delimiter=~ s/(\\|\/|\||\.|\*)/\\$1/g;

      ##      Process every element of the array
      foreach(@$arr){
            ##      Split every line using the delimiter that the user has specified.
            @tmp=split(/$esc_delimiter/,$_);

            ##      After we split we know how many columns are ..
            ##      ... present in every record. Now we have to ...
            ##      ... take care of situations where the user might want ..
            ##      ... to sort on non-existant or invalid columns.
            ##      Eg. Each record has 6 columns and the user has passed 7 or 8
            ##      ... or -1 etc...

            return null if ($col<0 || $col>(scalar @tmp));      ## Invalid col no.

            ##      This is important. We take the column that the user wants ...
            ##      ... to sort on and pre-pend it to the record itself.

            ##      Let's say the record is ...
            # Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      and , is the delimiter ...
            ##      ...& the user wants to sort on the 2nd column (PERL subscript 1).
            $new_arr=join($delimiter,$tmp[$col],$_);

            ##      After the above the record will be...
            # Jeff|Toronto|Jeff|jeff@hyrum.net|98|571803

            ##      Store this new record in an array
            push(@new_arr,$new_arr);
      }

      ##      Determine the type of sort
      if ($type=~ /^n$/i){            ##      Numeric Sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by number using the bynum subroutine
                  @new_arr=reverse sort bynum @new_arr;
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort bynum @new_arr;
            }
      }else{      ##      Alphabetic sort
            if ($sort_order=~ /^d$/i){      ##      Descending sort requested
                  ##      Sort the array by alphabets using the byalp subroutine
                  @new_arr=reverse sort byalp @new_arr
            }else{      ##      Default, Ascending sort order requested
                  @new_arr=sort byalp @new_arr
            }
      }

      undef @arr;      ##      Re initialize the array
      ##      Remember our sort is done, but we still have that...
      ##      ...extra column at the beggining that we must remove!!
      foreach(@new_arr){
            ##      Split every line using | as the delimiter.
            @tmp=split(/$esc_delimiter/,$_);
            shift(@tmp);      ##      Remove that 1st column
            ##      So before the shift if we had....
            # Jeff,Toronto,Jeff,jeff@hyrum.net,98,571803
            ##      After th shift we will have...
            # Toronto,Jeff,jeff@hyrum.net,98,571803

            ##      Join the array as one record...
            $new_arr=join($delimiter,@tmp);
            ##      ...& store it in another array.
            push(@arr,$new_arr);
      }

      ##      Return the final array (in sorted order)
      return @arr;
}

sub bynum{ $a <=> $b;}

sub byalp{ $a cmp $b;}


"..what needs to be changed in the code so it will work on NT ."

like you have yourself explained abov, the problem is not with the code but with something outside it.

had the problem been with the code, the behaviour would have been consistent across browsers and versions.

Also the extra character(s) that appears in the results page does not appear when the search results are few.

this would point to a lack of memory resources for the application.

i would suggest you try viewing the site from another machine running IE.

Let me know if you can still see the extra/junk characters


melq,

Pl. let me know if u are having the same problem using my script..

thanx
Amandeep,

Well, ... here is where we're at.

Your script is working excellent.  It just needs a small tune-up ... and it should be done I imagine.  :-)))

It works on an NT server as well as on Unix.  (GREAT!)

In difference from Maneshr's script ... the only dilemma was that in IE (for some unknown reason ... that we couldn't figure out) ... it would give us some garbage in the output when running the script on an NT server ... and using IE 5.5.  It was really weird ... and I'd still love to figure out how that could be fixed.

But anyhow ... your script is working wonderfully.

Here are the slight 'tune-up' changes that need to be made.

1)  When and if the user selects to search the CANCELLED course list (from section 1) and then selects to search by  Instructor's Last Name (from section 2) ... this is not a supported feature since the ccl.txt file does not include the Instructor's Last Name.  So, if you can ... (which was done in Maneshr's script) ....... if the user made those two selections together ... they would get a returned page that said "This category cannot be searched for this list!!"

This simply informed them that the search type was not available.  (I will be putting a warning on the HTML page, but this part of the script insures that even if they don't catch the warning, it will display a defined message.)

Currently, when I select these two items using your script, I get back a lot of error messages ... basically.

2)  The last field in the mcl.txt file (which is basically the comments field) ... they use commas to separate one comment from another.  This problem only exists in the last column of the mcl.txt file.  What is happening is ... using your script (currently) ... since we're using a ' , ' (comma) as the delimiter ... when and if the comment field uses one or more commas to separate the individual comments ... it throws the table and display of the information off.  

Now, in Maneshr's script, somehow he set it up so the additional commas in this field didn't effect the output.  But, currently in your script ... it is throwing the display off when commas are included in this field.

We can try to do one of two things.  Either ... (if you can) .. you could change your script (slightly) so that if and when commas are included in this last field (the comments field at the end of each line) ... it will ignore any commas that may be present - within the last field.

Or ... we can use, as I thought would also work ... a  ' ~ ' (tilda) in place of a ' , ' (comma) ... to use as the delimiter.  This would hopefully all us to use commas ... anywhere in the .txt files and not effect the output.

Let me know which way you'd recommend.

3)  I am not sure why this is a problem ... but I am concerned for two reasons.  The problem is .. that in Netscape (using version 4.75) ... for some reason, when I search the ENTIRE Master Course List ... without entering in any text in section 3 ... it very often will FREEZE up and stop.  It should be returning 1607 records.  But, over time, this may even grow to 2000 records, etc.

So, is there anything we can do ... that you can think of to help resolve this problem so it won't FREEZE up due to the size of the file it is searching and returning???


That's about all I can see.  Everything else appears to be working wonderfully.

I should be able to change the look and feel of the output (with regard to font sizes, colored background, etc.)

So, ... I just need these changes to be made.

Would this be possible????  


(And, if you can - which I not sure if you will be able to ... but I'd love to figure out why Maneshr's script was giving me the garbage in the output ... since it was only occurring when I was running the script on an NT server and then accessing the script using IE 5.5.  I tried accessing the script from two different machines ... using IE 5.5, and got the garbage in both situations.  Your thoughts would be appreciated.)

Thanks a lot....

Gary


I am glad to know that my solution could help u in some way. :-)

As for ur 2nd comment is concerned, I had already posted the modified script earlier which was using the '~' seperated fields in txt files. Please check that and let me know.

The other problems I will check and get back soon.

Thanx
Sounds great!

Thanks again for an excellent job!!!!!

I will looking for the 'fix'.  :-)))

Gary

PS:   If you can, be sure to look into the problem with Netscape, when I try and retrieve the entire list.  Just as a note ... I didn't have this problem with Maneshr's script - due to however it was written.  I hope that info helps regarding the problem.

Ok melq,

try this and let me know :

#!/usr/bin/perl

use CGI;
$cgi=new CGI;


$|++;

$mcl=$cgi->param('mcl');
$category=$cgi->param('category');
$search=$cgi->param('search');
$referer=$cgi->referer;

$delimiter=',';

%courselistFile=('current'=>'mcl.txt', 'cancelled'=>'ccl.txt');

## In the mcl.txt the curse title is 5th column, Instructor is in 11th column and so on...

%column_current=('entire'=>5, 'instructor'=>11, 'department'=>2, 'number'=>3);
%column_cancelled=('entire'=>3, 'department'=>1, 'number'=>2);

$sortField=$column_current{$category} if ($mcl eq "current");
$sortField=$column_cancelled{$category} if ($mcl eq "cancelled");
$database=$courselistFile{$mcl};

print $cgi->header;
print $cgi->start_html(-title=>"Search Result");

if($mcl eq "cancelled" && $category eq "instructor") {
    print "<h4 align='center'>Sorry, This category cannot be searched for this list</h4>";

}
else {

my @records;
my %data=();

## pushing the records in @records & copying the key field as the first field for sorting.
my $sortKey='';
my $key;

open(DATA,"$database");
while(<DATA>) {
    chomp;
    $sortKey=(split(/$delimiter/,$_))[$sortField-1];
    $sortKey=~s/^\s+//;
    if($search) {
        push(@records,"$sortKey:$_") if ($sortKey=~/^$search/i);
    }
    else {
        push(@records,"$sortKey:$_");
    }
    $key=$sortKey if ($sortKey);
}
close(DATA);

$type=($key=~/[a-zA-Z]/)?"char":"num"; ## Checking the key to be Numeric or Character..
if($type eq "num") {
    @records=sort { ($a=~/^([^:]*):/)[0]  <=>  ($b=~/^([^:]*):/)[0] } @records;
}
else {
    @records=sort { ($a=~/^([^:]*):/)[0]  cmp  ($b=~/^([^:]*):/)[0] } @records;
}

print "<h2 align='center'>Search Result</h2>";


$ctr=1;
print qq{
    <table width='100%' border='0' align='center'>
};

foreach (@records) {
    my ($rec) = /:(.*)/ ;
    my @recs=split(/$delimiter/,$rec);
    $rec=join('</td><td>',@recs);
    print "<tr><td>$ctr</td><td>$rec</td></tr>\n";
    $ctr++;
}

print "</table>\n";

$ctr--;
}

print "<hr>";
print "Database Searched : $database <br>";
print "Category  : $category <br>";
print "Keyword : $search <br>";
print "Total Records : $ctr <br>";
print "<a href='$referer'>Click here to go back to the Search Page..</a>";
print $cgi->end_html;

Amandeep,

I tried the above revision.

Here is what I got.

1)  You did fix (and it works) the part where by if the user selects to search the ccl.txt file ... AND ... tries to search for an Instructor's Last Name, ... they get the 'Sorry ...' message.  That looks perfect.

2)  I tried the script, without making any changes to the table border settings, ... and in Netscape ... it is still Freezing up when it tries to pull up the entire MCL.TXT file.

3)  I changed your table border from '0' to '1' so the information would be read more easily.  And, when I did this, the fields that are separated by commas (in the last field) are still forcing themselves into new table fields.  

Your code (in this new revision) was using a ' , ' (comma) as the delimiter.  Is this code supposed to generate the output (so the last field - with the extra commas) all within one field??  Or, will I need to generate a .txt file using   ' ~ ' (tilda) as the delimiter in order to get this to work.

4)  One other thing ... how can we get the empty cells (where no inforamtion is provided) to display a  '  -  '  (dash or something) to indicate the cell has nothing in it, as opposed to just having it totally empty.

You can see the effects of this script at:

http://web.njcu.edu/registrar/misc/mcl_online_amandeep2.html

Let me know.... and thanks,
Gary
Manesh,

Here is Amandeep's code from a short while ago.  It worked good except for some of the things I mentioned in my comment:    Date: Thursday, October 12 2000 - 04:47AM PDT  -  found above.  (PLEASE LOOK AT THIS.)

Let me know when (and hopefully if ....) we can simply figure out how to get rid of the garbage in IE ... when running it on an NT server??  Everything else is just right!!

I am praying!!!!!   Really praying!!  :-)

Gary


AMANDEEP'S CODE:



#!/usr/bin/perl -wT

use CGI;
$cgi=new CGI;

$|++;

$mcl=$cgi->param('mcl');
$category=$cgi->param('category');
$search=$cgi->param('search');
$referer=$cgi->referer;

$delimiter=',';

%courselistFile=('current'=>'mcl.txt', 'cancelled'=>'ccl.txt');

## In the mcl.txt the curse title is 5th column, Instructor is in 11th column and so on...

%column_current=('entire'=>5, 'instructor'=>11, 'department'=>2, 'number'=>3);
%column_cancelled=('entire'=>3, 'department'=>1, 'number'=>2);

$sortField=$column_current{$category} if ($mcl eq "current");
$sortField=$column_cancelled{$category} if ($mcl eq "cancelled");
$database=$courselistFile{$mcl};

print $cgi->header;
print $cgi->start_html(-title=>"Search Result");

my @records;
my %data=();

## pushing the records in @records & copying the key field as the first field for sorting.
my $sortKey='';
my $key;

open(DATA,"$database");
while(<DATA>) {
chomp;
$sortKey=(split(/$delimiter/,$_))[$sortField-1];
$sortKey=~s/^\s+//;
if($search) {
push(@records,"$sortKey:$_") if ($sortKey=~/^$search/i);
}
else {
push(@records,"$sortKey:$_");
}
$key=$sortKey if ($sortKey);
}
close(DATA);

$type=($key=~/[a-zA-Z]/)?"char":"num"; ## Checking the key to be Numeric or Character..
if($type eq "num") {
@records=sort { ($a=~/^([^:]*):/)[0]  <=>  ($b=~/^([^:]*):/)[0] } @records;
}
else {
@records=sort { ($a=~/^([^:]*):/)[0]  cmp  ($b=~/^([^:]*):/)[0] } @records;
}

print "<h2 align='center'>Search Result</h2>";


$ctr=1;
print qq{
<table width='100%' border='1' bgcolor='#dddddd' align='center'>
};

foreach (@records) {
my ($rec) = /:(.*)/ ;
my @recs=split(/$delimiter/,$rec);
$rec=join('</td><td>',@recs);
print "<tr><td>$ctr</td><td>$rec</td></tr>\n";
$ctr++;
}

print "</table>\n";

$ctr--;

print "<hr>";
print "Database Searched : $database <br>";
print "Category  : $category <br>";
print "Keyword : $search <br>";
print "Total Records : $ctr <br>";
print "<a href='$referer'>Click here to go back to the Search Page..</a>";
print $cgi->end_html;



See the results of this code at:

http://web.njcu.edu/registrar/misc/mcl_online_amandeep.html

Thanks,
Gary

 
Hi melq,

I'm sorry I forgot to change the $delimiter to '~', as I was testing the code at my end using ur comma seperated text files. Simply change the $delimiter as

$delimiter='~';

 - As far as the netscape is concerned I tested it at my end on Netscape 4.5.
The browser seemed to be freezing, but it did give the entire output. Only thing is that it takes some more time to read and render the page compared to IE.

 - If u want '-' to be displayed in case of blank fields, then just modify the foreach loop as :

foreach (@records) {
    my ($rec) = /:(.*)/ ;
    my @recs=split(/$delimiter/,$rec);
    my @r=map($_=~s/^\s*$/\-/,@recs);
    $rec=join('</td><td>',@recs);
    print "<tr><td>$ctr</td><td>$rec</td></tr>\n";
    $ctr++;
}


Try it and let me know.
Amandeep,

Whew.  It works!!

I didn't try the cancelled list .. but would it be safe to assume that if it worked on the Master Course List, ... that it will work on the Cancelled Course List???   Hip-hip-hurray!!!!

Now, here is what I need to wrap this thing up.  hahahahaha

1)  How do I go about adding (to the output from the .txt files - when they are searched) ... the TITLES for each column that I want to us?   Where do I put it in ... and .. can you re-write the code (as you did with the foreach loop) and tell me where to put it?  

2)  If I want to make the TITLES that I described in the above question (appear within the table) ... but have a shaded bgcolor (maybe a light yellow, etc.) for those <td> cells, please include that information within the code.  But, I still want the output from the .txt file to still appear on a different color - ... probably just white.

3)  If I want to insert my own TOP SECTION TO THE WEBPAGE OUPUT (which will resemble the current TOP SECTION of the website (as it is currently designed).  Where should I place the required HTML code?  For an idea of what the top of the page needs to look like - you can see the current webpage at:

http://web.njcu.edu/registrar/courselist.html

4)  If I need to change the FONT SIZE of the output from the .txt files, how and where would I make this change in the Perl script.  I would like to be able to have the TITLES for each column appear larger and in BOLD (like <font size="2"><b>Department</b></font>, yet have the actual output from the .txt files appear slightly smaller ... probably like <font size="1">Johnson</font>.  

Please let me know how and where to modify the script to accomodate this.

5)  Could you please add comments for EVERY LINE of the script. I am trying to learn Perl and would like to fully understand how the script was put together, what each line is doing, why you wrote it the way you did (which was great) ... etc.  So, please comment the script (line by line) for me ... as if I didn't know anything about Perl (other than the very minimal basics) ... which is not far from the truth.  hahahaha

Thanks,
Thanks!!
Thanks!!!!
Gary
ASKER CERTIFIED SOLUTION
Avatar of amandeep
amandeep
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Amandeep,

I am getting an error that says ...

The document contained no data.
Try again later, or contact the server's administrator.

Any idea why??

I have everything set up (from what I can tell properly)??


Sorry I did not test it earlier. This is tested one :

-------------------
#!/usr/bin/perl

use CGI;
$cgi=new CGI;

$|++;

$mcl=$cgi->param('mcl');
$category=$cgi->param('category');
$search=$cgi->param('search');
$referer=$cgi->referer;

$delimiter='~';

%courselistFile=('current'=>'mcl.txt', 'cancelled'=>'ccl.txt');

## In the mcl.txt the curse title is 5th column, Instructor is in 11th column and so on...

%column_current=('entire'=>5, 'instructor'=>11, 'department'=>2, 'number'=>3);
%column_cancelled=('entire'=>3, 'department'=>1, 'number'=>2);
@current_headers=("No.","Days","Department Name","Course Catalog number","Class section number","Course Title",
"Semester Hours","Day(s)","Start time","End time","Building/Room Location","Instructors Last Name","GPA Require
d");
@cancelled_headers=("No.","Department Name","Course Catalog number","Course Title","Class section number","Stat
us","Terms");

if ($mcl eq "current") {
$sortField=$column_current{$category};
@headers=@current_headers;
}
 if ($mcl eq "cancelled") {
$sortField=$column_cancelled{$category};
@headers=@cancelled_headers;
}

$database=$courselistFile{$mcl};

print $cgi->header;
print qq{
<html>
<head>
<title>Search Result</title>
<style type="text/css">
..headers {
font-family: arial, helvetica;
font-size: 10pt;
font-weight: bold;
background-color: #996600;
color: #ffffff;
}
..records {
font-family: arial, helvetica;
font-size: 8pt;
}
</style>
<script language='javascript'>
<!--
//Your Javascript code here...
-->
</script>
</head>
<body>

<!-- You can put your TOP SECTION here.. -->

};

if($mcl eq "cancelled" && $category eq "instructor") {
    print "<h4 align='center'>Sorry, This category cannot be searched for this list</h4>";

}
else {

my @records;
my %data=();

## pushing the records in @records & copying the key field as the first field for sorting.
my $sortKey='';
my $key;
open(DATA,"$database") or die "cannot open database file : $! \n";
while(<DATA>) {
    chomp;
    $sortKey=(split(/$delimiter/,$_))[$sortField-1];
    $sortKey=~s/^\s+//;
    if($search) {
        push(@records,"$sortKey:$_") if ($sortKey=~/^$search/i);
    }
    else {
        push(@records,"$sortKey:$_");
    }
    $key=$sortKey if ($sortKey);
}
close(DATA);
$type=($key=~/[a-zA-Z]/)?"char":"num"; ## Checking the key to be Numeric or Character..
if($type eq "num") {
    @records=sort { ($a=~/^([^:]*):/)[0]  <=>  ($b=~/^([^:]*):/)[0] } @records;
}
else {
    @records=sort { ($a=~/^([^:]*):/)[0]  cmp  ($b=~/^([^:]*):/)[0] } @records;
}
print "<h2 align='center'>Search Result</h2>";

$ctr=1;
print qq{
    <table width='100%' border='1' align='center'>
};

## Print the headers here...
print "<tr class='headers'>\n";
foreach (@headers) {
print "<td>$_</td>";
}
print "</tr>\n";
####

## Printing the records here...
foreach (@records) {
    my ($rec) = /:(.*)/ ;
    my @recs=split(/$delimiter/,$rec);
    my @r=map($_=~s/^\s*$/\-/,@recs);
    $rec=join('</td><td>',@recs);
    print "<tr class='records'><td>$ctr</td><td>$rec</td></tr>\n";
    $ctr++;
}
####

print "</table>\n";
$ctr--;
}

print qq{
<hr>
Database Searched : $database <br>
Category  : $category <br>
Keyword : $search <br>
Total Records : $ctr <br>
<a href='$referer'>Click here to go back to the Search Page..</a>

};

print $cgi->end_html;

-----------------

let me know ..
Amandeep,

Working very well.

Here is the script ... with small cosmetic changes made to it only.

#!/usr/bin/perl -wT

use CGI;
$cgi=new CGI;

$|++;

$mcl=$cgi->param('mcl');
$category=$cgi->param('category');
$search=$cgi->param('search');
$referer=$cgi->referer;

$delimiter='~';

%courselistFile=('current'=>'/InetPub/database/registrar/mcl_sp01.txt', 'cancelled'=>'/InetPub/database/registrar/ccl_sp01.txt');

## In the mcl.txt the course title is 5th column, Instructor is in 13th column and so on...

%column_current=('entire'=>5, 'instructor'=>13, 'department'=>2, 'number'=>3);
%column_cancelled=('entire'=>3, 'department'=>1, 'number'=>2);
@current_headers=("No.","Day/Eve","Department Name","Course Catalog Number","Class Section Number","Course Title","Semester Hours","-","Day(s)","-","Start Time","End Time","Building/Room Location","Instructor's Last Name","Comments");
@cancelled_headers=("No.","Department Name","Course Catalog number","Course Title","Class section number","Status","Terms");

if ($mcl eq "current") {
$sortField=$column_current{$category};
@headers=@current_headers;
}
if ($mcl eq "cancelled") {
$sortField=$column_cancelled{$category};
@headers=@cancelled_headers;
}

$database=$courselistFile{$mcl};

print $cgi->header;
print qq{
<html>
<head>
<title>Search Result</title>
<style type="text/css">
..headers {
font-family: arial, helvetica;
font-size: 10pt;
font-weight: bold;
background-color: #996600;
color: #ffffff;
}
..records {
font-family: arial, helvetica;
font-size: 8pt;
}
</style>

<script language='javascript'>
<!--


//-->
</script>
</head>

<body>

<!-- You can put your TOP SECTION here.. -->

};

if($mcl eq "cancelled" && $category eq "instructor") {
   print "<h4 align='center'>Sorry, This category cannot be searched for this list</h4>";

}
else {

my @records;
my %data=();

## pushing the records in @records & copying the key field as the first field for sorting.
my $sortKey='';
my $key;
open(DATA,"$database") or die "cannot open database file : $! \n";
while(<DATA>) {
   chomp;
   $sortKey=(split(/$delimiter/,$_))[$sortField-1];
   $sortKey=~s/^\s+//;
   if($search) {
       push(@records,"$sortKey:$_") if ($sortKey=~/^$search/i);
   }
   else {
       push(@records,"$sortKey:$_");
   }
   $key=$sortKey if ($sortKey);
}
close(DATA);
$type=($key=~/[a-zA-Z]/)?"char":"num"; ## Checking the key to be Numeric or Character..
if($type eq "num") {
   @records=sort { ($a=~/^([^:]*):/)[0]  <=>  ($b=~/^([^:]*):/)[0] } @records;
}
else {
   @records=sort { ($a=~/^([^:]*):/)[0]  cmp  ($b=~/^([^:]*):/)[0] } @records;
}
print "<h2 align='center'>Search Result</h2>";

$ctr=1;
print qq{
   <div align='center'>
       <table width='100%' border='2'>
};

## Print the headers here...
print "<tr class='headers'>\n";
foreach (@headers) {
print "<td valign='top' align='center' bgcolor='#ffffcc'><font size='1'>$_</font></td>";
}
print "</tr><tr class='records'>\n";
####

## Printing the records here...
foreach (@records) {
   my ($rec) = /:(.*)/ ;
   my @recs=split(/$delimiter/,$rec);
   my @r=map($_=~s/^\s*$/\-/,@recs);
   $rec=join('<td valign="top"><font size="1">',@recs,'</font></td>');
   print "<td valign='top'><font size='1'>$ctr</font></td> <td valign='top'><font size='1'>$rec</font></td></tr>\n";
   $ctr++;
}
####

print "</table></div>\n\n";
$ctr--;
}

print qq{
<hr width='100%' size='5' align='center'>
<br>
Keyword That Was Searched: $search <br>
Total Number Of Records Found: $ctr <br>
Category Searched : $category <br>
Database File That Was Searched : $database <br><br>
<b><font size="2"><a href='$referer'>Click here to go back to the Search Page..</a></font></b>
<br><br><br>
</body>
</html>

};

print $cgi->end_html;



Now. ....

I tried dropping my Javascript into the Header and the BODY portion into where you indicated, but I got an error.

Am I supposed to just cut and paste???  Will it work with the Javascript having double quotes around certain items, and in the body I have certain items with double quotes.  Will any of this be causing a problem.

Here is the Javascript and Body portion that needs to be at the top.


JAVASCRIPT and HTML that needs to appear in the top:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
      <title>NJCU REGISTRAR DEPARTMENT</title>

<meta name="description" content="NJCU REGISTRAR DEPARTMENT">
<meta name="keywords" content="New Jersey University, NJCU, Registrar, NJCU Registrar, Registrar Department">
<meta name="author" content="Gary M. Gordon">
<meta http-equiv="content-type" content="text/html; CHARSET=ISO-8859-1">
<meta http-equiv="content-language" content="en-GB">
<meta name="generator" content="homesite_4.5.1">
<meta http-equiv="Pragma" content="no-cache">
<meta name="robots" content="INDEX">
<meta name="copyright" content="NJCU">

<style type="text/css">
      TD {
      font-family: arial, helvetica;
      font-size: 10pt;
      color: #333333;
      }
</style>

<script language="javascript">

<!-- Hide the following script from old browsers.

if (document.images){

var calendaroff = new Image();

calendaroff.src="images/littlegreenarrow.gif";

var calendaron = new Image();

calendaron.src="images/littlegoldarrow.gif";


var transcriptoff = new Image();

transcriptoff.src="images/littlegreenarrow.gif";

var transcripton = new Image();

transcripton.src="images/littlegoldarrow.gif";


var regulationsoff = new Image();

regulationsoff.src="images/littlegreenarrow.gif";

var regulationson = new Image();

regulationson.src="images/littlegoldarrow.gif";


var gradesoff = new Image();

gradesoff.src="images/littlegreenarrow.gif";

var gradeson = new Image();

gradeson.src="images/littlegoldarrow.gif";


var registrationoff = new Image();

registrationoff.src="images/littlegreenarrow.gif";

var registrationon = new Image();

registrationon.src="images/littlegoldarrow.gif";


var courselistoff = new Image();

courselistoff.src="images/littlegreenarrow.gif";

var courseliston = new Image();

courseliston.src="images/littlegoldarrow.gif";

var njcuon = new Image();

njcuon.src="images/njcu_logo_button_08092000_over.jpg";

var njcuoff = new Image();

njcuoff.src="images/njcu_logo_button_08092000_up.jpg";

var njcudown = new Image();

njcudown.src="images/njcu_logo_button_08092000_down.jpg";


var registraron = new Image();

registraron.src="images/RegistrarOfficeLogo_over.gif";

var registraroff = new Image();

registraroff.src="images/RegistrarOfficeLogo.gif";


}


function imgoff(imgName)      {

if (document.images)      {

document[imgName].src=eval(imgName+"off.src");  
            }
      }


function imgon(imgName){

if (document.images){

document[imgName].src=eval(imgName+"on.src");

            }
      }

function imgdown(imgName){

if (document.images){

document[imgName].src=eval(imgName+"down.src");

            }
      }

// End hiding this script from old browsers. -->

</script>
</head>

<body text="#333333" bgcolor="#ffffff" link="#808080" alink="#cc3300" vlink="#006699" marginheight="0" marginwidth="0" leftmargin="0" topmargin="0">

<table border="0" cellpadding="0" cellspacing="0" width="100%" summary="Registrar Department Logo">
            <tr>
                              <td width="1" bgcolor="#336666"><img src="images/spacer.gif" width="1" height="1" border="0" alt=""></td>
               <td align="left" width="225" bgcolor="#336666"><img src="images/spacer.gif" width="6" height="6" border="0" alt=""><br><a href="vision.html" onmouseover="imgon('registrar')" onmouseout="imgoff('registrar')"><img name="registrar" src="images/RegistrarOfficeLogo.gif" width="230" height="34" border="0" alt="Go to Registrar Department Home Page" title="Go to Registrar Department Home Page"></a><img src="images/spacer.gif" width="5" height="5" border="0" alt=""></td>
                              <td align="right" width="375" bgcolor="#336666" valign="bottom"><font face="arial, helvetica" size="2" color="#999999"><div style="color: #999999; font-size: 10pt; font-family: arial, helvetica; font-weight: normal;"> |  &nbsp; <a style="color: #ffffff; text-decoration: none;" href="mailto:cdixon@njcu.edu"><font color="#ffffff">E-mail Us</font></a> &nbsp; | </div></font><img src="images/spacer.gif" width="5" height="5" border="0" alt=""></td>
                              <td bgcolor="#336666" width="100">&nbsp;</td>
            </tr>
</table>

<table border="0" summary="opening message and NJCU logo" cellpadding="0" width="640">
   <tr>
      <td valign="top" width="140"><a href="http://www.njcu.edu/" onmouseover="imgon('njcu')" onmouseout="imgoff('njcu')" onmousedown="imgdown('njcu')"><img src="images/njcu_logo_button_08092000_up.jpg" width="145" height="127" border="0" alt="Go to the NJCU WEBSITE" title="Go to the NJCU WEBSITE" name="njcu"></a></td>
            <td valign="top">


                  <table border="0" width="450" align="center">
                        <tr>
                              <td valign="top" width="295"><font face="arial, helvetica" size="2" color="#333333"><a href="calendar.html" onmouseover="imgon('calendar')" onmouseout="imgoff('calendar')"><img name="calendar" src="images/littlegreenarrow.gif" width="7" height="11" border="0" alt="Calendar" title="Calendar"></a> <a href="calendar.html">CALENDAR</a></font></td>
                              <td valign="top" width="200"><font face="arial, helvetica" size="2" color="#333333"><a href="transcript.html" onmouseover="imgon('transcript')" onmouseout="imgoff('transcript')"><img src="images/littlegreenarrow.gif" width="7" height="11" border="0" alt="Transcripts" title="Transcripts" name="transcript"></a> <a href="transcript.html">TRANSCRIPTS</a></font></td>
                        </tr>

                        <tr>
                              <td valign="top" width="295"><font face="arial, helvetica" size="2" color="#333333"><a href="regulations.html" onmouseover="imgon('regulations')" onmouseout="imgoff('regulations')"><img name="regulations" src="images/littlegreenarrow.gif" width="7" height="11" border="0" alt="Regulations" title="Regulations"></a> <a href="regulations.html">REGULATIONS and POLICIES</a></font></td>
                              <td valign="top" width="200"><font face="arial, helvetica" size="2" color="#333333"><a href="grades.html" onmouseover="imgon('grades')" onmouseout="imgoff('grades')"><img src="images/littlegreenarrow.gif" width="7" height="11" border="0" alt="Final Grades" title="Final Grades" name="grades"></a> <a href="finalgrades.html">FINAL GRADES</a></font></td>
                        </tr>

                        <tr>
                              <td valign="top" width="295"><font face="arial, helvetica" size="2" color="#333333"><a href="registration.html" onmouseover="imgon('registration')" onmouseout="imgoff('registration')"><img src="images/littlegreenarrow.gif" width="7" height="11" border="0" title="Registration Details" alt="Registration Details" name="registration"></a> <a href="registration.html">REGISTRATION DETAILS</a></font></td>
                              <td valign="top" width="200"><font face="arial, helvetica" size="2" color="#333333"><a href="courselist.html" onmouseover="imgon('courselist')" onmouseout="imgoff('courselist')"><img src="images/littlegreenarrow.gif" width="7" height="11" border="0" title="Master Course List" alt="Master Course List" name="courselist"></a> <a href="courselist.html">MASTER COURSE LIST</a></font></td>
                        </tr>
                  </table>

<br>
<center>
<table cellspacing="0" cellpadding="1" border="0" width="325" align="center">
<tr>
<td align="center" bgcolor="#336666">

            <table cellspacing="0" cellpadding="1" border="0" width="100%">
            <tr>
            <td align="center" bgcolor="#cc9900">

                        <table cellspacing="0" border="0" width="100%">
                        <tr>
                        <td valign="top" align="center" bgcolor="#ddddcc"><font face="arial, helvetica" size="5" color="#000000"><b>
                        <span style="font-family: arial, helvetica; font-size: 16pt; color: #000000; font-weight: bold;">MASTER COURSE LIST</span>
                        </b></font></td>
                        </tr>
                        </table>

            </td>
            </tr>
            </table>

      </td>
      </tr>
      </table>
</center>

</td>
</tr>
</table>


Then ... Other stuff ... to the END ...

</body>
</html>



Can you show me where and how to enter this stuff into the script???

Thanks,
Gary
Amandeep,

Also ... I tried searching for CANCELLED COURSES, and by Instructor's Last Name ... and got an error.

See it at:

http://web.njcu.edu/registrar/misc/mcl_online_amandeep3.html

Error:

Use of uninitialized value at C:\InetPub\www\cgi-bin\mcl_amandeep3.pl line 133.

Anyhow ... that was the only thing I found.

LOOKS GREAT!!

By the way, aside from my prior question (that I posted just before) the only thing that left that I would appreciate before I close this out and give you the points (plus an additional 100 for all your extra help) ... is if you would comment EACH line of the code ... so I can understand what each part is doing.  I apologize for my lack of knowledge with this ... but if you wouldn't mind adding comments - as if you were teaching someone how to write this .. I'D GREATLY APPRECIATE IT.

Thanks, .....

Gary

I have mailed u the script.
Pl. check and let me know.

Aman.
Aman,

Everything is perfect ... except I am still getting an error when I search the Cancelled Course List ... and for an Instructor's Last Name.  

I get the line that comes up saying ...

Sorry, This category cannot be searched for this list.

But ... I still get this error that appears just below it.

Use of uninitialized value at C:\InetPub\www\cgi-bin\mcl_amandeep3.pl line 281.

Aside from that ... everything looks perfect.

Please let me know what I need to correct so this doesn't come up.

Thanks,
Gary
Wonderful job.

Thanks,
Gary