poll episerver new forms

How to render choice element results as poll percentage

New Episerver forms => polls guide

Using this quick-guide might save you some time to create polls using new Episerver Forms. It requires some customization for a specific use-case, but gives a good idea on how to get started.

Say that you have a multiple choice element that you'd like to render results of in a poll.

This is the poll model I'd like to display:
 
public class PollAnswer
{
	public int Percent { get; set; }
	public string Answer { get; set; }

	public string AnswerPercentage
	{
		get { return string.Format("{0} ({1}%)", Answer, Percent); }
	}
}

public class PollModel
{
	public List Answers { get; set; }
	public FormContainerBlock PollBlock { get; set; }

	public bool ShowAnswers
	{
		get { return Answers != null && Answers.Any(); }
	}

	public bool ShowPoll
	{
		get { return PollBlock != null; }
	}
}

This is the code to get the answers, it gives some clues on the following:

  • How to get ChoiceElementBlock items from the form elements
  • How to get result form results
  • How to check if logged in user has voted already
  • How to get the actual answers in percentages
public static PollModel GetPoll(FormContainerBlock form)
{
	if (form == null) return new PollModel();

	var choices = (from filteredItem in form.ElementsArea.FilteredItems
				   let selectItem = filteredItem.GetContent() as ChoiceElementBlock
				   where selectItem != null
				   select selectItem).FirstOrDefault();

	if (choices == null) return new PollModel();

	var formDataRepository = ServiceLocator.Current.GetInstance();

	var data = formDataRepository.GetSubmissionData(
		new FormIdentity((form as IContent).ContentGuid, (form as ILocalizable).Language.Name),
		(form as IChangeTrackable).Created,
		DateTime.MaxValue).ToList();

	var currentUserName = PrincipalInfo.Current.Name;
	// if the poll is for logged in users, we could check if the user already voted
	// I left this for the sake of example (there are several built-in columns in EPiServer.Forms.Constants)
	var voted = (!string.IsNullOrEmpty(currentUserName) &&
		data.Any(x => x.Data[EPiServer.Forms.Constants.SYSTEMCOLUMN_SubmitUser].ToString().Equals(currentUserName)));

	var answers = (from item in choices.Items
				   let resultItem = data.Where(cd => (string)cd.Data[choices.FormElement.ElementName] == item.Value).ToList()
				   select new PollAnswer
				   {
					   Answer = item.Caption,
					   Percent = resultItem.Any() ? resultItem.Count() * 100 / data.Count : 0,
				   }).ToList();


	var viewModel = new PollModel
	{
		Answers = answers,
		PollBlock = form
	};

	return viewModel;
}

With some nice CSS, the poll is ready! Then, you might fine tune it with some buttons that toggle between the form and the answers, but I wanted to keep this short and simple.

comments powered by Disqus