Hopefully your not getting bored yet! We are almost there now
with this tutorial, we just have a few things left. In case
you have come into this tutorial half way through you can find the
other previous posts here
And this is what we have covered, and what we have left to cover
in the next few posts - This one will concentrate on the Submit
Button and the Submission Form using the API.
Overview
Setup (Local Development & Visual
Studio)
HTML / CSS / Templates
Razor
Existing Packages To Use
Main Navigation
DocTypes
Main Category Navigation
Sub Category
Listing Pages
Listing & Category Counts
- Submit Button
- Submission Form (API)
- Submission Form (Contour)
- Final Tweaks (Paging, Suggestions etc…)
Submit Button
So lets get started with the submit button, obviously we have a
directory that we want people to submit businesses to - But at the
the moment we don't have a submit button. We could just
create a page called 'Submit' and let the navigation Macro take
care of adding the submit link/button in the nav.
But in this case, we want the submit button to pass the actual
'Category ID' of the category that the user wants to submit their
business into. To make this easier for us, we are going to
create a submit button/link that only shows when the user is in a
valid 'BusinessCategory' and appends the Id to the
link so we can use it on the submit form.
Firstly to do this, we'll create a 'TextPage'
called 'Submit' as we'll be adding the form to this page via a
Macro which we'll allow to be used in the RTE. Once you have
this page, go to the properties tab and and TICK 'Hide In
Navi' so it doesn't appear in the navigation straight away
and also get the node ID as we'll use this in a minute.



Head over to Visual Studio, but this time instead of creating a
new Razor file for this we are going to update the
'Navigation' file to include our link. So
open up your 'Navigation.cshtml' file and after
the end of the foreach loop add in the following piece of code
(Replacing the node id in with your submit node id in the NiceUrl()
method).
@if (Model.NodeTypeAlias == "BusinessCategory")
{
<li><a
href="@string.Concat(umbraco.library.NiceUrl(1068), "?n=",
Model.Id)">Submit</a></li>
}
All this is doing is checking the current page has a docType of
'BusinessCategory' and if it does display a link
to the submit page, but append the category node id as a query
string. Save the file and build the solution, now open the
home page of the site and you'll see no change, but browse to one
of your categories and you'll see your new submit button.

Submission Form (API)
I'm not going to cover this part in much detail, I'm just going
to paste some code below to show you how you can use either the API
or contour to submit the businesses - But we'll concentrate on
using Contour in more detail in the next post and look at things
like email notification/workflows. To do this form using the
API just create a usercontrol called 'SubmitForm'
in your 'usercontrol' folder in VS and copy and
paste the code below.
Before you do this you will need to add an extra reference to
your solution I forgot in the first post and also add another field
to the business listing - The reference I forgot was the
'cms.dll' and add a new property to
capture the users email address on the
'BusinessListing' docType shown below

The code for the usercontrol is:
.ascx
<asp:Literal ID="litStatus" runat="server" />
<fieldset runat="server" id="submitbusinessform">
<legend>Business Details</legend>
<asp:ValidationSummary ID="ValidationSummaryText"
runat="server"
ForeColor=""
CssClass="errorMessage"
HeaderText="Please review the following errors:" />
<ul class="normalform">
<li>
<label for="tbTitle">Business:</label>
<asp:TextBox ID="tbTitle" runat="server" Width="300" MaxLength="60" ClientIDMode="Static" />
</li>
<li>
<label for="tbURL">URL:</label>
<asp:TextBox ID="tbURL" runat="server" Text="http://" Width="300" MaxLength="100" ClientIDMode="Static" />
</li>
<li>
<label for="tbDescription">Description:</label>
<asp:TextBox ID="tbDescription" runat="server" Width="300" TextMode="MultiLine" Rows="5" MaxLength="300" ClientIDMode="Static" />
</li>
<li>
<label for="tbName">Name:</label>
<asp:TextBox ID="tbName" runat="server" Width="300" MaxLength="100" ClientIDMode="Static" />
</li>
<li>
<label for="tbPhone">Phone:</label>
<asp:TextBox ID="tbPhone" runat="server" Width="300" MaxLength="100" ClientIDMode="Static" />
</li>
<li>
<label for="tbEmail">Email: </label>
<asp:TextBox ID="tbEmail" runat="server" Width="300" MaxLength="100" ClientIDMode="Static" />
</li>
<li>
<asp:Button ID="SubmitButton" runat="server" Text="Submit Listing" onclick="SubmitButtonClick" />
</li>
</ul>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" Display="None" ErrorMessage="Title Required" ControlToValidate="tbTitle" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" Display="None" ErrorMessage="URL Required" ControlToValidate="tbURL" InitialValue="http://" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" Display="None" ErrorMessage="Description Required" ControlToValidate="tbDescription" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" runat="server" Display="None" ErrorMessage="Name Required" ControlToValidate="tbName"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1"
runat="server" ErrorMessage="Invalid Email Address" Display="None"
ControlToValidate="tbEmail"
ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
</asp:RegularExpressionValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" runat="server" Display="None" ErrorMessage="Email Required" ControlToValidate="tbEmail"></asp:RequiredFieldValidator>
</fieldset>
.cs
using System;
using System.Web.UI;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
namespace Umbraco_Business_Directory.usercontrols
{
public partial class SubmitForm : UserControl
{
private int? _n;
protected void Page_Load(object sender, EventArgs e)
{
// get a valid category id
if (Request.QueryString["n"] != null)
_n = Convert.ToInt32(Request.QueryString["n"]);
// Check if we have a category id
CheckForNodeId();
}
private void CheckForNodeId()
{
if (_n != null) return;
submitbusinessform.Visible = false;
litStatus.Text = "Please navigate to a category and click the submit button to submit your business";
return;
}
protected void SubmitButtonClick(object sender, EventArgs e)
{
CheckForNodeId();
// Create a user
var u = new User(0);
// Create the listing but don't publish it
var t = Document.MakeNew(tbTitle.Text, DocumentType.GetByAlias("BusinessListing"), u, (int)_n);
// Add the document properties
t.getProperty("businessDescription").Value = tbDescription.Text;
t.getProperty("businessUrl").Value = tbURL.Text;
t.getProperty("businessPhoneNo").Value = tbPhone.Text;
t.getProperty("businessContactName").Value = tbName.Text;
t.getProperty("businessEmail").Value = tbEmail.Text;
// Show a message to user
litStatus.Text = "Business Submitted, once reviewed it will be live on the site";
// Hide now finished
submitbusinessform.Visible = false;
}
}
}
Save and build the solution, we now need to create a macro for
the form. Create a macro as you have done for the razor files
called 'Submit Form', but instead of selecting from the script file
dropdown select the form from the .NET usercontrols dropdown.
Also on this Macro CHECK the tickbox 'Use
In Editor' and UNCHECK 'Render
Content In Editor'

Save the Macro and go to the content section and click on the
Submit page you created earlier. Click on the RTE and select
insert Macro, and select your 'Submit Form' and click insert and
then 'Save & Publish' the page

Now browse to a category and click the submit button, you should
see the form below

Fill out the form with a test business and submit it to make
sure its all working, the form does the following
- Checks to make sure we have a category id, if not hides the
form and displays a message
- Does some basic validation on the fields
- Submits the business to Umbraco creating an
UNPUBLISHED 'BusinessListing' node under the
chosen category


This then allows you to login to Umbraco and either publish this
listing or delete it depending on what your submission criteria
is. If you do choose to go down this route and use the API
and not use Contour (Which we will cover in the next post) then you
will need to make sure you validate all the fields properly in this
form. As at the moment its just dumping the content into the
database, its not running through an XSS validator
or some other nasty checker.
You might also want to add in email notification to let you know
when someone submits, all this we will cover in the next post using
Contour as a submission form.