This section will walk you through the steps of creating a single survey page and setting up mappers.

First off, if you haven't already, add a reference to Coffee in your web project and add the necessary configuration to web.config

Create the Survey Definition Document

Create an XML file with the following contents and name it doc.xml

<?xml version="1.0" encoding="utf-8" ?>
<pages>
  <page id="1">
    <control type="SurveyQuestionsTable">
      <datamapper name="Page1"></datamapper>
      <configuration>
        <question type="TextBox" id="TextVal">
          <text>This is a TextBox:</text>
        </question>
        <question type="TextBox" id="NumberVal" datatype="integer">
          <text>This is a numeric TextBox:</text>
        </question>
        <question type="YesNo" id="YesNoVal">
          <text>This is a Yes/No radiobutton group:</text>
        </question>
      </configuration>
    </control>
  </page>
</pages>

We will be storing the data in Session variables for this example, here is a simple class to do that:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for SessionDataSource
/// </summary>
public class SessionDataSource
{
	public SessionDataSource()
	{
		//
		// TODO: Add constructor logic here
		//
	}


    public static void Set<T>(string sessionvarname, T value)
    {
        HttpContext.Current.Session[sessionvarname] = value;
    }

    public static T Get<T>(string sessionvarname)
    {
        if (HttpContext.Current.Session[sessionvarname] != null)
        {
            return (T)HttpContext.Current.Session[sessionvarname];
        }
        else
        {
            return default(T);
        }
    }

}

Create a corresponding DataModel and DataMapper

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Coffee.DataModels;

public class Page1 : DataModel 
{
    public string TextVal { get; set; }
    public int? NumberVal { get; set; }
    public bool? YesNoVal { get; set; }

	public Page1()
	{
        // Do not remove, required by GenericMapper to instantiate a generic type
	}

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Coffee;
using Coffee.DataMappers;

/// <summary>
/// Summary description for Page1Mapper
/// </summary>
public class Page1Mapper : SurveyQuestionTableMapper<Page1>
{
    public Page1Mapper()
        : base()
    {
    }

    public override void Load()
    {
        currentAnswer.TextVal = SessionDataSource.Get<string>("Page1TextVal");
        currentAnswer.NumberVal = SessionDataSource.Get<int?>("Page1NumberVal");
        currentAnswer.YesNoVal = SessionDataSource.Get<bool?>("Page1YesNoVal");
    }

    public override void Update()
    {
        SessionDataSource.Set("Page1TextVal", currentAnswer.TextVal);
        SessionDataSource.Set("Page1NumberVal", currentAnswer.NumberVal);
        SessionDataSource.Set("Page1YesNoVal", currentAnswer.YesNoVal);
    }
}

Add a SurveyManager to the page and instantiate it from the XML document

Create a page and add a DIV tag as our SurveyManager instance host and a Save button to trigger the Update method. We also add a DIV to display the answers we selected (to show that they are indeed being saved)

In the ASPX file:
...
<div id="survey" runat="server"></div>
<asp:Button runat="server" ID="btnSave" OnClick="btnSave_Click" Text="Save" />
<div id="answers" runat="server"></div>
...

Now add the following code to your codebehind:

In the codebehind:
    // class fields
    XmlDocument doc = new XmlDocument();
    SurveyManager manager;

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        doc.Load(Server.MapPath("data.xml"));
        // MUST create surveymanager in OnInit, if placed in CreateChildControls, it will be too late
        // to populate viewstate of child controls
        manager = new SurveyManager(doc.SelectSingleNode("pages/page[@id='1']"));
        survey.Controls.Add(manager);
    }

    protected void btnSave_Click(object sender, EventArgs e)
    {
        // save the answers via the mapper
        manager.Update();

        // display the answers
        answers.InnerHtml = "";

        foreach (string key in Session.Keys)
        {
            if (key.StartsWith("Page1"))
            {
                if(Session[key]!=null)
                    answers.InnerHtml += "<li>" + key + " - " + Session[key].ToString() + "</li>";
            }
        }
    }


Note that we instantiated SurveyManager in OnInit, for the reasons specified.

Setting up Global.asax

Finally, we need to add plumbing in the Application_Start event. This involves calling Base.Initialize and registering the DataMapper we created to the mapper factory. Right now we have to do this explicitly for each Mapper we create, but in later revisions this should be done by introspection.


    void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup
        Coffee.Base.Initialize();
        Coffee.DataMapperFactory.RegisterMapper(typeof(Page1Mapper));
    }


The page doesn't do anything exciting, but if you look at what's going on, we have created a set of questions and bound them to Session variables without writing any UI code.

Let's go over how it all comes together in the next section.

Last edited Jul 6, 2012 at 11:43 PM by RupertAvery, version 13

Comments

No comments yet.