Børre Stenseth
Moduler>Websites>Kalender

Kalender

Hva
Image1
En svært enkel interaktiv kalender

En svært enkel kalender som holder styr på uformaterte data for hver dag. Det lages en XML-fil for hver måned. Data for hver dag i måndeden lagres som en CDATA- seksjon under et element day. Selve kalenderen er en standardkontroll som er lagt til og formatert i Visual Studio.

En datafil kan se slik ut:

<?xml version="1.0"?>
<days>
  <day number="7">
  <![CDATA[dette er en mandag som alle andre]]>
  </day>
</days>

Denne måten å lagre data på er neppe optimal, men den er enkel og lett inspiserbar i den forstand at vi kan lese datafiler i allminnelige teksteditorer.

Koden

Koden er slik, Default.aspx.cs,

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

public partial class _Default : System.Web.UI.Page 
{
    DateTime actualDate;
    String EMPTY = "ingen notater";
    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = "";
        if (!this.IsPostBack)
            Calendar1.SelectedDate = DateTime.Now;
        actualDate = Calendar1.SelectedDate;
    }
    protected void TextBox1_Load(object sender, EventArgs e)
    {
        if(!this.IsPostBack)
            TextBox1.Text = LoadNote(actualDate);
    }
    protected void ButtonUpdate_Click(object sender, EventArgs e)
    {
        try{
            SaveNote(actualDate, TextBox1.Text);
        }
        catch (System.Web.HttpRequestValidationException ex)
        {
            Label1.Text = ex.Message;
        }
    }
    
    protected void Calendar1_SelectionChanged(object sender, EventArgs e)
    {
        Label1.Text = "";
        actualDate = Calendar1.SelectedDate;
        TextBox1.Text = LoadNote(actualDate);        
    }
    protected void Calendar1_VisibleMonthChanged(object sender, 
        MonthChangedEventArgs e)
    {
        actualDate = e.NewDate;
        Calendar1.SelectedDate = actualDate;
        TextBox1.Text = LoadNote(actualDate);
    }
    // find file for month
    protected String getFilename(DateTime d)
    {
        return String.Format(@"{0}\App_Data\{1}{2}.xml",
                           Path.GetDirectoryName(Request.PhysicalPath),
                           Convert.ToString(d.Year), 
                           Convert.ToString(d.Month));
    }
    // load the note for one day
    protected String LoadNote(DateTime d)
    {
        String filename = getFilename(d);
        FileInfo source = new FileInfo(filename);
        if (source.Exists)
        {
            // load this months file and parse it
            XmlDocument doc = new XmlDocument();
            try
            {
                doc.Load(filename);
                XmlNodeList list = doc.GetElementsByTagName("day");
                foreach (XmlElement p in list)
                    if (Convert.ToInt16(p.GetAttribute("number"))==d.Day)
                        return p.InnerText;
            }
            catch (Exception ex)
            {
                // errormessage in the label
                Label1.Text = ex.Message;
                return "";
            }
        }
        // no note exist:
        return EMPTY;
    }
    // save the note for one day
    protected void SaveNote(DateTime d,String content)
    {
        if(content.CompareTo(EMPTY)==0)
            return;
        
        String filename = getFilename(d);
        FileInfo source = new FileInfo(filename);
        XmlDocument doc = new XmlDocument();
    
        try
        {
            if (source.Exists)
            {
                // load it, parse it and update text                
                doc.Load(filename);
                XmlNodeList list = doc.GetElementsByTagName("day");
                Boolean done = false;
                for (int ix = 0; (ix < list.Count) && (!done); ix++)
                {
                    XmlElement p = (XmlElement)list.Item(ix);
                    if (Convert.ToInt16(p.GetAttribute("number")) == d.Day)
                    {
                        p.InnerXml = 
                            String.Format(@"<![CDATA[{0}]]>", content);
                        done = true;
                    }
                }
                if (!done)
                {
                    // create and insert a new day-element
                    XmlElement e=doc.CreateElement("day");
                    e.SetAttribute("number", Convert.ToString(d.Day));
                    e.AppendChild(doc.CreateCDataSection(content));
                    doc.DocumentElement.AppendChild(e);
                }
            }
            else
            {
                // create new file content
                String s = 
                    String.Format(@"<?xml version=""1.0""?>
                                    <days>
                                        <day number=""{0}"">
                                            <![CDATA[{1}]]>
                                        </day>
                                    </days>", 
                                    Convert.ToString(d.Day), content);
                doc.LoadXml(s);
            }
            doc.Save(filename);
        }
        catch (Exception ex)
        {
            // errormessage
            Label1.Text = ex.Message;
            return;
        }
    }
}

IsPostBack

Merk egenskapen IsPostBack. Dersom denne er false betyr det at siden hentes for "første gang". Det er altså ikke returen i en round-trip. Det er derfor nyttig å bruke denne egenskapen for å avgjøre om vi skal sette initielle verdier i feltene på vevside. I dette tilfelle betyr en slik initialisering at vi setter dagens dato, DateTime.Now, som valgt dato.

Vevsiden

Koden ser slik ut:

_Default.aspx

Alle stildata for selve kalenderkontrollen er satt av Visual Studio på grunnlag av en valgt autoformattering.

Merk sideattributten ValidateRequest="false". Dette skrur av testing på om noe av det vi sender potensielt kan være en sikkerhetsrisiko. Kanskje ikke så lurt å skru den av, men det muliggjør at vi skriver "hva som helst" i teksten.

Du kan teste den herhttp://donau.hiof.no/borres/dn/WCalendar/

Hvis du kjører eksempelet så se på kildekoden og se hvordan denne skiller seg fra den aspx-fila vi plasserer på tjeneren. Se spesielt hvordan selve kalenderen er representert og hvordan data sendes tilbake til tjeneren med Javascriptfunksjonen __doPostBack().

Eventuelle data som blir laget ved testing, blir fjernet ved ujevne mellomrom.

Referanser
Prosjekt:
https://svn.hiof.no/svn/psource/Csharpsites/WCalendar
Vedlikehold

B.Stenseth, revidert juni 2006

(Velkommen) Moduler>Websites>Kalender (Verden)