den 22 oktober 2009
av
Fredrik Sewen
Umbraco har redan en Datatype som är en Date-picker, men rent
grafiskt är den långt ifrån lika snygg som den som finns
tillgänglig genom jQuery UI. Därför bestämde jag mig för att skapa
en ny jQuery datatype.
Innan du läser det här bör du känna till lite om hur man skapar
Datatypes i Umbraco. Om du inte känner till hur man gör, kan du
läsa en Nibbles blogginlägg om det.
Vi börjar med att skapa klasserna
Vårt projekt kommer bestå av två klasser.
Först har vi vår Datatype-klass som ärver från
umbraco.cms.businesslogic.datatype.BaseDataType och
umbraco.interfaces.IDataType. Det är den här klassen som kommer
hantera de olika event som Umbraco kallar på.
Den andra klassen ärver från System.Web.UI.WebControls.TextBox
och umbraco.interfaces.IDataEditor. Det är vår webcontrol, den som
rent grafiskt kommer genereras för användaren.
OBS! I Nibbles blogginlägg nämner han tre
klasser. Den tredje klassen är en Prevalue-klass som tillåter att
man gör inställningar till sin Custom Datatype. Vi kommer använda
oss av Umbracos DefaultPrevalueEditor istället.
Skapa Datatype-klassen jQueryDatePicker.cs
using System;
using System.Collections.Generic;
using System.Text;
using umbraco.editorControls;
namespace B7.Umbraco.DataTypes
{
public class jQueryDatePicker : umbraco.cms.businesslogic.datatype.BaseDataType, umbraco.interfaces.IDataType
{
#region Abstract members
private umbraco.interfaces.IDataEditor _Editor;
private umbraco.interfaces.IData _baseData;
private umbraco.interfaces.IDataPrevalue _prevalueeditor;
public override umbraco.interfaces.IDataEditor DataEditor
{
get{
if (_Editor == null)
_Editor = new jQueryDatePickerEditor(Data);
return _Editor;
}
}
public override umbraco.interfaces.IData Data
{
get
{
if (_baseData == null)
_baseData = new umbraco.cms.businesslogic.datatype.DefaultData(this);
return _baseData;
}
}
public override Guid Id
{
get { return new Guid("71518B3E-B1A5-11DD-A22C-8AAA56D89593"); }
}
public override string DataTypeName
{
get { return "jQuery Date picker"; }
}
public override umbraco.interfaces.IDataPrevalue PrevalueEditor
{
get
{
if (_prevalueeditor == null)
_prevalueeditor = new DefaultPrevalueEditor(this, false);
return _prevalueeditor;
}
}
#endregion
}
}
När vi implementerar koden ovan är det två saker som är
bra att känna till.
public override Guid Id
{
get { return new Guid("71518B3E-B1A5-11DD-A22C-8AAA56D89593"); }
}
Det Guid som står här måste vara unikt för din specifika
Datatype. Lättaste sättet att skapa en ny guid är att googla efter
"Guid Generator".
public override string DataTypeName
{
get { return "jQuery Date picker"; }
}
Det namn som kommer visas i Umbraco när du väljer din datatype
är det som står här.
Om vi testar att bygga projektet nu, kommer vi få ett
Build-error. Det beror på att vi har sagt att vår Editor är av
typen jQueryDatePickerEditor och den har vi inte skapat ännu. Så
det blir nästa steg.
Skapa Datatype-klassen jQueryDatePickerEditor.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
namespace B7.Umbraco.DataTypes
{
public class jQueryDatePickerEditor : System.Web.UI.WebControls.TextBox, umbraco.interfaces.IDataEditor
{
private umbraco.interfaces.IData _data;
public jQueryDatePickerEditor(umbraco.interfaces.IData Data)
{
_data = Data;
}
public virtual bool TreatAsRichTextEditor
{
get { return false; }
}
public bool ShowLabel
{
get { return true; }
}
public Control Editor { get { return this; } }
public void Save()
{
try {
if (this.Text == String.Empty)
throw new FormatException();
DateTime date = DateTime.Parse(this.Text);
_data.Value = date;
}
catch {
this.Text = "";
_data.Value = null;
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (_data != null && _data.Value != null && _data.Value.ToString() != "")
this.Text = _data.Value.ToString();
string functionlimit = "$(function() {"
+ "$('#" +this.ClientID +"').datepicker({"
+ "changeMonth: true,"
+ "changeYear: true,"
+ "yearRange: '-150:+0',"
+ "maxDate: '+0D',"
+ "firstDay: 1,"
+ "hideIfNoPrevNext: true,"
+ "defaultDate: new Date(1980, 0, 1)"
+ "});"
+ "});";
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "jQueryDatePicker", functionlimit, true);
}
}
}
I konstruktorn i vår editor skickar vi med Data, som är datan
för det Content som innehåller vår Datatype. Det kommer vi utnyttja
i vår Save()-metod där vi först kollar att vår sträng i textfältet
är korrekt formaterad, och sedan sparar den till datan.
I OnInit-metoden börjar vi med att kolla om det redan finns
någon data sparad för vår datatype. Om det finns det så sätter vi
det värdet till vårt text-fält (kom ihåg att vi ärver från TextBox
och därför själva har en text).
String functionlimit är det script som kallar på jQuery
datepicker, med inställningar som vi valt här.
Den sista raden i OnInit är när vi registrerar scriptet till vår
ScriptManager. För att scriptet ska fungerar krävs tre saker
- Vi måste ha en scriptmanager på sidan.
- Vi måste ha jQuery
- Vi måste ha jQuery UI med Datepicker
Slutsats
För att Datatypen ska dyka upp i Umbraco är allt som behövs en
referens från ditt Umbraco-projekt till din datatype (alternativt
kopiera den till din bin-katalog om du kör ett enkelt
webb-projekt).
Svårare än så är det inte att skapa en Custom Datatype i
Umbraco. Det här är en enkel variant, och det finns många
förbättringar man kan tänka sig. Bl.a. att sätta alla inställningar
till Datepicker som prevalue-editor. Man kan även tänka sig att man
borde ha några fler valideringar som försäkrar sig om att det finns
en scriptmanager och att alla script som är nödvändiga är
installerade. Men, den här datatypen täckte mina behov, och därför
lät jag den vara som den är.