If you attended Southwest Fox 2016, a free copy of DBI’s Calendar Control was part of your goodies bag. I had a user request come in recently that the calendar control was a perfect fit for so had a chance to work with it.
My application has an “Appointment Book” form that shows all of the appointments, events, etc that the client has to deal with. It’s not terribly sophisticated, just listing all the items in date/time order, but it got the job done:
The problem the client ran into was that the “Intro” items frequently move around when people call to reschedule. They needed a quicker and easier way to change them as well as seeing what is going on over multiple days. This is exactly what the DBI Calendar Control does and I ended up with the form below. Again, not terribly sophisticated, not using a lot of the color/graphic capabilities of the control, but it gets the job done:
The advantage here for the user is that they can see the days graphically now, can see multiple days at once, and they can drag & drop the appointments to change the day/time of the appointment.
I was impressed with how easily the control was to work with and how smoothly it works with VFP. In 4 hours or so I went through DBI’s samples (in VFP!), created my own form, and did all the code for adding the appointments, allowing for drag & drop, and double-clicking to open an appointment for editing.
Here’s the 1 line of code for adding an appointment to the calendar. The calendar control works on minutes past midnight rather than a time format so the first parameter is converting my VFP time into minutes. The second parameter is end time which I don’t have for my appointments so I default to start time + 30 minutes. The third parameter is the date while the fourth is whatever text you want to show up.
lIndex = thisform.ctxCalendar1.addAppointment(HOUR(ApDate) * 60 + MINUTE(apDate),; (HOUR(apDate) + 1) * 60 + MINUTE(apDate) - 30,; TTOD(apDate),; lText)
Here’s the code to update my data when an appointment is dragged & dropped to a new date/time. This goes into the control’s AfterAppointmentChange event. The control keeps an index number for every added appointment so I just have to take the nIndex that is passed in, find that entry in my data, and then update my data with all of the other passed in parameters for the new date/time:
SELECT CurAppt LOCATE FOR ctIndex = nIndex IF !apx("Seek", CurAppt.apID) zmsg("o", "Error! Could not locate appointment to update date/time.", "Error!", "!") else * Update the time of the appointment SELECT apAll LOCAL lDateTime lDateTime = dtDate + (nStartTime * 60) replace apDate WITH lDateTime endif
This code adds or removes day columns when the user changes the form width:
LOCAL lCol lCol = INT((thisform.ctxCalendar1.Width - 60) / 150) thisform.ctxCalendar1.DayColumns = lCol
Really straight-forward code and the control works really smoothly. In the future I might get fancy and add some color-coding for different appointment types or add some graphics.
The ease of use from DBI has me wondering what other controls I might want to incorporate as well.