KiXforms Forum Index KiXforms
The Forum for the KiXforms Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Quick Links 
Site News
Downloads
Documentation
Donations
Script Archive
Tracking Systems

udfDatePicker() - GUI date selection

 
Post new topic   Reply to topic    KiXforms Forum Index -> Script Archive
View previous topic :: View next topic  
Author Message
rhowarth
KiXforms Dabbler
KiXforms Dabbler


Joined: 27 Apr 2005
Posts: 5
Location: Leatherhead, Surrey, United Kingdom

PostPosted: Fri Nov 27, 2009 2:56 pm    Post subject: udfDatePicker() - GUI date selection Reply with quote

It's a bit quiet in here.

Inspired by Bruno's calendar post, I've created a stand-alone UDF to use as a date selection dialogue for a current project.

The UDF header and examples should provide enough documentation to see how to use it.
Code:
; Function udfDatePicker() ; {{{
;
; Inspired by Bruno's post here: http://www.kixforms.org/forum/viewtopic.php?t=672
;
; udfDatePicker() - Allow user to select a date from a calendar.
;
; Parameters:   All parameters are optional.
;            sTitle   - Tool window title
;            sStartday      - The day that first appears in the tool
;            iTodayButton   - Does the "Today" button appear on the tool (true / false)
;                          Default is false
;            $asSpecialDays   - Array or space delimited list of special days which are
;                          highlighted in an alternate colour.  Default is today.
;            $sButtonStyle   - How the individual dat buttons appear.  Default is flat "popup"
;                          style, use "2" for a raised button effect.
;            $sLowDay      - The earliest day that can be selected.
;            $sHighDay      - The latest day that can be selected.
;
; Examples
; --------
; Display this month, highlight today
;   $v=udfDatePicker()
;
; Only allow user to select my birthday :)
;    $v=udfDatePicker("Special day","1966/12/21",,"1966/12/21",2,"1966/12/21","1966/12/21")
;
; Highlight the 10th and 20th this month, don't allow user to select days after today
;   $v=udfDatePicker("","",1,""+@YEAR+"/"+@MONTHNO+"/10 "+@YEAR+"/"+@MONTHNO+"/20",,"",@DATE)
;
;
;
;   $sMyBirthday=
; Amendement History
; ------------------
;   20091127 14:30   Richard Howarth <rhowarth@harsco.com>
;               Function initially created.
;
Function udfDatePicker(
      Optional $sTitle,
      Optional $sStartDay,
      Optional $iTodayButton,
      Optional $asSpecialDays,
      Optional $sButtonStyle,
      Optional $sLowDay,
      Optional $sHighDay
   )
   Dim $frm,$lblMonth,$btnPrev,$btnNext,$btnToday
   Dim $sDayHeader
   Dim $s,$i
   Dim $btnList[37]
   Dim $iDaynoX,$iDaynoHeight,$iDaynoWidth
   Dim $sAction
   Dim $sToolColour,$sEvenDayColour,$sOddDayColour,$sTodayColour
   Dim $iUpdate
   Dim $iMonth,$iYear
   Dim $iLastDay,$iFirstDay
   Dim $aiDaysInMonth,$asMonthName
   Dim $sThisDay

   $sToolColour=LightGray
   $sEvenDayColour=$sToolColour
   $sOddDayColour=Silver
   $sTodayColour=PaleGoldenrod

   $aiDaysInMonth=x,31,28,31,30,31,30,31,31,30,31,30,31
   $sDayHeader="10:Mo 37:Tu 64:We 91:Th 118:Fr 140:Sa 166:Su"
   $asMonthName="January","February","March","April",
      "May","June","July","August",
      "September","October","November","December"

   $iDaynoX=60   ; Offset for day
   $iDaynoHeight=20 ; Height of day button
   $iDaynoWidth=25 ; Width of day button


   If $sLowDay="" $sLowDay="0000/00/00" EndIf
   If $sHighDay="" $sHighDay="9999/99/99" EndIf

   If VarType($asSpecialDays) & 8192 $asSpecialDays=Join($asSpecialDays) EndIf
   If $asSpecialDays="" $asSpecialDays=@DATE EndIf
   $asSpecialDays=Split($asSpecialDays)

   If $sStartDay=""
      $iMonth=CInt(@MONTHNO)
      $iYear=CInt(@YEAR)
   Else
      $iMonth=CInt(Split($sStartDay,"/")[1])
      $iYear=CInt(Split($sStartDay,"/")[0])
   EndIf
   $iUpdate=1

   If Not IsDeclared($_funDatePicker_KiXform)
      Global $_funDatePicker_KiXform
   EndIf
   If VarType($_funDatePicker_KiXform)<>9
      ; $_funDatePicker_KiXform=initKixForms() ; Bespoke initialisation not used in public version
      $_funDatePicker_KiXform=CreateObject("KiXtart.System")
      If @ERROR Exit @ERROR EndIf
   EndIf

   $frm=$_funDatePicker_KiXform.Form()
   If @ERROR Exit @ERROR EndIf

   $frm.icon=$_funDatePicker_KiXform.BuiltinIcons(72)
   $frm.Text=IIf($sTitle="","Select a date",$sTitle)
   $frm.width=200
   $frm.height=220

   $lblMonth = $frm.Controls.Label()
   $lblMonth.Bounds = 30, 10, $frm.width-70, 15
   $lblMonth.textalign=32
   $lblMonth.BackColor=$sToolColour
   $lblMonth.BorderStyle=FixedSingle

   $btnPrev = $frm.Controls.ToolButton()
   $btnPrev.Icon=27
   $btnPrev.Left=10
   $btnPrev.height=15
   $btnPrev.width=20
   $btnPrev.top=10
   $btnPrev.onclick="Previous"
   $btnPrev.BackColor=$sToolColour

   If $iTodayButton
      $frm.height=240
      $btnToday = $frm.Controls.ToolButton()
      $btnToday.text="Today"
      $btnToday.Left=($frm.width/2)-25
      $btnToday.height=20
      $btnToday.width=40
      $btnToday.top=$frm.height-55
      $btnToday.onclick="Today"
      $btnToday.BackColor=$sToolColour
   EndIf

   $btnNext = $frm.Controls.ToolButton()
   $btnNext.Icon=28
   $btnNext.Left=$frm.width-40
   $btnNext.height=15
   $btnNext.width=20
   $btnNext.top=10
   $btnNext.onclick="Next"
   $btnNext.BackColor=$sToolColour

   ; Create short date header
   For Each $s in Split($sDayHeader) $frm.PrintXY(Split($s,":")[0],40,Split($s,":")[1]) Next

   For $i = 0 to 36
      $btnList[$i] = $frm.ToolButton()
      $btnList[$i].Location = 10+$iDaynoWidth*($i mod 7),$iDaynoX+$iDaynoHeight*($i/7)
      $btnList[$i].width = $iDaynowidth
      $btnList[$i].height = $iDaynoHeight
      $btnList[$i].BorderStyle=1
      $btnList[$i].FlatStyle=$sButtonStyle
   Next
   $frm.Show

   While $frm.Visible
      If $iUpdate
         $lblMonth.Text=$asMonthName[$iMonth-1]+" "+$iYear

         ; Fix leap day for this year
         $aiDaysInMonth[2]=28+((($iYear mod 4 = 0) AND ($iYear mod 100 > 0)) OR ($iYear mod 400 = 0))

         ; Calculate the offset for the first day of the month, algorithm taken from:
         ;   http://www.faqs.org/faqs/calendars/faq/part1/index.html#ixzz0Y3svssjS
         Dim $a,$y,$m
         $a = (14 - $iMonth) / 12
         $y = $iYear - $a
         $m = $iMonth + 12*$a - 2
         ; The "1" here is hardcoded for the first day of the month
         $iFirstDay = (1 + $y + $y/4 - $y/100 + $y/400 + (31*$m)/12) mod 7

         ; Algorithm gives Sunday=0, fix date  to ease calculation (Sunday=7)
         $iFirstDay=$iFirstDay+7*($iFirstDay=0)
         $btnPrev.enabled=TRUE
         $btnNext.enabled=TRUE
         For $i=0 to 36
            If ($i+1)>=$iFirstDay AND ($i-$iFirstDay+1)<$aiDaysInMonth[$iMonth]
               $btnList[$i].Text = ($i+2-$iFirstDay)
               $sThisDay=CStr($iYear)+"/"+Right("0"+$iMonth,2)+"/"+Right("0"+$btnList[$i].Text,2)
               $btnList[$i].OnClick = 'btnDayNo '+$sThisDay
               $btnList[$i].visible=TRUE
               $btnList[$i].Backcolor=IIf(($i mod 7) mod 2,$sOddDayColour,$sEvenDayColour)
               If 1+AScan($asSpecialDays,$sThisDay) AND $sTodayColour $btnList[$i].Backcolor=$sTodayColour EndIf
               If $sThisDay<$sLowDay
                  $btnList[$i].enabled=FALSE
                  $btnPrev.enabled=FALSE
               EndIf
               If $sThisDay>$sHighDay
                  $btnList[$i].enabled=FALSE
                  $btnNext.enabled=FALSE
               EndIf
            Else
               $btnList[$i].visible=FALSE
            EndIf
         Next

         $iUpdate=0
      EndIf
      $sAction=$frm.DoEvents
      Select
      Case $sAction=""
         ; No action
      Case $sAction="Previous"
         $iMonth=$iMonth-1
         If $iMonth<1 $iMonth=12 $iYear=$iYear-1 EndIf
         $iUpdate=1
      Case $sAction="Next"
         $iMonth=$iMonth+1
         If $iMonth>12 $iMonth=1 $iYear=$iYear+1 EndIf
         $iUpdate=1
      Case $sAction="Today"
         $iMonth=@MONTHNO
         $iYear=@YEAR
         $iUpdate=1
      Case Split($sAction)[0]="btnDayNo"
         $udfDatePicker=Split($sAction)[1]
         $frm.hide
      Case Default
         "Unexpected event: "+$sAction+@CRLF
      EndSelect
   Loop

   $frm=0
   Exit 0
EndFunction ; }}}


Edit: Removed debug code.

_________________
Richard H


Last edited by rhowarth on Mon Nov 30, 2009 2:37 pm; edited 1 time in total
Back to top
View user's profile Send private message
Mart
KiXforms Regular
KiXforms Regular


Joined: 03 Oct 2005
Posts: 57
Location: Rotterdam - Netherlands

PostPosted: Sun Nov 29, 2009 10:27 pm    Post subject: Reply with quote

A UDF is not supposed to create screen output unless it is used in some kind of way from a script. This one shows the current date preceded by xx.
This line seem to be the culprit.

Code:

"xx " + Join($asSpecialDays) + @crlf


Commenting this line kills the automatic screen output and does not seem to interfere with the UDF’s functionality. Is this line needed for the UDF to work 100% correct?

Nevertheless his is a really nice UDF Cool

_________________
Mart

- He's chained forever to a world that's departed.....It's not enough, it's not enough - Sorrow by Pink Floyd.
Back to top
View user's profile Send private message
Mart
KiXforms Regular
KiXforms Regular


Joined: 03 Oct 2005
Posts: 57
Location: Rotterdam - Netherlands

PostPosted: Mon Nov 30, 2009 1:21 pm    Post subject: Reply with quote

Richard is unable to edit his post because for some reason the account he used in locked. Shawn, Rod, can one of you reset his account?

Reply from Richard:
Quote:

No, the offending line is not needed. It's just a bit of debug code I missed when I tidied up ready for posting.
The offending line can be removed.

_________________
Mart

- He's chained forever to a world that's departed.....It's not enough, it's not enough - Sorrow by Pink Floyd.
Back to top
View user's profile Send private message
Rod
KiXforms Webmaster
KiXforms Webmaster


Joined: 22 Feb 2003
Posts: 202
Location: United Kingdom

PostPosted: Mon Nov 30, 2009 2:24 pm    Post subject: Reply with quote

Richard's account is now unlocked. This normally happens when an incorrect password is entered too many times in succession.

Rod.

_________________
Back to top
View user's profile Send private message Send e-mail Visit poster's website
rhowarth
KiXforms Dabbler
KiXforms Dabbler


Joined: 27 Apr 2005
Posts: 5
Location: Leatherhead, Surrey, United Kingdom

PostPosted: Mon Nov 30, 2009 2:39 pm    Post subject: Reply with quote

Actually it was auto-locked becuase I changed the mail address in my profile which then needs amin approval.

Anyhoo, thanks for re-enabling.

Debug line removed from code.

_________________
Richard H
Back to top
View user's profile Send private message
enahsyemotp
KiXforms Regular
KiXforms Regular


Joined: 22 Sep 2010
Posts: 40
Location: Tulsa, OK

PostPosted: Sat Oct 23, 2010 7:18 pm    Post subject: Reply with quote

Hey Richard...Thanks a million for this awesome little nugget. I made some simple modifications that improve upon your work (in my opinion). But here is my updated version for what it's worth to any future visitors...

Code:

udfDatePicker("",,1,,1,,@Date)

Function udfDatePicker(
      Optional $sTitle,
      Optional $sStartDay,
      Optional $iTodayButton,
      Optional $asSpecialDays,
      Optional $sButtonStyle,
      Optional $sLowDay,
      Optional $sHighDay
   )
   Dim $frm,$lblMonth,$btnPrev,$btnPrevYr,$btnNext,$btnNextYr,$btnToday
   Dim $sDayHeader
   Dim $s,$i
   Dim $btnList[37]
   Dim $iDaynoX,$iDaynoHeight,$iDaynoWidth
   Dim $sAction
   Dim $sToolColour,$sEvenDayColour,$sOddDayColour,$sTodayColour
   Dim $iUpdate
   Dim $iMonth,$iYear
   Dim $iLastDay,$iFirstDay
   Dim $aiDaysInMonth,$asMonthName
   Dim $sThisDay
   $sToolColour=LightGray
   $sEvenDayColour=$sToolColour
   $sOddDayColour=Silver
   $sTodayColour=PaleGoldenrod
   $aiDaysInMonth=x,31,28,31,30,31,30,31,31,30,31,30,31
   $sDayHeader="10:Mo 37:Tu 64:We 91:Th 118:Fr 140:Sa 166:Su"
   $asMonthName="January","February","March","April",
      "May","June","July","August",
      "September","October","November","December"
   $iDaynoX=50   ; Offset for day
   $iDaynoHeight=20 ; Height of day button
   $iDaynoWidth=25 ; Width of day button
   If $sLowDay="" $sLowDay="0000/00/00" EndIf
   If $sHighDay="" $sHighDay="9999/99/99" EndIf
   If VarType($asSpecialDays) & 8192 $asSpecialDays=Join($asSpecialDays) EndIf
   If $asSpecialDays="" $asSpecialDays=@DATE EndIf
   $asSpecialDays=Split($asSpecialDays)
   If $sStartDay=""
      $iMonth=CInt(@MONTHNO)
      $iYear=CInt(@YEAR)
   Else
      $iMonth=CInt(Split($sStartDay,"/")[1])
      $iYear=CInt(Split($sStartDay,"/")[0])
   EndIf
   $iUpdate=1
   If Not IsDeclared($_funDatePicker_KiXform)
      Global $_funDatePicker_KiXform
   EndIf
   If VarType($_funDatePicker_KiXform)<>9
      $_funDatePicker_KiXform=CreateObject("KiXtart.System")
      If @ERROR Exit @ERROR EndIf
   EndIf
   $frm=$_funDatePicker_KiXform.Form()
   If @ERROR Exit @ERROR EndIf
   $frm.icon=$_funDatePicker_KiXform.BuiltinIcons(101)
   $frm.width=200
   $frm.height=210
   $lblMonth = $frm.Controls.Label()
   $lblMonth.Bounds = 30, 10, $frm.width-70, 18
   $lblMonth.textalign=32
   $lblMonth.BackColor=$sToolColour
   $lblMonth.BorderStyle=FixedSingle
   $btnPrevYr = $frm.Controls.ToolButton()
   $btnPrevYr.Icon=26
   $btnPrevYr.Left=0
   $btnPrevYr.height=15
   $btnPrevYr.width=15
   $btnPrevYr.top=10
   $btnPrevYr.flatstyle=1
   $btnPrevYr.onclick="PreviousYr"
   $btnPrev = $frm.Controls.ToolButton()
   $btnPrev.Icon=27
   $btnPrev.Left=15
   $btnPrev.height=15
   $btnPrev.width=15
   $btnPrev.top=10
   $btnPrev.flatstyle=1
   $btnPrev.onclick="Previous"
   If $iTodayButton
      $frm.height=230
      $btnToday = $frm.Controls.ToolButton()
      $btnToday.text="Today"
      $btnToday.Left=($frm.width/2)-25
      $btnToday.height=20
      $btnToday.width=40
      $btnToday.top=$frm.Height-55
      $btnToday.onclick="Today"
      $btnToday.BackColor=$sToolColour
      $btnToday.FlatStyle = 1
   EndIf
   $btnNext = $frm.Controls.ToolButton()
   $btnNext.Icon=28
   $btnNext.Left=$frm.width-40
   $btnNext.height=15
   $btnNext.width=15
   $btnNext.top=10
   $btnNext.onclick="Next"
   $btnNext.FlatStyle=1
   $btnNextYr = $frm.Controls.ToolButton()
   $btnNextYr.Icon=29
   $btnNextYr.Left=$frm.width-25
   $btnNextYr.height=15
   $btnNextYr.width=15
   $btnNextYr.top=10
   $btnNextYr.flatstyle=1
   $btnNextYr.onclick="NextYr"
; Create day header labels
   For Each $s in Split($sDayHeader) $frm.PrintXY(Split($s,":")[0],30,Split($s,":")[1]) Next
   For $i = 0 to 36
      $btnList[$i] = $frm.ToolButton()
      $btnList[$i].Location = 10+$iDaynoWidth*($i mod 7),$iDaynoX+$iDaynoHeight*($i/7)
      $btnList[$i].width = $iDaynowidth
      $btnList[$i].height = $iDaynoHeight
      $btnList[$i].BorderStyle=1
      $btnList[$i].FlatStyle=$sButtonStyle
   Next
   $labFrame=$frm.Controls.Label()
   $labFrame.BorderStyle=1
   $labFrame.Text=""
   $labFrame.Width=181
   $labFrame.Height=106
   $labFrame.Top=47
   $labFrame.Left=7
   $frm.Show
   While $frm.Visible
      If $iUpdate
         $lblMonth.Text=$asMonthName[$iMonth-1]+" "+$iYear
         ; Fix leap day for this year
         $aiDaysInMonth[2]=28+((($iYear mod 4 = 0) AND ($iYear mod 100 > 0)) OR ($iYear mod 400 = 0))
         ; Calculate the offset for the first day of the month, algorithm taken from:
         ;   http://www.faqs.org/faqs/calendars/faq/part1/index.html#ixzz0Y3svssjS
         Dim $a,$y,$m
         $a = (14 - $iMonth) / 12
         $y = $iYear - $a
         $m = $iMonth + 12*$a - 2
         ; The "1" here is hardcoded for the first day of the month
         $iFirstDay = (1 + $y + $y/4 - $y/100 + $y/400 + (31*$m)/12) mod 7
         ; Algorithm gives Sunday=0, fix date  to ease calculation (Sunday=7)
         $iFirstDay=$iFirstDay+7*($iFirstDay=0)
         If $iFirstDay>5
            $labFrame.Height=126
         Else
            $labFrame.Height=106
         EndIf
         $btnPrev.enabled=TRUE
         $btnPrevYr.enabled=TRUE
         $btnNext.enabled=TRUE
         $btnNextYr.enabled=TRUE
         For $i=0 to 36
            If ($i+1)>=$iFirstDay AND ($i-$iFirstDay+1)<$aiDaysInMonth[$iMonth]
               $btnList[$i].Text = ($i+2-$iFirstDay)
               $sThisDay=CStr($iYear)+"/"+Right("0"+$iMonth,2)+"/"+Right("0"+$btnList[$i].Text,2)
               $btnList[$i].OnClick = 'btnDayNo '+$sThisDay
               $btnList[$i].visible=TRUE
               $btnList[$i].Backcolor=IIf(($i mod 7) mod 2,$sOddDayColour,$sEvenDayColour)
               If 1+AScan($asSpecialDays,$sThisDay) AND $sTodayColour $btnList[$i].Backcolor=$sTodayColour EndIf
               If $sThisDay<$sLowDay
                  $btnList[$i].enabled=FALSE
                  $btnPrev.enabled=FALSE
                  $btnPrevYr.enabled=FALSE
               Else
                  $btnList[$i].enabled=TRUE
                  $btnPrev.enabled=TRUE
                  $btnPrevYr.enabled=TRUE
               EndIf
               If $sThisDay>$sHighDay
                  $btnList[$i].enabled=FALSE
                  $btnNext.enabled=FALSE
                  $btnNextYr.enabled=FALSE
               Else
                  $btnList[$i].enabled=TRUE
                  $btnNext.enabled=TRUE
                  $btnNextYr.enabled=TRUE
               EndIf
            Else
               $btnList[$i].visible=FALSE
            EndIf
         Next
         $iUpdate=0
      EndIf
      $sAction=$frm.DoEvents
      Select
      Case $sAction=""
         ; No action
      Case $sAction="Previous"
         $iMonth=$iMonth-1
         If $iMonth<1 $iMonth=12 $iYear=$iYear-1 EndIf
         $iUpdate=1
      Case $sAction="Next"
         $iMonth=$iMonth+1
         If $iMonth>12 $iMonth=1 $iYear=$iYear+1 EndIf
         $iUpdate=1
      Case $sAction="PreviousYr"
         $iMonth=$iMonth-12
         If $iMonth<1 $iMonth=12-Abs($iMonth) $iYear=$iYear-1 EndIf
         $iUpdate=1
      Case $sAction="NextYr"
         $iMonth=$iMonth+12
         If $iMonth>12 $iMonth=Abs($iMonth)-12 $iYear=$iYear+1 EndIf
         $iUpdate=1
      Case $sAction="Today"
         $iMonth=@MONTHNO
         $iYear=@YEAR
         $iUpdate=1
      Case Split($sAction)[0]="btnDayNo"
         $udfDatePicker=Split($sAction)[1]
         $frm.hide
      Case Default
         "Unexpected event: "+$sAction+@CRLF
      EndSelect
   Loop
   $frm=0
   Exit 0
EndFunction
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    KiXforms Forum Index -> Script Archive All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group