24 August 2009
jQuery FullCalendar and ASP.NET MVC
Recently I had to integrate jQuery FullCalendar into ASP.NET MVC application. Up to now I was not able to find such an example, so I will try to provide one. I assume that you are familiar with ASP.NET MVC, jQuery and FullCalendar component, so I’m not going to introduce each technology.
Then we need to reference the files we just added to our project. I will do it by placing the following lines of code inside the <head> section of Site.Master file:
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<link href="../../Content/fullcalendar.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script src="../../Scripts/fullcalendar.js" type="text/javascript"></script>
</head>
Now we are ready to use the calendar routines inside our views. How to do it? Just create a div tag and render the calendar’s HTML code inside. Here is how to modify Home’s Index.aspx:
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
$(document).ready(function() {
$('#calendar').fullCalendar({
events: "/Home/CalendarData"
});
});
</script>
<div id="calendar">
</div>
</asp:Content>
The code above will render the calendar’s HTML inside a div with id=”calendar”. The calendar data will be delivered by invoking the following URL: /Home/CalendarData. This corresponds to CalendarData method from the Home controller. This controller is supposed to return the data in Json format. Here is a sample implementation:
[HandleError]
public class HomeController : Controller
{
public ActionResult CalendarData()
{
IList<CalendarDTO> tasksList = new List<CalendarDTO>();
tasksList.Add(new CalendarDTO
{
id = 1,
title = "Google search",
start = ToUnixTimespan(DateTime.Now),
end = ToUnixTimespan(DateTime.Now.AddHours(4)),
url = "www.google.com"
});
tasksList.Add(new CalendarDTO
{
id = 1,
title = "Bing search",
start = ToUnixTimespan(DateTime.Now.AddDays(1)),
end = ToUnixTimespan(DateTime.Now.AddDays(1).AddHours(4)),
url = "www.bing.com"
});
return Json(tasksList);
}
private long ToUnixTimespan(DateTime date)
{
TimeSpan tspan = date.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0));
return (long)Math.Truncate(tspan.TotalSeconds);
}
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
The code above creates two calendar entries called “Google search” and “Bing search”. Everything should be pretty simple, except the stuff around ToUnixTimespan routine.
There is well known problem with serialization of dates in Json format. There is no strict standard, so there are several approaches to this problem. For example, take a look here. The implementation adopted by Microsoft was not recognized by FullCalendar, so I had to introduce the ToUnixTimespan routine. Basically, this routine returns the seconds after 1/1/1970.
Because of the above, you should notice that the start and end dates are represented as int:
public class CalendarDTO
{
public int id { get; set; }
public string title { get; set; }
public long start { get; set; }
public long end { get; set; }
public string url { get; set; }
}
If you have done everything correct, the final result will be
Enjoy!
21 June 2007
Anti-development methodologies
Enjoy!
27 April 2007
BrainStorm Rocks
Our project with the code name Bookvar will compete in the finals this year in Seoul, Korea. This was possible, because of the remarkable team I'm part of. Right now I can't find appropriate words to describe them, but as one of the jury said: "I had the chance to watch these young motivated and smart people". It's a great pleasure to work with each one of them.
Although we managed to win the local round, there is still much work to be done. Lucky for us, the finals are after 3 months.
Check out this post from Ruslan Trifonov if you want to see some pictures from the event. Ruslan was member of the jury.
13 March 2007
Grand Prix Racing Online
There are some interesting issues about the implementation and hosting, but because of security I can not share them.
Good luck Vlado, and continue with the great job.
12 March 2007
NHibernate and triggers
[NHibernate.AdoNet.TooManyRowsAffectedException] {"Unexpected row count: 2; expected: 1"} NHibernate.AdoNet.TooManyRowsAffectedException
After a quick investigation the problem was obvious - the exception raises when a row from a table is updated and the row has fired a trigger which executes an update statement.
I have faced with this problem since early beta of NHibernate (0.8.4 as far as I can remember). Till now the only solution I have found is to use SET NOCOUNT to stop the message that shows the number of rows affected by a Transact-SQL statement from being returned as part of the results.
Just place SET NOCOUNT ON before the UPDATE statement inside the trigger and then after the UPDATE statement place SET NOCOUNT OFF. This will solve the problem.
ASP.NET Web Part editor in pop-up dialog
20 December 2006
First Bulgarian .NET Book is here
17 November 2006
Windows Forms data binding and notification of changed properties
Yesterday a college of mine asked me a question: "How to refresh TextBox control in Windows forms application binded to a property of object, when the property change its value?". The solution is very simple, but according to me not very well documented (at least in books I read).
Solution: Provide event named PropertyNameChanged, where PropertyName is the name of property binded to the TextBox. During the binding process, the text box inspects binded object for event with the mentioned signature and binds to it. The sample code looks like this:
public class Customer
{private string mName;
public string Name
{get { return mName; }
set { mName = value;if (NameChanged != null)
{NameChanged(this, EventArgs.Empty);
}
}
}
public event EventHandler NameChanged;
}
Customer cust = new Customer();textBox1.DataBindings.Add("Text", cust, "Name");
11 September 2006
Cool conference in Bulgaria
Google toolbar 4
The other features I like are SpellCheck and Translate. If you are inspired, install the toolbar from here for WinXP and IE. Enjoy!
04 September 2006
ADO.NET Entity Framework ContextObject and ASP.NET application
The idea is simple: Context object will be stored in ASP.NET session and after the request HTTPModule will free it. I'm using ASP.NET session instead of ASP.NET context to further extend this example to support session per application transaction strategy. If you are wondering what is "session per application transaction" take a look at NHibernate session management. Here is the code of the implementation:
public class ContextManager<T>where T: ObjectContext, new()
{public static T ObjectContext
{ get {T resultContext;
if (HttpContext.Current.Items.Contains(
ContextConst.CONTEXT_OBJECT_SESSION_KEY)) {resultContext =
(T)HttpContext.Current.Items[ ContextConst.CONTEXT_OBJECT_SESSION_KEY];}
else { resultContext = new T();HttpContext.Current.Items[ContextConst.CONTEXT_OBJECT_SESSION_KEY] =
resultContext;
}
return resultContext;}
}
public static bool isActiveObjectContext
{ get { return HttpContext.Current.Items.Contains(
ContextConst.CONTEXT_OBJECT_SESSION_KEY);}
}
}
public class ContextHttpModule : IHttpModule
{ #region IHttpModule Memberspublic void Init(HttpApplication context)
{context.EndRequest += new EventHandler(OnEndRequest);
}
public void Dispose()
{ //Intentionaly not implemented}
public void OnEndRequest(Object sender, EventArgs e)
{if (HttpContext.Current.Items.Contains(ContextConst.CONTEXT_OBJECT_SESSION_KEY))
{ ObjectContext contextObject = (ObjectContext)HttpContext.Current.Items[
ContextConst.CONTEXT_OBJECT_SESSION_KEY];contextObject.Dispose();
}
}
#endregion}
internal class ContextConst
{public const string CONTEXT_OBJECT_SESSION_KEY =
"ContextConst.CONTEXT_OBJECT_SESSION_KEY";}
Now, lets look how the code above can be used. First lets make some corrections to web.config file:
<connectionStrings>
<add name="Duwamish7Model.Duwamish7"
connectionString="metadata=C:\Temp\ContextObject\Model;
mapping=C:\Temp\ContextObject\Model; provider=System.Data.SqlClient;provider connection string="Data Source=ns-server;
Initial Catalog=Duwamish7;Integrated Security=True""
providerName="System.Data.Mapping" />
</connectionStrings>
<httpModules>
<add name="ContextObjectManager"
type="ObjectContextManager.ContextHttpModule, ObjectContextManager"/>
</httpModules>
Duwamish7 db = ContextManager<Duwamish7>.ObjectContext;
Query<Authors> query = db.GetQuery<Authors>(
"SELECT VALUE a FROM Authors AS a WHERE a.PKId > 144");Repeater1.DataSource = query;
Repeater1.DataBind();
P.S. The code above is not tested for concurrency problems.
|
|