Skagit Valley College Educational Planning Tool

Faculty and students needed a way to plan out the degree path of a student. The faculty and counselors needed to be able to track the student’s progress over the time they are attending SVC.

My role in this project was to create a responsive modern view to allow the faculty or student to create a “Degree Plan” using live data from our catalog of classes and student records.

Integrated student and class data from legacy systems using a custom built api to convert the data between modern display style and the legacy storage style.

Needed to overcome obstacles related to the formatting of the legacy data such as converting dates and times into human readable text. Also creating conversion algorithms to deal with displaying legible content instead of the codes that the data is stored in.

allow the faculty counselor and mentors to track the student progress over the life of the plan.

Development of the Paperless Diploma Application Form inspires the new 3dw Tools Form Content Display Wizard

I was working on a way to break up page content and display it in user friendly chunks. Very similar to the Jquery Form Wizard plugin, but hopefully a lot easier to use. After years of making forms into applications, I have come up with  an algorithm to plug into any form or content that will transform it into a paperless web application with the following features:

  • To a developers point of view the best thing is Automation!
  • Content organized and displayed to the user in an easy to navigate style.
  • Client side validation for form elements when and where needed.
  • Form summary and easy ability to make changes before submit.
  • Takes care of form data submission using Ajax to hand the data on a silver platter to any api.

Here are the notes to myself while developing.

Hiding and Displaying content

The first decision is how to break up the content chunks. Well, a div with an id of “step_xxx” seems like a good idea. XXX should be a detailed way to identify the content such as “step_intro” “step_personal_info”. I will put these divs on the page in the correct order that they would be accessed, with the exception of where the paths branch off.

So now I have my content set up in chunks that I can select and identify using JavaScript. I am going to use JQuery because of it’s powerful selection abilities. One little bit of code gives me the selection I need…

$('div[id^="step_"]').hide(); // select and hide all divs with id containing "step_" in the id.

Well this is a good start, but now I need to determine how many steps are in my display, create an index or table of contents, and then step the user through them as needed.

Creating a table of contents

My initial selector from above gives me the power to do more than just show/hide the elements that are selected. By turning this selection into a list, I can come up with a table of contents for my users to know exactly what kind of huge form they are about to fill out. Give them a chance to chicken out :)

I have created a function to list this table of contents:

function createTableofContents(){
for(i=0;i<totalsteps;i++){
$("#step_intro").append("<p>Step:"+thesteps[i].id+" || Find a way to put the contents of the first child element here as description text</p>");
}
}

But its rough. We need to put the toc into a container styled to display in a sidebar list view. Lets check the dom for the existence of id tableofcontents, create it if its not there, then append the steps array. This would allow to drop into any form, yet give advanced users the ability to make a custom view to display the toc.

Now I need a way to give these steps a description that would mean something to the user, since they probably don’t care about “step_step1a”. Referring to my previous post on using custom attributes, I feel like this would be a good place to use them. I don’t want to put it as a title , because the elements inside the div will need to have their own titles. I am going to give each step an attribute of stepdesc and assign it a value that would be a good description of the step.

Now when the page loads, the huge amount of content is hidden , and the user is presented with a wizard to guide them through the steps, and even a table of contents so they know where they are in the wizard.

Moving through the wizard steps

I need to look for existing elements named : “stepDownButton” and “stepUpButton” . If they are not there, then create them. If they are there, then leave it alone. This will allow for a button to be put in place where user needs a branch off the linear path. If the content is on a linear path, the plug in will create all the buttons to step through the content. In the first step, make a special button to “begin”. in the second to last step make the “next”  button into a  “submit” button instead.

*** is it possible to add the abilty to hit enter and have it click the next button.? lets try it soon.

Validating User Input

Now I need to provide a means of validation for each step that has a required field. I will make a function to call for each step, check whether there is a required element, and validate if needed. I would like to pass this off to the jquyer validaton plugin. Need to work on this though, cause its called a little differently than I had setup for. They add an attribute of required to the element rather than a class. Also having trouble to plug in the validator to my plug in lol.

function validateIt(whatstep){    objectstovalidate = $("#"+whatstep+"  .required");    if(objectstovalidate.length>0){    alert('validate step: '+whatstep + ' ' +objectstovalidate.length);    }   } //end validator function.

This works good on the select and the inputs, but radio buttons are always a pain in the ass. Good thing I have my previous post on working with checkboxes and radio buttons to refer to.  I don’t want to add the additional code to loop through these, and figure out what value would be required, then have to alter my validator function. I am going to use a hidden text field, make it required, and put the value of the chosen radio button into it. That should enforce validation on choosing a radio button.

******** its working ok, but then there is a duplicate field in the form summary: Commencement Attendance Option : mtvernoncampus<– from the radio button choice. Commencement Attendance Option Choice : mtvernoncampus<– from the hidden text field.

I’m going to need a better way to validate a group of radio buttons if  this plug in will work everywhere easily.*************

$("input[type='radio'][name='commencementattendanceoption']").on("change", function(){
				alert($( this ).val())
			});

Dynamic fields and validation.

I want to make a reusable code to add a dynamic field with validation. I need to add text box to allow user to attach transcripts.

I will pass the step  id into a function to create the dynamic fields in the container. with validation and ability to delete the addl field and its validation.

form summary

A major goal is to provide a solution for the summary and display of user’s data before form submission, so they may go back and correct any errors.
In the second to last step, the plugin will set the the “NEXT” button onclick to stepUp(‘submit’);  The plugin will add a summary of the data the user entered so they may go back and make any changes. You may choose a custom display of the summary by putting an element with id “formsummaryarea” into this step. The plugin will omit any empty or hidden fields from the summary, and you can put class “nosummary” to omit any other items from the summary.

It seems that i need to modify the summary when it displays the contents of a dropdown element, it needs to display the text rather than the value. For example, the dropdown for choose degree, the values are numeric, and the display is a text string. For the summary, telling the user that they chose document 10 is pointless, they need to confirm the text name of the doc that they chose.

<pre>

if($(“[name='”+this.name+”‘]”).is(“select”)){
thesummary=thesummary+”<br />”+field.name + ” : “+  $(“[name='”+this.name+”‘] :selected”).html();
}

</pre>

SQL Select with variable and IF statement

Sometimes I need to select from sql based on criteria from another query. In certain situations, you can use the server side scripting to manipulate and call queries, but other times for performance, the best way is to have SQL server handle the workload.

I can declare a variable and set it from one query, and use it in another. For example, I want to check if there are only one record for an RID code passed in as a parameter, and then update the record if so:

declare @RecordCount int

    set @RecordCount = (select  count(*) FROM [My].[dbo].[Table]  where RID= @RID)
IF @RecordCount == 1
UPDATE [My].[dbo].[Table] SET myBitField= 1 WHERE RecordId= @RecordId

Compare alphanumeric strings for greater/less than equality C#

I have some alphanumeric strings to compare. I need to know if A1234 is before B5678 when sorted alphanumerically. I also want to ignore the case of the alphabetic characters.

int comparison = String.Compare(A1234, B5678, comparisonType: StringComparison.OrdinalIgnoreCase);

The integer returned will be -1 if lower in order, 0 if equal and 1 if greater.

Split a comma delimited string into an array in C#

The ability to split a string is a common feature in programming. The way to implement this in c# is a bit different than most languages.

We have a string such as:

string myVars = “var1, var2, var3, var4”;

We need to split this string into an array of individual variables. That’s where our String.Split() method comes into play. Its pretty easy once you know the syntax. The Microsoft docs don’t mention this way:

string[] myArray = myVars.Split(‘,’);

The key is the single quotes around your delimiter in the split method.

Skagit Valley College Student Document Repository

A screen shot of the student document repository user interface.
A screen shot of the student document repository user interface.


If the Financial Aid Department is the heart of the college institution, then the Skagit Valley College was suffering from a stroke. The heart was clogged up from the result of years of managing paperwork using tried and true ancient techniques: the in person delivery of hand filed paper forms.

And then corona virus came to deliver the death blow. Due to the pandemic, the college campus was forced to close. Unable to allow students to come to campus and process in person financial aid meant that our college might suffer the same fate as several other Washington State institutions and be shut down completely.

They came to me with this problem desperate for a solution. They needed a document repository that could be integrated with our current Legacy student management system data, but that will also be able to transition with our data over the next few years as the school complete its moves to a new student data management system. They needed a way to assign the forms to the students, and a portal where students could securely upload their documents.

The college had a legacy document storage system in place, aging and in need of replacement. The system had fallen out of development and was no longer being supported. The decision was to either purchase an expensive out of the box system, or develop one in-house. Due to the success of previous projects, the President of SVC decided to have me develop a custom in-house document storage and management solution that would be easily integrated into our student data management system.

During the planning phase, the project management documents were drawn up, key deliverables determined, and the use case scenarios developed.

Throughout the software development life cycle, those documents were referred to in order to prevent feature / scope creep from setting back the projected completion date. Using Agile project management I completed several sprints of user story backlogs, and the scrum retrospectives revealed valuable lessons learned about the techniques used to program the application.

 In the midst of the pandemic, forced into working remotely, I was under the pressure to save the college by finishing my application well ahead of the projected schedule.

The project close was met with very satisfied stake holders, and the project sponsor was happy to sign off the completed product.

Compare old and new record for logging c#

You have an old record, and the new one to be saved to database. Generate a log of the changes made using this snipped.

string logmessage = "The Doc Repo Category " + oldDocCatTitle + " has been edited.";
                logmessage += (oldDocCatTitle != DocCatTitle) ? "The title changed from " + oldDocCatTitle + " to " + DocCatTitle + "." : "";
                logmessage += (oldDocCatDesc != DocCatDesc) ? "The description changed from " + oldDocCatDesc + " to " + DocCatDesc + "." : "";
                logmessage += (oldDocCatShared != DocCatShared) ? "The shared changed from " + oldDocCatShared.ToString() + " to " + DocCatShared.ToString() + "." : "";
                logmessage += (oldDocCatShowOnHome != DocCatShowOnHome) ? "The description changed from " + oldDocCatShowOnHome.ToString() + " to " + DocCatShowOnHome.ToString() + "." : "";
                if (oldDocCatTitle != DocCatTitle || oldDocCatDesc != DocCatDesc || oldDocCatShared != DocCatShared || oldDocCatShowOnHome != DocCatShowOnHome || oldDocCatLink != DocCatLink)
                {
                    bool addLog = dataProcessing.addLog(Session["adminSID"].ToString(), "", logmessage, out string logMessage);
                }

Return Post Variables from c# api as JSON array

Call to c# api using ajax and recieve an array of variables in JSON format.

javascript call to api: In aspx page, you can access a posted in variable such as an id…

const NewsID = ‘<%=Request.Form[“NewsID”]%>’;

… then call to api and get record from that id…

 $.ajax({
type: 'POST',
url: 'update.aspx/loadRecord',
data: JSON.stringify({ NewsID: NewsID }),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (msg) {
var obj =  jQuery.parseJSON(msg.d)
console.log("I have successfully called to the api.");

 // set the heading value
 $("#Heading").val(obj.Heading);
 // set the body value
 $("#Body").val(obj.Body);
}
});


The C# api receives the record id and returns a record…

... call to database and get record ...

var message = new {Heading=Heading, Body= Body};
return JsonConvert.SerializeObject(message);