Nibble

Archive for September, 2010

Silverlight for Umbraco Media Objects Intro video 1

This week I got a mail asking me If I would be up for posting a video on this blog, since it’s about umbraco, I’m happy to do so.

So here it is: a short intro video on Project SUMO ( Silverlight for Umbraco Media Objects), featuring some key members from the fabulous umbraco community

In order of appearance:

Silverlight for Umbraco Media Objects is a Silverlight 4 application for managing, editing and uploading images to the media section of an Umbraco installation and is a collaboration between Microsoft Uk and some umbraco community members.

 

More details on SUMO can be found on codeplex http://sumo.codeplex.com/ and on it’s project page on our.umbraco.org http://our.umbraco.org/projects/website-utilities/silverlight-for-umbraco-media-objects-%28sumo%29

Setting up a poll on your umbraco site using Contour 20

Umbraco’s formbuilder Contour is great for adding forms to your website! It doesn’t stop at contact forms and questionnaires, in this post I’ll show you how you can add a poll to your site using Contour.

Step 1: Setting up the form

Using Contour’s slick interface it’s super easy to create the form, simply navigate to the Contour section (if Contour is installed, otherwise first install it from the package repo) and create a new form.

On that new form setup a new field of the type ‘radiobutton list’ and we’ll make this a mandatory field since you’ll have to select an option before you can submit your vote.

image

Once the field is added you can simply setup the different options

image

Once the options are setup simply save the form and you should end with something like this:

image 

Step 2: Displaying the results

Ok now we have a form that will capture the votes. Next we need a way of displaying the results. Contour has some default xslt extensions you can use to fetch the submitted records.

But what I need to do is to first fetch all the different options, for that I’ll just create a custom xslt extensions that just returns some xml that has an overview of all questions and answers on a form

        public static XPathNodeIterator PossibleAnswers(string guid)
        {
            FormStorage fs = new FormStorage();
 
            Form f = fs.GetForm(new Guid(guid));
            fs.Dispose();
 
            XmlDocument d = new XmlDocument();
            XmlNode root = d.CreateElement("questions");
 
            foreach (Field fld in f.AllFields)
            {
 
                if (fld.FieldType.SupportsPrevalues 
                    && fld.PreValueSource.Type.GetPreValues(fld).Count > 0)
                {
                    XmlNode question = d.CreateElement("question");
                    XmlNode caption = d.CreateElement("caption");
 
                    XmlCDataSection questionvalue = d.CreateCDataSection(fld.Caption);
                    caption.AppendChild(questionvalue);
 
                    question.AppendChild(caption);
 
                    XmlNode answers = d.CreateElement("answers");
 
                    foreach (PreValue pv in fld.PreValueSource.Type.GetPreValues(fld))
                    {
                        XmlNode answer = d.CreateElement("answer");
                        XmlAttribute answerId = d.CreateAttribute("id");
                        answerId.Value = pv.Id.ToString();
                        answer.Attributes.Append(answerId);
                        XmlCDataSection value = d.CreateCDataSection(pv.Value);
                        answer.AppendChild(value);
                        answers.AppendChild(answer);
                    }
 
                    question.AppendChild(answers);
                    root.AppendChild(question);
                }
 
            }
 
            d.AppendChild(root);
 
            return d.CreateNavigator().Select(".");
        }

Then we’ll write some xslt that will use this extensions to output a list of questions with their different options. We also need to know how many records have been submitted and how many ‘votes’ each answers has. To see the total number of submitted records for a form we can use the default contour xslt extension umbraco.contour:GetRecordsFromForm(‘form id’) , the total number of votes(records) we can get by counting the records count(umbraco.contour:GetRecordsFromForm(‘form id’)/uformrecord) then the only think left is to count the number of votes each option has…

The end result of the xslt that will output the results:

<xsl:param name="currentPage"/>
 
<xsl:param name="formid" select="/macro//formid" />
    
<xsl:template match="/">
  
    <xsl:if test="$formid">
     <xsl:variable name="records" select="umbraco.contour:GetRecordsFromForm($formid)"/>
     <xsl:variable name="numberOfRecords" select="count($records/uformrecord)" />
    
   <div class="results" style="width:300px">
       <h3>Poll results</h3>
     
     <xsl:for-each select="contourpoll:PossibleAnswers($formid)//question">
    <xsl:variable name="numberOfAnswers" select="count(./answer)" />
       
    <h4><xsl:value-of select="caption"/></h4>
      <ul style="list-style:none;padding-left:0px;margin-left:0px;">
        <xsl:for-each select=".//answer">
      <xsl:sort select="count($records//value [@key = current()/@id])"
                data-type="number" order="descending"/>
 
      <xsl:variable name="currentId" select="@id" />
      <xsl:variable name="currentVotes" select="count($records//value [@key = $currentId])" />
      <xsl:variable name="currentPercentage"
                        select="round (($currentVotes div $numberOfRecords) * 100)"/>
      
      <li>
          <xsl:value-of select="."/>
          <div class="scorebarcontainer" style="width:100%;background-color:#eee;height:20px">
            <div class="scorebar"
                    style="width:{$currentPercentage}%;background-color:#ccc;height:20px">
            </div>
          </div>
      </li>
   </xsl:for-each>
  </ul>
       </xsl:for-each>
    </div>
      
    </xsl:if>
</xsl:template>

 

And how this will look:

image

 

Step 3: Only show form if you haven’t voted yet

Ok so now we have a form that will be used to submit the votes and an xslt macro used to output the results

So depending on if the user has submitted a vote yet we need to show the poll or the results.

So once the user submits the form we’ll set a cookie, and we can do that by hooking into the Contour event model

using System;
using Umbraco.Forms.Core.Services;
 
namespace Contour.Addons.ScoreCalclulator
{
    public class SetCookieOnSubmit: umbraco.BusinessLogic.ApplicationBase {
 
        public SetCookieOnSubmit()
        {
            RecordService.RecordSubmitted +=
                new EventHandler<Umbraco.Forms.Core.RecordEventArgs>(RecordService_RecordSubmitted); 
        }
 
        void RecordService_RecordSubmitted(object sender, Umbraco.Forms.Core.RecordEventArgs e)
        {
            umbraco.library.setCookie(e.Form.Id.ToString(), "1"); 
        }
 
 
    }
}

So this will basically set a cookie with the current submitted form id as key.

Next on the template where we put our poll we just check if that cookie exists.

The pollId is getting pulled from a page property value, on my homepage I have this property:

image

Which will render like this (so the content editor can select the poll he wants to display)

image

On the template instead of simply dropping the form macro I first simply check if there is a poll id and then depending on the cookie show the form macro or the results macro

<%
              
string pollId = umbraco.presentation.nodeFactory.Node.GetCurrent().GetProperty("activePoll").Value;
             
if(!string.IsNullOrEmpty(pollId)){
 
   if (Request.Cookies[pollId] == null) { %>
                    
  <umbraco:Macro FormGuid="[$activePoll]"
                  Alias="umbracoContour.RenderForm" runat="server"></umbraco:Macro>
                   
<% }
 
else {%>
                    
  <umbraco:Macro formid="[$activePoll]"
                 Alias="ContourPollResults" runat="server"></umbraco:Macro>
                   
<% }} %>

 

The Result

 

Download the sourcefiles here

Second round of Umbraco courses in the Benelux 0

Registration just opened for the second round of official umbraco courses, this time held in Ghent, Belgium.

Level 1 is running on 30 November - 1 December and level 2 on 2-3 December.

These are the same courses taught throughout the world and will teach you everything you need to know to attain your Umbraco Certification (including new umbraco 4.5 functionality, the new xml schema,Linq 2 umbraco, Examine,…).

Secure your seat today!
http://umbraco.org/training/training-in-benelux