Formatting a “Pretty Date” from an “Ugly” Database Timestamp

One of the constant issues when working with legacy data is how ugly it is. When you’re calling a stored procedure to pull out legacy data from an Oracle Storage Management System backend, the resulting text string is formatted in a way that… Well, let’s just say its hideous looking, or at least we can say that it’s not human readable. Fortunately I’ve come up with a large library of conversion methods to take this data and format it into a way that will look good in the application front end UI. For example here’s a here’s a sample from my library that can take a MySQL timestamp and format it to look nice on a web page or application front end. To save critical UI space and help differentiate old records from new ones, the display shows a different format for how old the record is. For example records from today will simply say what time they were entered. Records from this week will have the day of the week and records older than that will have the dates. I use techniques like these frequently while handling the data conversion from where it’s stored in a legacy back in to being displayed on the modern front end user interfaces.

//********************************************************************************
function formatDateFromDb($timestamp){
    $time_object = new DateTime($timestamp, new DateTimeZone('UTC'));
    $time_object->setTimezone(new DateTimeZone('America/Los_Angeles'));
    /*echo("<p>records from last year {$time_object->format('m/d/y g:i A')} </p>");
    echo("<p>records from last week {$time_object->format('D F j g:i A')} </p>");
    echo("<p>records from current week (but not from today) {$time_object->format('D g:i A')} </p>");
    echo("<p>records from current day {$time_object->format('g:i A')} </p>");*/
    
    $current_year = date('Y');
    $timestampyear = date('Y', strtotime($timestamp));
    $current_week = date('W');
    $timestampweek = date('W', strtotime($timestamp));
    $current_day = date('N');
    $timestampday = date('N', strtotime($timestamp));
    $current_hour = date('H');
    $timestamphour = date('H', strtotime($timestamp));
    $prettyDate = "";
    
   
    
    if($current_year - $timestampyear > 0) {
        //records from last year |  03/08/21 3:41 PM
        $prettyDate = $time_object->format('m/d/y g:i A');
    } else {
        if($current_week - $timestampweek > 0){
            //records from last week | Mon March 8 3:41 PM
            $prettyDate = $time_object->format('D F j g:i A');
        } else if(($current_week - $timestampweek == 0 && $current_day - $timestampday >0) || ($current_week - $timestampweek == 0 && $current_day - $timestampday == 0 && $timestamphour < 8)){
             //  records from current week (but not from today) |  Mon 3:41 PM
            $prettyDate = $time_object->format('D g:i A');
        } else if($current_week - $timestampweek == 0 && $current_day - $timestampday == 0 && $timestamphour >= 8){
            // records from current day | 3:41 PM
            $prettyDate = $time_object->format('g:i A');
        } else {
            $prettyDate = "time format not found for {$timestamp}";
        }
     
    }
    return $prettyDate;
}
//-----------------------------------------------------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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>

Allow user to print the contents of an element

Here is a cross browser solution to allow the user to press a button and print out the contents of an element. Suppose we have a content area with an id of “mycontentarea”, and a button that says “print”. We can attach a handler to the click event and run this code in the function to print out the contents of “mycontentarea”:

[code]
w=window.open();
reportinfo =  document.getElementById(‘mycontentarea’);
w.document.write(reportinfo.innerHTML);
w.document.close();
w.print();
w.close();[/code]

Using jquery document delegate to create Inline Editable fields.

I have come up with a technique to allow the user to edit content “Inline”.

Lets look at an example. I have a table of data, and the user needs to be able to edit the “Description” Field. Rather than take the user away from this ui view, I wish to enable “Inline Editing” like many powerful applications are offering these days.

The first step is to assign functions to the correct fields and capture the users input events. The user would click on the field to select it, so lets set up a doc delegate event to capture a click on the description field. We need to use doc delegate because the data is dynamic and so isn’t  in the DOM when the events handlers are normally assigned. Read my post about JQuery Document Delegate to catch up on this technique. I am going to delegate the capture of a click event on any table row <tr> with a class of “editBannerDescription”

$("#bannerslist").on("click", ".editBannerDescription", function(e){
var thedata=$(this).html();
alert(thedata);
 });

Yeah boyeee we have captured a click event for any element in the bannerslist table, and have access to the content that is in the table cell.

The next step is to alter the ui view so the user can edit the contents of the description table cell. I use a JQuery / JavaScript function to accomplish this:

enableEditDescription(object, bannernid){
     console.log("Message from enable Edit Description function: lets 
enable to edit the description of slide id:"+bannernid+" from
description of : "+$("#"+object).html()); }

I will continue to modify the enableEditDescription function to alter the ui view when the user clicks. I will grab the content from the cell, and replace the content with a text area whose value is the text that was in the cell.

The final code looks like this:

$("#bannerslist").on("click", ".editBannerDescription" , function(e){
var thedata=$(this).html();
var object=$(this).attr("id");
var getbannernid = object.match(/d+$/);
if(getbannernid){
    bannernid=parseInt(getbannernid[0], 10);
    console.log("Message from banner admin inc, here in doc delegate for 
     editBannerDescription with content of :"+thedata+" in cell 
     object id: "+object+" for banner nid: "+bannernid);
     enableEditDescription(object, bannernid);}
else{ alert('error getting id');}
 }); // end #bannerslist doc delegate actions

Now, when the user clicks a table cell with editable content, the cell changes into an inline editor.

The user needs to be able to “escape out” of the edit mode, discarding any changes that were made in the field.

Lets start with capturing the escape key press event when the user is in an editing field. We’ll use the good ol doc  delegate to capture this as so…

$("body").on("keydown", "textarea, input", function(e){
if(e.keyCode==27){
console.log("We have key press of escape key, on event target " + e.target.id + 
" lets exit edit mode without saving changes. Lets decide what place they're editing...");}
}); // end on keydown event handler

Now I can put back the original content of the cell and the user will have “escaped out” of edit mode.

The next step is going to be really fun. We are going to capture the press of the “Edit” button and save the new content into our cms.

Banner and Slider Administration Control Panel

Due to my years of experience designing custom content management systems, I have been tasked with creating a plug in to the CMS at Skagit Valley College that will allow staff to administer their respective home page image sliders via a web based admin control panel. Features include list of slides, ability to upload new slides, delete slides, arrange the sequence of the slides, and control the display of the slides. The slides are live at www.skagit.edu

The users will also have the ability to administer home page banners. Features include list of banners, ability to upload new banners, assign banner to homepage, delete banners.

The purpose of this project is to reduce webmaster workload by allowing staff to admin their respective home page sliders and banners. I will be taking on the role of Senior Developer for this project, and will perform the duties of all roles including : Information Architect,  User Experience Designer, User Interface Designer, Web Application Developer, SQL Database Administration.

I begin with the I/A documentation, the key to every successful project. After creating the Creative Brief, and clearly stating the objectives, purpose, target audience and timeline for the project, I then create the Flowcharts, Wireframes and User Stories.

With all the proper documentation in place, I have a clear project scope and will begin the design, develop and deployment by using my project management cloud.

From the screenshot you can see the hand written notes from meeting with the client, and the task lists that I created for the project. Each task list is filled with the tasks that I need to get done, and notes about each topic. It really helps keep me on track and manage the progress for the project.

I am going to develop an object oriented api for this project, with the application programming interface expressed in javascript and vbscript.

The api to handle the upload of slides will be interesting, since there isn’t a build in method for capturing the form upload data. We are using a third party library to handle the upload, and I haven’t even seen it yet.

I have  the list of slides layout in a table, since its the perfect use of tablular data. The list is generated dynamically and injected into the dom via a call to the api. This has the effect of negating my events that I place on the image to have a mouseover thumbnail preview. I  need to use the doc delegate that I deved into in a previous article.

Im going to delegate the event to my slides layout table, and then apply it to any td element with the class of “previewzone”. So lets slap it on there and see if it works…

$("#slideslist").on("mouseover mouseout", ".previewzone", function(e){
alert(e.type);
});
There is now a mouseover and mouseout event on any td with the class of “previewzone”

Sweet! Now I can set up the event handler so that it displays a preview of the image on mouseover, and hides it on mouseout.

Beyond Responsive Web Design – Creating Content for Different Devices

Screen shot of bonus content on large screen.

There are some things that should not be handled with responsive design. For example I’m creating bonus content for devices with very large screens. Using responsive design, the common technique is to load this bonus content into the dom but not show it for certain size screens. However this still takes its toll on the load time and would impact performance of the device since it would still have the content in its memory.

For the bonus content,  I am going to display  a large graphic image only on devices that meet a certain height and width requirement. This can be easily accomplished without a third party plug in or framework using standard JavaScript.

Screenshot of content on tablet

Content on Samsung Galaxy Mobile Phone

The JavaScript behind this is surprisingly simple and cross browser compatible. I have tested successfully on  PC’s with new ie and firefox, surface pro, android 2.2 up, ipad, iphone, blackberry playbook, older  imac with safari.

var screenheight=screen.height;
var screenwidth=screen.width;
if(screenwidth>=1280 && screenheight >= 1000){
// execute my sweet js script to display bonus content.
}

	

3DW Tools CSS Styles Library

After three years of  designing proof of concept and rapid prototypes I have decided to compile all of my custom css styles that were spread between multiple projects into one master library of css style design patterns. My 3DW Tools CSS Styles Library is managed via my cms, and when included into a project,  grants  access to some really great styles that can be  called using an easy to remember  style language.

In order to produce HTML 5 designs without Flash or Photo Shop, my 3DW Tools CSS Styles Library is the perfect addition to a blank HTML 5 page or a  JQuery build, giving me the ability to design some really great mockups, proof of concept, rapid prototype, and user experience designs.

Here is the link to the visual reference.

Here is a css box shadow generator https://developer.mozilla.org/en-US/docs/Web/CSS/Tools/Box-shadow_generator

Here is a css button generator https://developer.cdn.mozilla.net/media/uploads/demos/m/o/mok20123/8aff6ca4f35726d64880dd6fc77739ba/css3-button-generato_1325474481_demo_package/index.html

Here is the css border radius generator https://developer.mozilla.org/en-US/docs/Web/CSS/Tools/Border-radius_generator

Upgrading Legacy Web Forms with my Content Display Wizard plugin.

Here is an example of how  my plugin makes it easy for the user to navigate and successfully submit the data. And for us weary developers, the best part is the AUTOMATION. My plugin will provide content navigation, client side validation and handle the submission of the data via ajax to my api.

At Skagit Valley College, I plug my wizard into a legacy form and it’s transformed into a slick responsive paperless web application for data collection. There was an old  Hall of Fame nomination form that had been moved into the cms of our new responsive version of the SVC site…

 

After simply including my Content Display Wizard Plugin, its now a slick paperless web application for data collection. Go check it out, go through the form to view the summary and I’m sure you will love the user experience.

Technical Instructions: How to use my Form Content Display Wizard

So, to use my plugin to any form or content,

Separate content chunks:
Wrap the content in div containers with unique ids begining with “step_xxx”  where xxx should be a detailed way to identify the content such as “step_intro” and  “step_personal_info”

If the path is non branching, the plugin will create buttons for “back” and “next” named “stepDownButton” and “stepUpButton” . It will look for the second to last step and put a submit, and the last step is the confirmation. To create a custom path, branch, or skip a step, just create a button named “stepDownButton” and “stepUpButton” . Give the button an onclick of stepUp(‘stepname’) or stepDown(‘stepname’) to make the button skip to a certain step.

Table of contents
The plugin will use the first element inside the step as description for the table of contents. You can use the attribute stepdesc on the step_xxx element as a custom title for the toc. The toc will be appended to the first step unless you make a custom toc using a container with id of “tableofcontents”. This can be disabled by …..

Form elements and Validation
To provide “empty field” validation to form elements in a step, just add the class “required” to the element. Place the class “email” to validate an email address on one input element. You can add class “match” to two elements in a step and they will have to match each other. Give the elements a unique ID and a good name attribute, and the plugin will create placeholders for the text input elements from the name.
NOTE: it seems like the name attribute is the perfect place to put a readable descriptive title that could be used in creating the labels, and for  summary display. NOTE: it seems like moving to the new html5 text inputs for validation such as email tel, then if input type = email, wouldn’t need a class selector.Just a thought for moving forward with

Data summary
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.

Submit and final confirm
In the final step, you should place your  final confirmation text there. This will tell the user the results of their data submit, success or error.  When user is ready, the script will submit the form data, and move to the final confirmation.

 

 

Themeing the elements

To theme the elements, just add classes to items in the ui view using jquery :

This will add a Panel effect to the divs—
$(‘div[id^=”step_”]’).addClass(“softblackgradient blackbottomrightboxshadow mediumallaroundpadding”);

The buttons wont work to style this way cause they aren’t in dom yet. To theme the buttons, you need to  set these global variables before you call to include the plugin.:

I feel that the “Begin”  button should look very different from the Next and Back buttons:
beginbuttonclass = “button roundedcorners success mediumallaroundpadding”

Here is to style the step up and step down buttons:
stepupbuttonclass=”button oval success smallallaroundpadding”
stepdownbuttonclass=”button oval alert smallallaroundpadding”

The “Submit” button needs to also look very different from the step up and down buttons.
style it like this: submitbuttonclass=”button roundedcorners mediumallaroundpadding success”

 

If you have put in custom buttons to go to non linear paths, make sure to still give the the names of stepUpButton and stepDownButton. Then you can select and style them as well using the jquery selector.

Theres tableofcontents to layout the toc, and  highlightstep to control the highlighted step. This is proving very difficult to get out of the plugin, since the toc relies on the scripts. There are classes yellowhighlight, and  mediumtext that will need to be declared in the ui view that is using the plugin.