There isn’t a lot to like about the WEBDEV Date Entry control. In fact there isn’t a lot to like about the WINDEV one either, but that is a different conversation. There are a few issues with it. We are going to solve them by using the jQuery UI DatePicker Widget
First unless the user types in the date in the exact format you specify (including 2 or 4 digit year), it won’t accept it as a valid date. It doesn’t do any intelligent parsing.
To avoid that issue, we disabled direct edit only allowed the user to edit the date via the calendar button. Which quickly leads to the 2nd issue, the calendar popup only has arrows for changing months, not years, which is fine if you are entering recent dates, but not very friendly if you are entering date of birth, etc. where the user would have to hit the arrow button possibly 720 or more times! (60 years * 12 months = 720).
A third issue, is only relevant to folks that develop for multiple language markets, If you show the date in MM/DD/YYYY or DD/MM/YYYY format depending on language it can become very confusing to the users when the date is 01/03/2020. Is that January 3rd or March 1st? To solve that issue in one project we display the dates as DD-mmm-YYYY. So are dates are 1-Mar-2020. No confusion there, but just imagine what they does for the first issue listed, now its nearly impossible for a user to enter a date correctly.
jQuery UI to the rescue, with the Date Picker widget. But first we need to understand a few things, WebDev already uses jQuery and jQuery UI, however when they built their jQuery UI library they choose to not include the date picker widget. So we need to build our own JQuery UI library and we have to include it in our page a special way to avoid conflicts between the two.
Normally we would go into the Project Description on the Advanced WebDev tab and include additional JavaScript Files, but I have had issues with that conflicting with the Libraries already loaded by WebDev, so instead we have to do a bit of manual work (I know we are so spoiled with WebDev we don’t like that word!).
First you need the library, over on https://jqueryui.com/ you can build and download a custom library with just the Date Picker Widget in it, or you can just download the example app I will provide in a link at the end of the article and use the library from there, you will find a jquery-ui-1.12.1.custom.zip include in the project folder as well as the indivuals files needed in the _WEB folder.
Note you can also select a theme for the download, I used the Base theme for this project. Which is fairly simple and plain, as you can see from this image there are quite a few different themes to choose from, or you can even “Roll Your Own” using the ThemeRoller located at https://jqueryui.com/themeroller/

I renamed the jquery-ui.min.js to jquery-ui.datepicker.min.js, to make it easier to identify and copied it to the _WEB folder.

Since we did this manually, it did not get added to the SCM, and you definitely want it in the SCM especially if you are working with multiple developers! So back over to the IDE, and on the SCM tab of the ribbon bar we click Manage, then navigate to the _WEB folder, right click and choose add files, and select the library.

Now it should be in your SCM

Next from the downloaded zip file, we need to copy the entire images directory into our _WEB folder. These are images used by the CSS file will be be importing shortly

And once again since we are adding these files manually we need to add them to the SCM manually, however this time we chose import a local directory to get all of them at once.

The end result should look similar to this

Finally we need to add a CSS file (jquery-ui.min.css) from the zip, so that the date picker widget looks nice. We need to copy it into the _WEB folder.
We don’t need to do any extra steps to get it in the SCM as we are going to add it via the interface, so back to the IDE, go into the project description and on the Skin tab, click on the “Free CSS style sheets” button and select the file we just added, if you are using the SCM when you save it, it will add the file to the SCM automagically.

While we are still on the Project Description there is one more thing we need to do. On the Advanced WEBDEV tab. Note: I am using the WINDEV with WEBDEV integrated IDE, if you are using just WEBDEV I believe it will just say Advanced. Click on the little … button next to HTML standard and turn off “Compress ALIAS and JavaSCript procedure names” and “Compress JavaScript code”. With those turned on the JavaScript ID’s for our controls are like A1,A2, etc. which might save a bit of space, but sure ain’t easy when writing code, especially since they can change as you add, delete controls!

We are almost done with the project setup stuff. We need to pull the library into our page, since we can’t do it via the project description area. You can do this page by page on the pages you need it, or if you are an Uncle Pete disciple I know you are using page templates and can do it on your page template and be done with it.
Of course the wxDemo project has uses a page template, so that is where I am going to make the change, in the Init Area you need to add a line of code to include the date picker library like this

MyPage..HTMLEndPage += [
<script src="/[%FolderWeb()%]/jquery-ui.datepicker.min.js"></script>
]
That is simply adding the JavaScript code to the end of the page to include our library. If we had added the library via the Project Description Additional JavaScript files function, it would include it at the top of the page, and the order that libraries are loaded effects things and can lead to conflicts, so we need our library loaded last.
One more step to fully setup our project, we need a global browser procedure to setup all the defaults of our jQuery UI date picker.

PROCEDURE setDatePickerDefaults()
dpobj is dynamic object = new "Object"
dpobj.changeMonth = True
dpobj.changeYear = True
dpobj.autoSize = True
dpobj.dateFormat = "m/d/yy"
dpobj.yearRange = "1900:" + Left(Today(),4)
dpobj.monthNamesShort = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]
dpobj.dayNamesMin = [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ]
dpobj.altFormat = "yymmdd"
RESULT dpobj
Line 11 is really important as that is what gets our date into our hidden control with the right format for WEBDEV, as you will see shortly.
Now our project is all setup, all we need to do is add code for our actual date edit controls.
First lets look at a normal WEBDEV date edit control.
When we press the calendar button we see one of the issues I mentioned

And if you play with the control a bit you will notice it’s all around a PITA to enter a correct date in it, and at times you can even get trapped in it trying to get an entry made.
Now lets look a the jQuery UI version

Along with being more attractive with the default CSS,you can adjust the CSS or theme to make it match your site colors, fonts, etc. But it also has drop downs for month and year making it much easier to navigate to a specific date quickly.
BTW, there are a ton of additional properties you can set in the setDatePickerDefaults procedure we created above: Include arrows as well as the drop downs, show multiple months, customize the formatting, just to name a few. We will take a look at a couple shortly. Check out all the options at https://api.jqueryui.com/datepicker/
So lets see how we setup entry field. First we need to edit controls, the first is hidden and is linked to the database if needed, and holds the date value in standard WEBDEV format. The field type is set to Text (NOT DATE), we make it invisible, and allow overide (so we can position it off the page), and linked to the database field if needed.


And as mentioned it would be linked to your database field if you were doing a normal project. In the example project we aren’t linking as this isn’t a complete form, just an example of some edit controls.
And as you can see I place the control off the page so it isn’t in the way of my design, another technique Uncle Pete’s Disciples will recognize 🙂

Now for the edit control that will be visible, I name it the same as the hidden control with a suffix of Display. No magic to this name, use whatever makes sense to you as long as you can tell the 2 fields apart. Again the type is Text (NOT DATE). The field is visible, but Read-only. As soon as the user enters the field the calendar pops up for entry, so having the field editable would just confuse things.


And this control would not be linked to anything as we will be controlling the value in it via code.
Now in the Load browser event of the page we need to setup our control to use the Jquery UI Date Picker, it takes 5 lines of code!

dpobj is dynamic object = new "Object"
dpobj = setDatePickerDefaults()
dpobj.altField = "#EDTDATEPICKER1"
edtDatePicker1Display = DateToString(edtDatePicker1,"MM/DD/YYYY")
jQuery("#EDTDATEPICKER1DISPLAY")."datepicker"(dpobj)
The first line of code creates a empty JavaScript Object. The second line of code populates that object using the global browser procedure we created earlier. Note: If you need one date control to have different options that others, once you have populated to the Object via the global procedure you can add additional settings, we will look at that shortly.
Line 3 links the date picker to the hidden control, that would normally be linked to our database, and as mentioned earlier, the altFormat option in the global procedure gets it into the correct format for WEBDEV. Also notice that control name is prefixed with a #, which is a jQuery way of saying we want to match the HTML ID, and the name of the edit control is all in caps. Remember this is JavaScript which is case sensitive, WEBDEV generates the IDs as all upper case, so we need to do the same here. If you code isn’t working one of two things is the likely culprit, either you made a typo on the control name, or you forgot to turn off the JavaScript compression on the project. Neither will generate any errors, but your control won’t behave as expected.
Line 4 just populates the display control with the formatted version of the date.
And Line 5 activates the enables the data picker widget for the display control. Again notice the case on the edit control name. You might be wondering why datepicker is in quotes. Well the reason is again related to JavaScript case sensitivity. the widget name is datepicker (all lower case), when you type datapicker into the IDE, intellisense want to change it to DatePicker. Technically intellisense only displays it differently and in the generated HTML it is still lower case if you type it that way, but I have had trouble with copy and paste, etc. getting the wrong case and generating JavaScript errors, so it is just easier and safer to wrap it with quotes.
That is all there is to it, you know have an edit control using the Jquery UI date picker widget.
Bonus Material One: Multiple date entries, and additional options
As mentioned above, there are a number of different options that can be set for the widget. If you want all of your date controls to use an option add the code to the global browser procedure setDatePickerDefaults. But what if you want an option to only apply to a specific date control, well lets add a second date control and find out.
I setup my two edit fields the same as above, they are named edtDatePicker2 and edtDatePicker2Display. However let’s say that this input field is for birth dates. We probably don’t need anything older than 1900 and if you are working with people that have birth dates in the future, you should probably be doing something other than reading my blog! So lets limit the year to 1900 through the current year. And lets say we also want Monday to be the first day of the week, instead of Sunday. Lets look at our code in the Load Event for this second edit control

dpobj2 is dynamic object = new "Object"
dpobj2 = setDatePickerDefaults()
dpobj2.yearRange = "1900:" + Left(Today(),4)
dpobj2.firstDay = 1
dpobj2.altField = "#EDTDATEPICKER2"
edtDatePicker2Display = DateToString(edtDatePicker2,"MM/DD/YYYY")
jQuery("#EDTDATEPICKER2DISPLAY")."datepicker"(dpobj2)
Line 7 is the same as Line 1 with the exception of we need a new JavaScript object so the 2 don’t interfere with each other, so we name it dpobj2, likewise Line 8 is the same other than the object name
Line 9 is new and limits the year between 1900 and the current year.
Line 10 changes the first day of the month to Monday
Line 11,12 and 13 are the same with the exception of the object and edit control names.
Let’s take a look at the results. Notice Monday starts the week, and the drop down for year ends at 2020.

Bonus Material Two: Possibly advancements
As I mentioned at the beginning of this article the WINDEV date entry isn’t anything to write home about either, and one of the few things those of us that migrated from the Clarion world do miss is Clarions date entry was top notch, you could type a date in just about any format and the parser would intelligently figure it out and reformat the date correct.
WINDEV is much more rigid when it comes to parsing the date entered. In one of our projects, the windows version of the same European project that is using the month name stuff from above, we wrote our own custom parser code that can parse the input from the user similar to the way Clarion did and return a correctly formatted date.
It would be fantastic and I believe achievable to combine that parser, with the Jquery UI data picker to create a truly advanced date entry control for our WEBDEV projects. It is one of those things that has been on my todo list for ever, but paying projects always get in the way. Maybe one day one of our paying clients will ask for the feature… hint … hint 🙂
Download links
As promised you can grab the example project from my dropbox or you can download it from our public SCM. Info on our public SCM can be found here
Many thanks for this Pete…
I ve been longing to change the WB date picker, this article just made this time the right time!
I m using WB24.. I assume the process wont be too different form WB25.
Thanks again!
LikeLike
Everything I did will work in v24, in fact I have been using the JQuery UI date picker for a long time.
LikeLike