/MKB/TimePicker/TimeSelector.cs

# · C# · 1160 lines · 868 code · 118 blank · 174 comment · 111 complexity · c4d1ebaebd5d6a2041e4b25151aa016f MD5 · raw file

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Specialized;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Text;
  7. using System.Web;
  8. using System.Web.UI;
  9. using System.Web.UI.HtmlControls;
  10. using System.Web.UI.WebControls;
  11. using System.Drawing;
  12. // ToDo:
  13. // Second Bug
  14. // Test clock a little
  15. // Option for read only clock
  16. // Ticking clock
  17. // release
  18. // support seconds
  19. // release
  20. // Read only and Enabled functionality doesn't work
  21. // If no control to the left is selected, select the left hour
  22. // Release
  23. // Make this control databindable
  24. // Release
  25. // Make support military time, 24 hour format
  26. // Release
  27. // add some validators for required fill in, required between time,
  28. // Release DONE TO HEREEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
  29. // Make design time pretty. right now it sucks
  30. // Release
  31. // Give it diff preset looks, figure out how MS did that with gridviews
  32. namespace MKB.TimePicker
  33. {
  34. /// <summary>
  35. /// Control that allows you to display a time picker in the same format as the Windows XP clock settings view.
  36. /// </summary>
  37. [ValidationProperty("Date")]
  38. [DefaultProperty("Text")]
  39. [ParseChildren(ChildrenAsProperties = true)]
  40. [ToolboxData("<{0}:TimeSelector runat=server></{0}:TimeSelector>")]
  41. public class TimeSelector : WebControl, IPostBackEventHandler, IPostBackDataHandler, IScriptControl
  42. {
  43. /// <summary>
  44. /// Enumerator representing the 3 adjustable parts of time for this control
  45. /// </summary>
  46. public enum TimePartType
  47. {
  48. Hour,
  49. Minute,
  50. Second
  51. }
  52. /// <summary>
  53. /// Enumerator representing AM/PM values
  54. /// </summary>
  55. public enum AmPmSpec
  56. {
  57. AM,
  58. PM
  59. }
  60. /// <summary>
  61. /// Enumerator Representing 12/24 Hour Formats
  62. /// </summary>
  63. public enum TimeFormat
  64. {
  65. Twelve = 12,
  66. TwentyFour = 24
  67. }
  68. /// <summary>
  69. /// Constructor initializes control as HtmlTextWriterTag.Span
  70. /// </summary>
  71. public TimeSelector() : base(HtmlTextWriterTag.Span) { }
  72. ScriptManager _sm = null;
  73. #region Properties
  74. #region Public Properties
  75. [Category("Appearance"),
  76. Description("Allows settings for the incremental buttons."),
  77. DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
  78. NotifyParentProperty(true),
  79. PersistenceMode(PersistenceMode.InnerDefaultProperty)]
  80. public ButtonSettings ButtonSettings
  81. {
  82. get
  83. {
  84. object o = ViewState["ButtonSettings"];
  85. return (o == null) ? null : (ButtonSettings)o;
  86. }
  87. set { ViewState["ButtonSettings"] = value; }
  88. }
  89. public override Color BorderColor
  90. {
  91. get
  92. {
  93. if (base.BackColor.IsEmpty)
  94. return ColorTranslator.FromHtml("Silver");
  95. else
  96. return base.BorderColor;
  97. }
  98. set
  99. {
  100. base.BorderColor = value;
  101. }
  102. }
  103. /// <summary>
  104. /// Returns the current hour value. 1-12.
  105. /// </summary>
  106. [DefaultValue("0")]
  107. public int Hour
  108. {
  109. get
  110. {
  111. if ((ViewState["Hour"] != null) && (ViewState["Hour"] != string.Empty))
  112. return Convert.ToInt32(ViewState["Hour"]);
  113. else
  114. return 0;
  115. }
  116. set
  117. {
  118. ViewState["Hour"] = value;
  119. }
  120. }
  121. /// <summary>
  122. /// Returns the AM<![CDATA[/]]>PM value
  123. /// </summary>
  124. [DefaultValue("PM")]
  125. public AmPmSpec AmPm
  126. {
  127. get
  128. {
  129. if (ViewState["AmPm"] != null)
  130. return (AmPmSpec)ViewState["AmPm"];
  131. else
  132. return AmPmSpec.PM;
  133. }
  134. set
  135. { ViewState["AmPm"] = value; }
  136. }
  137. /// <summary>
  138. /// Gets or sets the 12<![CDATA[/]]>24 time format preference
  139. /// </summary>
  140. [DefaultValue("Twelve")]
  141. public TimeFormat SelectedTimeFormat
  142. {
  143. get
  144. {
  145. if (ViewState["SelectedTimeFormat"] != null)
  146. return (TimeFormat)ViewState["SelectedTimeFormat"];
  147. else
  148. return TimeFormat.Twelve;
  149. }
  150. set
  151. { ViewState["SelectedTimeFormat"] = value; }
  152. }
  153. /// <summary>
  154. /// Returns the current minute value. 0-59.
  155. /// </summary>
  156. [DefaultValue("0")]
  157. public int Minute
  158. {
  159. get
  160. {
  161. if ((ViewState["Minute"] != null) && (ViewState["Minute"] != string.Empty))
  162. return Convert.ToInt32(ViewState["Minute"]);
  163. else
  164. return 0;
  165. }
  166. set
  167. {
  168. ViewState["Minute"] = value;
  169. }
  170. }
  171. /// <summary>
  172. /// Returns the current second value. 0-59.
  173. /// </summary>
  174. [DefaultValue("0")]
  175. public int Second
  176. {
  177. get
  178. {
  179. if ((ViewState["Second"] != null) && (ViewState["Second"] != string.Empty))
  180. return Convert.ToInt32(ViewState["Second"]);
  181. else
  182. return 0;
  183. }
  184. set
  185. {
  186. ViewState["Second"] = value;
  187. }
  188. }
  189. /// <summary>
  190. /// DateTime value. Defaults to current day if not set. Otherwise, maintains a value of the date assigned plus time shown.
  191. /// </summary>
  192. [Browsable(true)]
  193. public DateTime Date
  194. {
  195. get
  196. {
  197. if (ViewState["Date"] == null)
  198. return DateTime.MinValue;
  199. else
  200. {
  201. if (SelectedTimeFormat == TimeFormat.Twelve)
  202. {
  203. ViewState["Date"] = Convert.ToDateTime(ViewState["Date"]).ToShortDateString() + " " + Hour.ToString() + ":" + Minute.ToString() + ":" + Second.ToString() + " " + AmPm.ToString();
  204. }
  205. else
  206. {
  207. ViewState["Date"] = Convert.ToDateTime((Convert.ToDateTime(ViewState["Date"]).ToShortDateString() + " " + Hour.ToString() + ":" + Minute.ToString() + ":" + Second.ToString() + " "), System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat);
  208. }
  209. return Convert.ToDateTime(ViewState["Date"]);
  210. }
  211. }
  212. set
  213. {
  214. ViewState["Date"] = value;
  215. SetTime(value);
  216. }
  217. }
  218. /// <summary>
  219. /// Determines whether or not this control is editable by a user within a browser.
  220. /// </summary>
  221. [Browsable(true)]
  222. [Category("Behavior")]
  223. [DefaultValue(false)]
  224. [Description("Determines whether or not this control is editable by a user within a browser.")]
  225. public bool ReadOnly
  226. {
  227. get
  228. {
  229. if (ViewState["ReadOnly"] != null)
  230. return Convert.ToBoolean(ViewState["ReadOnly"]);
  231. else
  232. return false;
  233. }
  234. set
  235. {
  236. ViewState["ReadOnly"] = value;
  237. }
  238. }
  239. /// <summary>
  240. /// Determines whether or not this control displays the seconds slot in the browser.
  241. /// </summary>
  242. [Browsable(true)]
  243. [Category("Appearance")]
  244. [DefaultValue(true)]
  245. [Description("Determines whether or not this control displays the up and down buttons for adjusting time in the browser.")]
  246. public bool DisplayButtons
  247. {
  248. get
  249. {
  250. if (ViewState["DisplayButtons"] != null)
  251. return Convert.ToBoolean(ViewState["DisplayButtons"]);
  252. else
  253. return true;
  254. }
  255. set
  256. {
  257. ViewState["DisplayButtons"] = value;
  258. }
  259. }
  260. /// <summary>
  261. /// Determines whether or not this control displays the seconds slot in the browser.
  262. /// </summary>
  263. [Browsable(true)]
  264. [Category("Appearance")]
  265. [DefaultValue(true)]
  266. [Description("Determines whether or not this control displays the seconds slot in the browser.")]
  267. public bool DisplaySeconds
  268. {
  269. get
  270. {
  271. if (ViewState["DisplaySeconds"] != null)
  272. return Convert.ToBoolean(ViewState["DisplaySeconds"]);
  273. else
  274. return true;
  275. }
  276. set
  277. {
  278. ViewState["DisplaySeconds"] = value;
  279. }
  280. }
  281. ///// <summary>
  282. ///// Determines the color of the border surrounding the main time box area.
  283. ///// </summary>
  284. //[Browsable(true)]
  285. //[Category("Appearance")]
  286. //[DefaultValue("Silver")]
  287. //[Description("Determines the color of the border surrounding the main time box area.")]
  288. //public string BorderColor
  289. //{
  290. // get
  291. // {
  292. // if (ViewState["BorderColor"] != null)
  293. // return Convert.ToString(ViewState["BorderColor"]);
  294. // else
  295. // return "Silver";
  296. // }
  297. // set
  298. // {
  299. // ViewState["BorderColor"] = value;
  300. // }
  301. //}
  302. ///// <summary>
  303. ///// Determines the color of the background of the main time box area.
  304. ///// </summary>
  305. //[Browsable(true)]
  306. //[Category("Appearance")]
  307. //[DefaultValue("White")]
  308. //[Description("Determines the color of the background of the main time box area.")]
  309. //public string BackgroundColor
  310. //{
  311. // get
  312. // {
  313. // if (ViewState["BackgroundColor"] != null)
  314. // return Convert.ToString(ViewState["BackgroundColor"]);
  315. // else
  316. // return "White";
  317. // }
  318. // set
  319. // {
  320. // ViewState["BackgroundColor"] = value;
  321. // }
  322. //}
  323. /// <summary>
  324. /// Determines whether or not seconds are a factor in this control. If set to false, the second will always be 00.
  325. /// </summary>
  326. [Browsable(true)]
  327. [Category("Behavior")]
  328. [DefaultValue(false)]
  329. [Description("Boolean value that determines whether or not seconds are a factor in this control. If set to false, the second will always be 00.")]
  330. public bool AllowSecondEditing
  331. {
  332. get
  333. {
  334. if (ViewState["AllowSecondEditing"] != null)
  335. return Convert.ToBoolean(ViewState["AllowSecondEditing"]);
  336. else
  337. return false;
  338. }
  339. set
  340. {
  341. ViewState["AllowSecondEditing"] = value;
  342. }
  343. }
  344. /// <summary>
  345. /// Enables ticking clock-like functionality.
  346. /// </summary>
  347. [Browsable(true)]
  348. [Category("Behavior")]
  349. [DefaultValue(false)]
  350. [Description("Boolean indicating whether or not the control acts as a clock in nature rather than a timepicker.")]
  351. public bool EnableClock
  352. {
  353. get
  354. {
  355. if (ViewState["EnableClock"] != null)
  356. return Convert.ToBoolean(ViewState["EnableClock"]);
  357. else
  358. return false;
  359. }
  360. set
  361. {
  362. ViewState["EnableClock"] = value;
  363. }
  364. }
  365. private int _MinuteIncrement = 15;
  366. /// <summary>
  367. /// Determines how many minutes are added or subtracted from the minute slot when a user clicks the up and down arrows.
  368. /// </summary>
  369. [Browsable(true)]
  370. [Category("Behavior")]
  371. [DefaultValue(15)]
  372. [Description("Determines how many minutes are added or subtracted from the minute slot when a user clicks the up and down arrows.")]
  373. public int MinuteIncrement
  374. {
  375. get { return _MinuteIncrement; }
  376. set { _MinuteIncrement = value; }
  377. }
  378. private int _SecondIncrement = 1;
  379. /// <summary>
  380. /// Determines how many seconds are added or subtracted from the second slot when a user clicks the up and down arrows.
  381. /// </summary>
  382. [Browsable(true)]
  383. [Category("Behavior")]
  384. [DefaultValue(1)]
  385. [Description("Determines how many seconds are added or subtracted from the second slot when a user clicks the up and down arrows.")]
  386. public int SecondIncrement
  387. {
  388. get { return _SecondIncrement; }
  389. set { _SecondIncrement = value; }
  390. }
  391. #endregion
  392. #region Private Properties
  393. private string AppPath
  394. {
  395. get { return (HttpContext.Current.Request.ApplicationPath.EndsWith("/")) ? HttpContext.Current.Request.ApplicationPath : HttpContext.Current.Request.ApplicationPath + "/"; }
  396. }
  397. #endregion
  398. #endregion
  399. #region Lifecycle Methods
  400. #region Postback & State Maintenance Methods
  401. bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection values)
  402. {
  403. return this.LoadPostData(postDataKey, values);
  404. }
  405. public virtual bool LoadPostData(string postDataKey, NameValueCollection values)
  406. {
  407. bool hasHourChange = false;
  408. bool hasMinuteChange = false;
  409. bool hasSecondChange = false;
  410. bool hasAmPmChange = false;
  411. string sHour = values[this.UniqueID];
  412. if(sHour != string.Empty)
  413. if (int.Parse(sHour) != Hour)
  414. {
  415. Hour = int.Parse(sHour);
  416. hasHourChange = true;
  417. }
  418. string sMinute = values[this.UniqueID + "_txtMinute"];
  419. if(sMinute != string.Empty)
  420. if (int.Parse(sMinute) != Minute)
  421. {
  422. Minute = int.Parse(sMinute);
  423. hasMinuteChange = true;
  424. }
  425. string sSecond = values[this.UniqueID + "_txtSecond"];
  426. if(!String.IsNullOrEmpty(sSecond))
  427. if (int.Parse(sSecond) != Second)
  428. {
  429. Second = int.Parse(sSecond);
  430. hasSecondChange = true;
  431. }
  432. //AmPmSpec tAmPm = (values[this.UniqueID + "_txtAmPm"] == "AM") ? AmPmSpec.AM : AmPmSpec.PM;
  433. //if (tAmPm != AmPm)
  434. //{
  435. // AmPm = tAmPm;
  436. // hasAmPmChange = true;
  437. //}
  438. // If missing, should be in 24 hour
  439. string sAmPm = values[this.UniqueID + "_txtAmPm"];
  440. if (!String.IsNullOrEmpty(sAmPm))
  441. {
  442. AmPmSpec tAmPm = (values[this.UniqueID + "_txtAmPm"] == "AM") ? AmPmSpec.AM : AmPmSpec.PM;
  443. if (tAmPm != AmPm)
  444. {
  445. AmPm = tAmPm;
  446. hasAmPmChange = true;
  447. }
  448. }
  449. else
  450. {
  451. if (int.Parse(sHour) > 11)
  452. {
  453. AmPm = AmPmSpec.PM;
  454. }
  455. else
  456. {
  457. AmPm = AmPmSpec.AM;
  458. }
  459. }
  460. return hasHourChange || hasAmPmChange || hasMinuteChange || hasSecondChange;
  461. }
  462. void IPostBackDataHandler.RaisePostDataChangedEvent()
  463. {
  464. this.RaisePostDataChangedEvent();
  465. }
  466. public virtual void RaisePostDataChangedEvent()
  467. {
  468. SetTime(Hour, Minute, Second, AmPm);
  469. }
  470. void IPostBackEventHandler.RaisePostBackEvent(string args)
  471. {
  472. this.RaisePostBackEvent(args);
  473. }
  474. protected virtual void RaisePostBackEvent(string args)
  475. {
  476. }
  477. #endregion
  478. protected override void RenderContents(HtmlTextWriter output)
  479. {
  480. output.AddAttribute("CellSpacing", "0");
  481. output.AddAttribute("CellPadding", "0");
  482. output.AddStyleAttribute(HtmlTextWriterStyle.BorderCollapse, "collapse");
  483. output.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "None");
  484. output.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0px");
  485. output.RenderBeginTag(HtmlTextWriterTag.Table);
  486. output.RenderBeginTag(HtmlTextWriterTag.Tr);
  487. output.AddStyleAttribute(HtmlTextWriterStyle.VerticalAlign, "Bottom");
  488. output.RenderBeginTag(HtmlTextWriterTag.Td);
  489. #region Hour textBox
  490. // Hour Input TextBox
  491. output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + @"_txtHour");
  492. output.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
  493. if (ReadOnly)
  494. {
  495. output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "readonly");
  496. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.blur();");
  497. }
  498. else
  499. {
  500. //output.AddAttribute(HtmlTextWriterAttribute.Tabindex, "1");
  501. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.select();lastFocusCtrl=this;");
  502. output.AddAttribute(HtmlTextWriterAttribute.Onchange, "intOnly(this," + Convert.ToString((int)SelectedTimeFormat) + ");");
  503. output.AddAttribute("onFocus", "this.select();lastFocusCtrl=this;");
  504. output.AddAttribute("onKeyDown", "return updownArrow(event, this," + Convert.ToString((int)SelectedTimeFormat) + "," + MinuteIncrement.ToString() + "," + SecondIncrement.ToString() + ");");
  505. }
  506. //output.AddAttribute(HtmlTextWriterAttribute.Class, "Hour");
  507. output.AddStyleAttribute(HtmlTextWriterStyle.Height, "15px");
  508. output.AddStyleAttribute("border-bottom", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  509. output.AddStyleAttribute("border-left", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  510. output.AddStyleAttribute("border-top", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  511. output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor));
  512. output.AddStyleAttribute("border-right", "none");
  513. output.AddStyleAttribute(HtmlTextWriterStyle.Width, "17px");
  514. output.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "9pt");
  515. output.AddAttribute(HtmlTextWriterAttribute.Cols, "2");
  516. output.AddAttribute(HtmlTextWriterAttribute.Maxlength, "2");
  517. if (Hour > 0)
  518. output.AddAttribute(HtmlTextWriterAttribute.Value, getTimePartString(Hour, TimePartType.Hour));
  519. output.RenderBeginTag(HtmlTextWriterTag.Input);
  520. output.RenderEndTag();
  521. #endregion
  522. AddSeperator(output);
  523. #region Minute TextBox
  524. // Minute Input TextBox
  525. output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + @"_txtMinute");
  526. output.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + "_txtMinute");
  527. if (ReadOnly)
  528. {
  529. output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "readonly");
  530. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.blur();");
  531. }
  532. else
  533. {
  534. //output.AddAttribute(HtmlTextWriterAttribute.Tabindex, "2");
  535. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.select();lastFocusCtrl=this;");
  536. output.AddAttribute(HtmlTextWriterAttribute.Onchange, "intOnly(this," + Convert.ToString((int)SelectedTimeFormat) + ");");
  537. output.AddAttribute("onFocus", "this.select();lastFocusCtrl=this;");
  538. output.AddAttribute("onKeyDown", "return updownArrow(event, this," + Convert.ToString((int)SelectedTimeFormat) + "," + MinuteIncrement.ToString() + "," + SecondIncrement.ToString() + ");");
  539. }
  540. //output.AddAttribute(HtmlTextWriterAttribute.Class, "Minute");
  541. output.AddStyleAttribute(HtmlTextWriterStyle.Height, "15px");
  542. output.AddStyleAttribute("border-bottom", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  543. output.AddStyleAttribute("border-left", "none");
  544. output.AddStyleAttribute("border-top", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  545. output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor));
  546. output.AddStyleAttribute("border-right", "none");
  547. output.AddStyleAttribute(HtmlTextWriterStyle.Width, "17px");
  548. output.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "9pt");
  549. output.AddAttribute(HtmlTextWriterAttribute.Cols, "2");
  550. output.AddAttribute(HtmlTextWriterAttribute.Maxlength, "2");
  551. if (Minute >= 0)
  552. output.AddAttribute(HtmlTextWriterAttribute.Value, getTimePartString(Minute, TimePartType.Minute));
  553. output.RenderBeginTag(HtmlTextWriterTag.Input);
  554. output.RenderEndTag();
  555. #endregion
  556. #region Seconds TextBox
  557. // Second Input TextBox
  558. if (DisplaySeconds)
  559. {
  560. AddSeperator(output);
  561. output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + @"_txtSecond");
  562. output.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + "_txtSecond");
  563. if ((ReadOnly) || (!AllowSecondEditing))
  564. {
  565. output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "readonly");
  566. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.blur();");
  567. }
  568. if (AllowSecondEditing)
  569. {
  570. //output.AddAttribute(HtmlTextWriterAttribute.Tabindex, "3");
  571. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.select();lastFocusCtrl=this;");
  572. output.AddAttribute(HtmlTextWriterAttribute.Onchange, "intOnly(this," + Convert.ToString((int)SelectedTimeFormat) + ");");
  573. output.AddAttribute("onFocus", "this.select();lastFocusCtrl=this;");
  574. output.AddAttribute("onKeyDown", "return updownArrow(event, this," + Convert.ToString((int)SelectedTimeFormat) + "," + MinuteIncrement.ToString() + "," + SecondIncrement.ToString() + ");");
  575. }
  576. output.AddStyleAttribute(HtmlTextWriterStyle.Height, "15px");
  577. output.AddStyleAttribute("border-bottom", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  578. output.AddStyleAttribute("border-left", "none");
  579. output.AddStyleAttribute("border-top", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  580. output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor));
  581. output.AddStyleAttribute("border-right", "none");
  582. output.AddStyleAttribute(HtmlTextWriterStyle.Width, "17px");
  583. output.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "9pt");
  584. if(SelectedTimeFormat == TimeFormat.Twelve)
  585. output.AddStyleAttribute("border-right", "none");
  586. else
  587. output.AddStyleAttribute("border-right", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  588. output.AddAttribute(HtmlTextWriterAttribute.Cols, "2");
  589. output.AddAttribute(HtmlTextWriterAttribute.Maxlength, "2");
  590. if (AllowSecondEditing)//&&(!LoadZeroSecondsInitially))
  591. output.AddAttribute(HtmlTextWriterAttribute.Value, getTimePartString(Second, TimePartType.Second));
  592. else
  593. output.AddAttribute(HtmlTextWriterAttribute.Value, "00");
  594. output.RenderBeginTag(HtmlTextWriterTag.Input);
  595. output.RenderEndTag();
  596. }
  597. #endregion
  598. #region AM/PM TextBox
  599. // AmPm Input TextBox
  600. if (SelectedTimeFormat != TimeFormat.TwentyFour) // Don't render unless it's 12 hour format
  601. {
  602. output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + @"_txtAmPm");
  603. output.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID + "_txtAmPm");
  604. output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "readonly");
  605. if (ReadOnly)
  606. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.blur();");
  607. else
  608. {
  609. //output.AddAttribute(HtmlTextWriterAttribute.Tabindex, "4");
  610. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.select();lastFocusCtrl=this;");
  611. output.AddAttribute(HtmlTextWriterAttribute.Onchange, "keepAmPm();");
  612. output.AddAttribute("onFocus", "this.select();lastFocusCtrl=this;");
  613. output.AddAttribute("onKeyDown", "return updownArrow(event, this," + Convert.ToString((int)SelectedTimeFormat) + "," + MinuteIncrement.ToString() + "," + SecondIncrement.ToString() + ");");
  614. }
  615. //output.AddAttribute(HtmlTextWriterAttribute.Class, "AmPm");
  616. output.AddStyleAttribute(HtmlTextWriterStyle.Height, "15px");
  617. output.AddStyleAttribute("border-bottom", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  618. output.AddStyleAttribute("border-left", "none");
  619. output.AddStyleAttribute("border-right", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  620. output.AddStyleAttribute("border-top", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  621. output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor));
  622. output.AddStyleAttribute(HtmlTextWriterStyle.Width, "22px");
  623. output.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "9pt");
  624. output.AddAttribute(HtmlTextWriterAttribute.Cols, "2");
  625. output.AddAttribute(HtmlTextWriterAttribute.Maxlength, "2");
  626. output.AddAttribute(HtmlTextWriterAttribute.Value, AmPm.ToString());
  627. output.RenderBeginTag(HtmlTextWriterTag.Input);
  628. output.RenderEndTag();
  629. }
  630. output.RenderEndTag(); // End AmPm cell
  631. #endregion
  632. #region Up and Down Buttons
  633. if ((!ReadOnly) && (!EnableClock) && (DisplayButtons))
  634. {
  635. //output.AddStyleAttribute(HtmlTextWriterStyle.VerticalAlign, "Bottom");
  636. output.RenderBeginTag(HtmlTextWriterTag.Td);
  637. // Up Arrow for Adding Time
  638. output.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
  639. output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + @"_imgUp");
  640. if (!ReadOnly)
  641. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "addTime(this," + Convert.ToString((int)SelectedTimeFormat) + "," +
  642. MinuteIncrement.ToString() + "," + SecondIncrement.ToString() + ");");
  643. #region Up Button Settings
  644. if (this.ButtonSettings == null)
  645. {
  646. output.AddAttribute(HtmlTextWriterAttribute.Src,
  647. Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector), "TimePicker.Images.up.jpg"));
  648. output.AddAttribute("onMouseOver", "this.src='" +
  649. Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector), "TimePicker.Images.up-over.jpg") + "';");
  650. output.AddAttribute("onMouseOut", "this.src='" +
  651. Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector), "TimePicker.Images.up.jpg") + "';");
  652. }
  653. else
  654. {
  655. output.AddAttribute(HtmlTextWriterAttribute.Src, this.ButtonSettings.UpImageURL);
  656. if (this.ButtonSettings.MouseOversActive)
  657. {
  658. output.AddAttribute("onMouseOver", "this.src='" + this.ButtonSettings.UpOverImageURL + "';");
  659. output.AddAttribute("onMouseOut", "this.src='" + this.ButtonSettings.UpImageURL + "';");
  660. }
  661. }
  662. #endregion
  663. output.RenderBeginTag(HtmlTextWriterTag.Img);
  664. output.RenderEndTag();
  665. output.Write("<br />");
  666. // Down Arrow for Subtracting Time
  667. output.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
  668. output.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + @"_imgDown");
  669. if (!ReadOnly)
  670. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "subtractTime(this," + Convert.ToString((int)SelectedTimeFormat) + "," + MinuteIncrement.ToString() + "," + SecondIncrement.ToString() + ");");
  671. #region Down Button Settings
  672. if (this.ButtonSettings == null)
  673. {
  674. output.AddAttribute(HtmlTextWriterAttribute.Src,
  675. Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector), "TimePicker.Images.down.jpg"));
  676. output.AddAttribute("onMouseOver", "this.src='" +
  677. Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector), "TimePicker.Images.down-over.jpg") + "';");
  678. output.AddAttribute("onMouseOut", "this.src='" +
  679. Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector), "TimePicker.Images.down.jpg") + "';");
  680. }
  681. else
  682. {
  683. output.AddAttribute(HtmlTextWriterAttribute.Src, this.ButtonSettings.DownImageURL);
  684. if (this.ButtonSettings.MouseOversActive)
  685. {
  686. output.AddAttribute("onMouseOver", "this.src='" + this.ButtonSettings.DownOverImageURL + "';");
  687. output.AddAttribute("onMouseOut", "this.src='" + this.ButtonSettings.DownImageURL + "';");
  688. }
  689. }
  690. #endregion
  691. output.RenderBeginTag(HtmlTextWriterTag.Img);
  692. output.RenderEndTag();
  693. output.RenderEndTag(); // End Button Cell
  694. }
  695. #endregion
  696. output.RenderEndTag(); // Row
  697. output.RenderEndTag(); // Table
  698. AddJavaScript();
  699. }
  700. protected override void Render(HtmlTextWriter writer)
  701. {
  702. if (!this.DesignMode)
  703. _sm.RegisterScriptDescriptors(this);
  704. base.Render(writer);
  705. }
  706. protected override void OnPreRender(EventArgs e)
  707. {
  708. if (!this.DesignMode)
  709. {
  710. // Make sure ScriptManager exists
  711. _sm = ScriptManager.GetCurrent(Page);
  712. if (_sm == null)
  713. throw new HttpException("A ScriptManager control must exist on the page.");
  714. // Register as client control.
  715. _sm.RegisterScriptControl(this);
  716. }
  717. base.OnPreRender(e);
  718. // BuildCSS();
  719. if ((Date == DateTime.MinValue) && (Hour == 0))
  720. {
  721. if (SelectedTimeFormat == TimeFormat.Twelve)
  722. Date = DateTime.Now;
  723. else // 24 hour format
  724. {
  725. Date = DateTime.Now;
  726. if (Hour < 12)
  727. Hour += 12;
  728. Date = Convert.ToDateTime(DateTime.Now.ToShortDateString() + " " +
  729. (Hour).ToString() + ":" + Minute.ToString() + ":" + Second.ToString() + " " + AmPm.ToString());
  730. }
  731. }
  732. else if ((Hour != 0) && (Date == DateTime.MinValue))
  733. {
  734. Date = Convert.ToDateTime(DateTime.Now.ToShortDateString() + " " +
  735. Hour.ToString() + ":" + Minute.ToString() + ":" + Second.ToString() + " " + AmPm.ToString());
  736. }
  737. // Moved to the onload for situations when the control isn't shown to begin with in an updatepanel
  738. //Page.ClientScript.RegisterClientScriptResource(typeof(MKB.TimePicker.TimeSelector), "TimePicker.js.MKB_TimePicker.js");
  739. }
  740. protected override void OnLoad(EventArgs e)
  741. {
  742. if (EnableClock)
  743. {
  744. ReadOnly = true;
  745. AllowSecondEditing = true;
  746. }
  747. Page.ClientScript.RegisterClientScriptResource(typeof(MKB.TimePicker.TimeSelector), "TimePicker.js.MKB_TimePicker.js");
  748. base.OnLoad(e);
  749. }
  750. #endregion
  751. #region Custom Functions
  752. private void SetTime(DateTime DateAndTime)
  753. {
  754. if (SelectedTimeFormat == TimeFormat.Twelve)
  755. {
  756. Hour = Convert.ToInt32(DateAndTime.ToString("hh", System.Globalization.DateTimeFormatInfo.InvariantInfo));
  757. AmPm = (DateAndTime.ToString("tt", System.Globalization.DateTimeFormatInfo.InvariantInfo) == "AM") ? AmPmSpec.AM : AmPmSpec.PM;
  758. }
  759. else // 24 hour format
  760. {
  761. Hour = Convert.ToInt32(DateAndTime.ToString("HH", System.Globalization.DateTimeFormatInfo.InvariantInfo));
  762. }
  763. Minute = Convert.ToInt32(DateAndTime.ToString("mm", System.Globalization.DateTimeFormatInfo.InvariantInfo));
  764. Second = (AllowSecondEditing)?Convert.ToInt32(DateAndTime.ToString("ss", System.Globalization.DateTimeFormatInfo.InvariantInfo)):0;
  765. string sMinute = (Minute.ToString().Length == 1) ? "0" + Minute.ToString() : Minute.ToString();
  766. ViewState["Date"] = Convert.ToDateTime(ViewState["Date"]).ToShortDateString() + " " + Hour.ToString() + ":" + sMinute + ":00 " + AmPm.ToString();
  767. }
  768. /// <summary>
  769. /// Preset to an hour and a minute such as 2:30 PM
  770. /// </summary>
  771. /// <param name="hour">Integer representing the hour</param>
  772. /// <param name="minute">Integer representing the minute</param>
  773. /// <param name="AmOrPm">Enum indicating which part of the day the time is being set</param>
  774. public void SetTime(int hour, int minute, AmPmSpec AmOrPm)
  775. {
  776. SetTime(hour, minute, 0, AmOrPm);
  777. }
  778. /// <summary>
  779. /// Preset to an hour and a minute such as 2:30 PM
  780. /// </summary>
  781. /// <param name="hour">Integer representing the hour</param>
  782. /// <param name="minute">Integer representing the minute</param>
  783. /// <param name="second">Integer representing the seconds</param>
  784. /// <param name="AmOrPm">Enum indicating which part of the day the time is being set</param>
  785. public void SetTime(int hour, int minute, int second, AmPmSpec AmOrPm)
  786. {
  787. Hour = hour;
  788. Minute = minute;
  789. Second = second;
  790. AmPm = AmOrPm;
  791. string DateToUse = (this.Date.Date.ToShortDateString() == DateTime.Now.ToShortDateString()) ? DateTime.Now.ToShortDateString() : this.Date.Date.ToShortDateString();
  792. Date = Convert.ToDateTime(DateToUse + " " +
  793. Hour.ToString() + ":" + Minute.ToString() + ":" + Second.ToString() + " " + AmOrPm.ToString());
  794. }
  795. private void AddSeperator(HtmlTextWriter output)
  796. {
  797. // Seperator Input TextBox
  798. output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "readonly");
  799. //output.AddAttribute(HtmlTextWriterAttribute.Class, "Seperator");
  800. output.AddAttribute(HtmlTextWriterAttribute.Cols, "1");
  801. output.AddAttribute(HtmlTextWriterAttribute.Maxlength, "1");
  802. output.AddAttribute(HtmlTextWriterAttribute.Value, ":");
  803. //output.AddStyleAttribute(HtmlTextWriterStyle.Height, "15px");
  804. output.AddStyleAttribute(HtmlTextWriterStyle.Height, "15px");
  805. output.AddStyleAttribute("border-bottom", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  806. output.AddStyleAttribute("border-left", "none");
  807. output.AddStyleAttribute("border-right", "none");
  808. output.AddStyleAttribute("border-top", "solid 1px " + ColorTranslator.ToHtml(BorderColor));
  809. output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor));
  810. output.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "9pt");
  811. output.AddStyleAttribute(HtmlTextWriterStyle.Width, "4px");
  812. output.AddAttribute(HtmlTextWriterAttribute.Onclick, "this.nextSibling.focus();//this.blur();return false;");
  813. output.AddAttribute("onfocus", "this.nextSibling.focus();//blur();return false;");
  814. output.RenderBeginTag(HtmlTextWriterTag.Input);
  815. output.RenderEndTag();
  816. }
  817. /// <summary>
  818. /// Registers and inserts a javascript client script block that handles time changes from the user
  819. /// </summary>
  820. protected virtual void AddJavaScript()
  821. {
  822. //Page.ClientScript.RegisterClientScriptInclude("TimePicker.js.MKB_TimePicker.js",
  823. // Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector), "TimePicker.js.MKB_TimePicker.js"));
  824. if (EnableClock)
  825. {
  826. Page.ClientScript.RegisterStartupScript(typeof(String), "OnClickEvents", @"
  827. <SCRIPT LANGUAGE=""JavaScript"">
  828. function updateClock ( ) {
  829. var selectedTimeFormat = " + (int)SelectedTimeFormat + @";
  830. var currentTime = new Date ( );
  831. var currentHours = currentTime.getHours ( );
  832. var currentMinutes = currentTime.getMinutes ( );
  833. var currentSeconds = currentTime.getSeconds ( );
  834. // Convert an hours component of '0' to '12'
  835. if(document.getElementById('" + this.UniqueID + @"_txtAmPm') != null)
  836. document.getElementById('" + this.UniqueID + @"_txtAmPm').value = ( currentHours < 12 ) ? 'AM' : 'PM';
  837. if(selectedTimeFormat == 12)
  838. {
  839. currentHours = ( currentHours == 0 ) ? 12 : currentHours;
  840. currentHours = ( currentHours > 12 ) ? currentHours - 12 : currentHours;
  841. }
  842. currentHours = ( currentHours < 10 ? '0' : '' ) + currentHours;
  843. // Update the time display
  844. if(selectedTimeFormat == 12)
  845. document.getElementById('" + this.UniqueID + @"_txtHour').value = ( currentHours > 12 ) ? currentHours - 12 : currentHours;
  846. else
  847. document.getElementById('" + this.UniqueID + @"_txtHour').value = currentHours;
  848. document.getElementById('" + this.UniqueID + @"_txtMinute').value = ( currentMinutes < 10 ? '0' : '' ) + currentMinutes;
  849. if(" + DisplaySeconds.ToString().ToLower() + @")
  850. document.getElementById('" + this.UniqueID + @"_txtSecond').value = ( currentSeconds < 10 ? '0' : '' ) + currentSeconds;
  851. }
  852. </script>");
  853. //'" + Date.ToString("MMMM") + " " + Date.ToString("dd") + ", " + Date.ToString("yyyy")
  854. // + " " + Date.ToString("HH") + ":" + Date.ToString("mm") + ":" + Date.ToString("ss") + "'" + @");
  855. Page.ClientScript.RegisterStartupScript(typeof(String), "OnLocalCloclEvents", @"
  856. var ie = /MSIE/.test(navigator.userAgent);
  857. /* =================================================== */
  858. var addEvent;
  859. if (document.addEventListener) {
  860. addEvent = function(element, type, handler) {
  861. element.addEventListener(type, handler, null);
  862. };
  863. } else if (document.attachEvent) {
  864. addEvent = function(element, type, handler) {
  865. element.attachEvent('on' + type, handler);
  866. };
  867. } else {
  868. addEvent = new Function; // not supported
  869. }
  870. addEvent(window,'load',startClock);
  871. function startClock(){
  872. updateClock();
  873. setInterval('updateClock()', 1000);
  874. }
  875. ", true);
  876. }
  877. }
  878. /// <summary>
  879. /// Builds and inserts a style client script block to style the control
  880. /// </summary>
  881. protected virtual void BuildCSS()
  882. {
  883. if (!Page.ClientScript.IsClientScriptBlockRegistered("TimeSelectorStyling"))
  884. {
  885. Page.ClientScript.RegisterClientScriptBlock(typeof(String), "TimeSelectorStyling", @"
  886. <style>
  887. .Hour
  888. {
  889. border-bottom: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  890. border-left: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  891. border-top: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  892. background-color: " + ColorTranslator.ToHtml(BackColor) + @";
  893. border-right:none;
  894. width:17px;
  895. height:19px;
  896. font-size:9pt;
  897. }
  898. .Minute
  899. {
  900. border-bottom: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  901. border-top: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  902. background-color: " + ColorTranslator.ToHtml(BackColor) + @";
  903. border-left: none;
  904. border-right:none;
  905. width:17px;
  906. height:19px;
  907. font-size:9pt;
  908. }
  909. .Second
  910. {
  911. border-top: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  912. border-right: none;
  913. border-bottom: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  914. background-color: " + ColorTranslator.ToHtml(BackColor) + @";
  915. border-left: none;
  916. width:17px;
  917. height:19px;
  918. font-size:9pt;
  919. }
  920. .SecondTwentyFour
  921. {
  922. border-top: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  923. border-right: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  924. border-bottom: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  925. background-color: " + ColorTranslator.ToHtml(BackColor) + @";
  926. border-left: none;
  927. width:17px;
  928. height:19px;
  929. font-size:9pt;
  930. }
  931. .Seperator
  932. {
  933. border-bottom: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  934. border-top: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  935. background-color: " + ColorTranslator.ToHtml(BackColor) + @";
  936. border-left: none;
  937. border-right: none;
  938. width:4px;
  939. height:19px;
  940. font-size:9pt;
  941. }
  942. .AmPm
  943. {
  944. border-top: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  945. border-right: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  946. border-bottom: solid 1px " + ColorTranslator.ToHtml(BorderColor) + @";
  947. background-color: " + ColorTranslator.ToHtml(BackColor) + @";
  948. border-left: none;
  949. width:22px;
  950. height:19px;
  951. font-size:9pt;
  952. }
  953. </style>
  954. ");
  955. }
  956. }
  957. /// <summary>
  958. /// Gets a string representation of the time with leading 0's in number less than 10
  959. /// </summary>
  960. /// <param name="TimePartValue">The hour, minute, or second that you want formatted</param>
  961. /// <param name="TimePart">A <see cref="TimePartType">TimePart</see> that determines which part of the time TimePartValue is.</param>
  962. /// <returns></returns>
  963. protected virtual string getTimePartString(int TimePartValue, TimePartType TimePart)
  964. {
  965. string sTemp = TimePartValue.ToString();
  966. switch (TimePart)
  967. {
  968. case TimePartType.Hour:
  969. if ((TimePartValue >= 0) && (TimePartValue <= 9))
  970. sTemp = "0" + TimePartValue.ToString();
  971. break;
  972. case TimePartType.Minute:
  973. if ((TimePartValue >= 0) && (TimePartValue <= 9))
  974. sTemp = "0" + TimePartValue.ToString();
  975. break;
  976. case TimePartType.Second:
  977. if ((TimePartValue >= 0) && (TimePartValue <= 9))
  978. sTemp = "0" + TimePartValue.ToString();
  979. break;
  980. }
  981. return sTemp;
  982. }
  983. #endregion
  984. #region IScriptControl Members
  985. IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
  986. {
  987. ScriptControlDescriptor descriptor = new ScriptControlDescriptor(
  988. "MKB.TimePicker.TimeSelector", this.ClientID);
  989. descriptor.AddProperty("date", this.ResolveClientUrl(this.Date.ToString()));
  990. descriptor.AddProperty("hour", this.ResolveClientUrl(this.Hour.ToString()));
  991. descriptor.AddProperty("minute", this.ResolveClientUrl(this.Minute.ToString()));
  992. descriptor.AddProperty("second", this.ResolveClientUrl(this.Second.ToString()));
  993. descriptor.AddProperty("ampm", this.ResolveClientUrl(this.AmPm.ToString()));
  994. return new ScriptDescriptor[] { descriptor };
  995. }
  996. IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
  997. {
  998. ScriptReference reference = new ScriptReference();
  999. if (Page != null)
  1000. reference.Path = Page.ClientScript.GetWebResourceUrl(typeof(MKB.TimePicker.TimeSelector),
  1001. "TimePicker.js.TimeSelector.js");
  1002. return new ScriptReference[] { reference };
  1003. }
  1004. #endregion
  1005. }
  1006. }