|
|
Recently, I checked on a deal from a daily deal site but immediately I noticed the countdown timer. I tried searching to see how the timer is doen but I could not find a simple solution that I like so I decided to experiment on it using jQuery and MVC 3.
My first attempt was to write a jQuery plugin. It will do the necessary time calculations and countdown. While developing the plugin I realized if I only need the code in a sigle page there is no need for plugin. Also since the server need to know the time left anyway I can simplify the solution using the best of both MVC and jQuery. So the solution is to calculate the time left in c-sharp inside the model class, pass than information from MVC controllers to the view page then let the jQuery magic begins.
Let's start with a count down date time model to handle the remaining days, hours, minutes and seconds.
public class CountDownTimerModel
{
public int Day { get; set; }
public int Hour { get; set; }
public int Minute { get; set; }
public int Seconds { get; set; }
public Boolean IsStarted { get; set; }
}
Likely you need a deal page model where you can add the countdown model like the one below
public class DealViewModel
{
public DateTime DealDateStart { get; set; }
public DateTime DealDateEnd { get; set; }
public CountDownTimerModel TimeToEnd
{
get
{
var t = new CountDownTimerModel();
DateTime e = (DateTime)DealDateEnd;
if (DealDateStart > DateTime.UtcNow)
{
e = (DateTime)DealDateStart;
t.IsStarted = false;
}
else
{
t.IsStarted = true;
}
var timeDiff = e.Subtract(DateTime.UtcNow);
t.Day = timeDiff.Days;
t.Hour = timeDiff.Hours;
t.Minute = timeDiff.Minutes;
t.Seconds = timeDiff.Seconds;
return t;
}
}
public String DealStartMessage
{
get
{
if (DealDateStart > DateTime.UtcNow)
{
return "Deal will start soon!";
}
else if (DealDateEnd < DateTime.UtcNow)
{
return "Deal is closed!";
}
return "Deal is ON now!";
}
}
public String DealFrontMessage
{
get
{
if (DealDateStart < DateTime.UtcNow && DealDateEnd > DateTime.UtcNow)
{
return "Deal ends in ";
}
else if (DealDateEnd < DateTime.UtcNow)
{
return "Deal is closed since ";
}
return "Deal will start in ";
}
}
}
In the Controller, we can then have this action method.
public ActionResult Countdown()
{
DealViewModel dl = new DealViewModel();
dl.DealDateStart = DateTime.UtcNow;
dl.DealDateEnd = DateTime.UtcNow.AddMinutes(1);
ViewBag.deal = dl;
return View();
}
/// <summary>
/// This post action method was added to let user submit their own datetime
/// </summary>
/// <param name="dstart"></param>
/// <param name="dend"></param>
/// <returns></returns>
[HttpPost]
public ActionResult Countdown(DateTime dstart, DateTime dend)
{
DealViewModel dl = new DealViewModel();
dl.DealDateStart = dstart;
dl.DealDateEnd = dend;
ViewBag.deal = dl;
return View();
}
Here is a sample view using razor view engine. Notice that I put the days, hours, minutes and seconds in a separate span element. This will simplify the update from jquery.
<h2>
Countdown experiment
</h2>
<div id="TimeToEnd">
<span id="timerMessage">@MvcHtmlString.Create(ViewBag.deal.DealFrontMessage) </span>
<span id="DayLeft">@ViewBag.deal.TimeToEnd.Day</span><span class="fcBlue01">d </span>
<span id="HourLeft">@ViewBag.deal.TimeToEnd.Hour</span><span class="fcBlue01">h
</span><span id="MinuteLeft">@ViewBag.deal.TimeToEnd.Minute</span><span class="fcBlue01">m
</span><span id="SecondsLeft">@ViewBag.deal.TimeToEnd.Seconds</span><span class="fcBlue01">s
</span>
</div>
Now here is the magic in jQuery. This is rather very elementary jQuery codes but
it serves the purpose so let it be this way. Modify it if you want a little more sophisticated.
<script type="text/javascript">
//<![CDATA[
jQuery(document).ready(function () {
// countdown timer
var dealCountdown = setInterval(function () {
var sec = $("#SecondsLeft").text();
var min = $("#MinuteLeft").text();
var hr = $("#HourLeft").text();
var day = $("#DayLeft").text();
--sec;
// Check if the time is over
if (sec == 0 && min == 0 && hr == 0 && day == 0) {
// ADD Callback here if you want - the time is over
$("#timerMessage").html("Time is OVER since ");
clearInterval(dealCountdown);
//===== YOU CAN DELETE FROM HERE IF YOU DO NOT NEED COUNT UP
var dealCountUp = setInterval(function () {
var sec = $("#SecondsLeft").text();
var min = $("#MinuteLeft").text();
var hr = $("#HourLeft").text();
var day = $("#DayLeft").text();
++sec;
countUp(sec, min, hr, day);
}, 1000);
//===== YOU CAN DELETE TO HERE IF YOU DO NOT NEED COUNT UP
}
countDown(sec, min, hr, day);
}, 1000);
// end of document
});
function countDown(sec,min,hr,day) {
if (sec < 0) {
// Start decrement
sec = 59;
--min;
if (min < 0) {
min = 59;
--hr;
if (hr < 0) {
hr = 23;
--day;
$("#DayLeft").text(day);
}
$("#HourLeft").text(hr);
}
$("#MinuteLeft").text(min);
}
$("#SecondsLeft").text(sec);
}
function countUp(sec, min, hr, day) {
if (sec > 59) {
sec = 0;
++min;
if (min > 59) {
min = 0;
++hr;
if (hr > 23) {
hr = 00;
++day;
$("#DayLeft").text(day);
}
$("#HourLeft").text(hr);
}
$("#MinuteLeft").text(min);
}
$("#SecondsLeft").text(sec);
}
//]]>
</script>
In the future blog, I will post another version of image slider plugin. You can use the slide to show multiple images in a deal page.
You can see a live example of the countdown timer here
Summary
In this article you learn a technique how to display a countdown timer using the power of jQuery and MVC. I hope this will help you build your own daily deal website using MVC.