(VB) DNN 5 module development tutorial - part 5: The edit control

5. June 2010 15:12

To C# version

This time we are going to create ourselves an edit control. We start with the markup, so open EditProducts.ascx. Make it look like this:

<%@ Control language="vb" Inherits="SipidCode.Modules.Products.EditProducts" AutoEventWireup="false" Explicit="True" Codebehind="EditProducts.ascx.vb" %>
<%@ Register TagPrefix="dnn" TagName="TextEditor" Src="~/controls/TextEditor.ascx"%>
<table width="650" border="0" summary="Edit Product Item">
 <tr>
  <td width="75">Name</td>
  <td><asp:TextBox ID="Name" runat="server"></asp:TextBox></td>
 </tr>
 <tr>
  <td>Description</td>
  <td><dnn:TextEditor ID="Description" runat="server" height="200" width="510" /></td>
 </tr>
</table>
<p>
    <asp:linkbutton cssclass="CommandButton" id="cmdUpdate" resourcekey="cmdUpdate" runat="server" borderstyle="none" text="Update" OnClick="cmdUpdate_Click"></asp:linkbutton>&nbsp;
    <asp:linkbutton cssclass="CommandButton" id="cmdCancel" resourcekey="cmdCancel" runat="server" borderstyle="none" text="Cancel" causesvalidation="False" OnClick="cmdCancel_Click"></asp:linkbutton>&nbsp;
    <asp:linkbutton cssclass="CommandButton" id="cmdDelete" resourcekey="cmdDelete" runat="server" borderstyle="none" text="Delete" causesvalidation="False" OnClick="cmdDelete_Click"></asp:linkbutton>&nbsp;
</p>

Open EditProducts.ascx.vb. In the region “Private Members” the class variable ItemId is declared. This is where we store the ID of the product item to edit.
Insert the following code into the empty Page_Load method (we deleted the method body in the previous part, remember?):

If Not (Request.QueryString("ItemId") Is Nothing) Then
 ItemId = Integer.Parse(Request.QueryString("ItemId"))
End If

Now we have the product item ID in the ItemId variable, if supplied. If there was no ItemId parameter in the query string this means that we should create a new item instead of editing an existing one.

Add the following code:

If Not IsPostBack Then
 If Not Null.IsNull(ItemId) Then
  cmdDelete.Attributes.Add("onClick", "javascript:return confirm('" + Localization.GetString("DeleteItem") + "');")

  Dim dc As New ProductsController
  Dim itm As ProductsInfo = dc.GetProduct(ModuleId, ItemId)

  If Not itm Is Nothing Then
   Name.Text = itm.Name
   Description.Text = itm.Description
  Else
   Response.Redirect(Globals.NavigateURL(), True)
  End If
 Else
  cmdDelete.Visible = False
 End If
End If

This only has to be done the first time the page is loaded so we wrap it in a check for IsPostBack. In the case when an ItemId is supplied we add some client script to get a confirmation when deleting an item. Then we fetch the product item with the current module ID and item ID as keys and populate the controls. If there is no matching item, something must be wrong. In that case we redirect the heck out of there, back to the view page.
When an ItemId is not supplied, this means we should create a new item. Just hide the Delete button.

Error handling is always a good thing, so wrap everything in Page_Load in a try-catch. The Page_Load method should now look something like this:

Protected Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 Try
  If Not (Request.QueryString("ItemId") Is Nothing) Then
   ItemId = Integer.Parse(Request.QueryString("ItemId"))
  End If

  If Not IsPostBack Then
   If Not Null.IsNull(ItemId) Then
    cmdDelete.Attributes.Add("onClick", "javascript:return confirm('" + Localization.GetString("DeleteItem") + "');")

    Dim dc As New ProductsController
    Dim itm As ProductsInfo = dc.GetProduct(ModuleId, ItemId)

    If Not itm Is Nothing Then
     Name.Text = itm.Name
     Description.Text = itm.Description
    Else
     Response.Redirect(Globals.NavigateURL(), True)
    End If
   Else
    cmdDelete.Visible = False
   End If
  End If
 Catch ex As Exception
  Exceptions.ProcessModuleLoadException(Me, ex)
 End Try
End Sub

The error handling code displays an error message to the user, which is enough for us right now.

Go through all three of the Click event handlers and make sure they are marked as Protected and not Private.

Insert the following as method body for cmdCancel_Click:

Response.Redirect(Globals.NavigateURL(), True)

Next in line is the implementation of cmdUpdate_Click. Basically we check if we got an ItemId or not and thereby decide if we should update an existing item or create a new one.
cmdUpdate_Click should look like this:

Protected Sub cmdUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cmdUpdate.Click
 Try
  Dim controller As New ProductsController
  Dim productItem As New ProductsInfo

  productItem.ModuleId = ModuleId
  productItem.ItemId = ItemId
  productItem.Name = Name.Text
  productItem.Description = Description.RichText.Text

  If Null.IsNull(ItemId) Then
   controller.AddProduct(productItem)
  Else
   controller.UpdateProduct(productItem)
  End If
  Response.Redirect(Globals.NavigateURL(), True)
 Catch ex As Exception
  Exceptions.ProcessModuleLoadException(Me, ex)
 End Try
End Sub

One thing to note about the code above is how we pull the content from the Description TextEditor control. If you use Description.Text you will get the HTML encoded content (“<” is converted to “&lt;” and so on) which is not what you want in this case. Use Description.RichText.Text and you will get the raw markup.

The last event handler is cmdDelete_Click. If we have an ItemId then we delete the corresponding product item from the database. Simple as that. cmdDelete_Click should look like this:

Protected Sub cmdDelete_Click(ByVal sender As Object, ByVal e As EventArgs) Handles cmdDelete.Click
 Try
  If Not Null.IsNull(ItemId) Then
   Dim controller As New ProductsController
   controller.DeleteProduct(ModuleId, ItemId)
  End If
  Response.Redirect(Globals.NavigateURL(), True)
 Catch ex As Exception
  Exceptions.ProcessModuleLoadException(Me, ex)
 End Try
End Sub

 With that done, compile the project to make sure everything is ok. Then log in as host in your DotNetNuke website. Now we’re going to add our brand new edit control to the Products module. Go to Host > Module Definitions. Locate the Products row in the list and click the edit icon.

Products module definition row

Scroll down to the section Module Controls and click Add Module Control.

Product module controls

Make the following settings and click Update:

Edit control definition

Now we can at last create product items and edit them. Great! Try it out!
Go to the page where you added the Products module. Make sure you are in edit mode. Now click the Add Content link. This time it actually happens something interesting. You should now see the edit control with a text field for product name and a text editor for description. Enter some text in them and click Update. The product you just added should now appear in the product list.
Now click the edit (pencil) icon next to the product name. This will take you to the edit screen and let you edit the product item.
Play around with your nice new controls until next time, when we look at the settings control.

Tags: , , ,

DotNetNuke | Modules | Tutorials

Comments

8/3/2010 2:34:12 AM #

Tom

HI, have tried to follow you in this tutorial
but get errors here: "Description.Text = itm.Description" and here:
"productItem.Description = Description.RichText.Text"

Error  5  'Text' is not a member of 'System.Web.UI.UserControl'.  C:\Inetpub\wwwroot\DesktopModules\Products\EditProducts.ascx.vb  72  29  Products

Error  6  'RichText' is not a member of 'System.Web.UI.UserControl'.  C:\Inetpub\wwwroot\DesktopModules\Products\EditProducts.ascx.vb  116  43  Products

Have I missed something?
Best regards, Tom

Tom Norway |

8/3/2010 10:05:47 PM #

Johan

Hi,
As long as you carefully followed the tutorial (especially part 2) you shouldn't have missed anything.
I think you get the error because the VS designer fails to declare the Description control with the correct type (should be Global.DotNetNuke.UI.UserControls.TextEditor).
To trigger the designer to recreate the EditProducts.ascx.designer.vb file, add a control (doesn't matter which) to EditProducts.ascx in design mode and compile the project. Then remove the control and compile again. That should do the trick...

Please let my know how it goes.

Johan Sweden |

8/3/2010 11:10:23 PM #

Tom

Thank you so much!! for the tip that worked and for this wondeful tutorial!

Tom Norway |

8/4/2010 10:50:23 PM #

Johan

Happy to help!
Keep up the good work!

Johan Sweden |

11/12/2010 1:33:29 PM #

Sebastian

Hi there,

I have the same Error message as Tom,
and did what you described.

But it doesnt solve the Error.

Error  5  'Text' is not a member of 'System.Web.UI.UserControl'.  C:\inetpub\wwwroot\DotNetNuke\DesktopModules\Products\EditProducts.ascx.vb  72  25  Products


Error  6  'RichText' is not a member of 'System.Web.UI.UserControl'.  C:\inetpub\wwwroot\DotNetNuke\DesktopModules\Products\EditProducts.ascx.vb  119  43  Products

Sebastian Netherlands |

9/1/2010 7:59:08 PM #

Ahmed Eltawil

For some reason, when I open DotNetNuke website's login screen, I don't see the textboxes, just the login image (the lock). I click on the Register link and I was able to go the User Registration page, but still can't see any textboxes or any controls.

I tried resetting IIS, uninstalled DNN and installed it again (worked for a while but happened again later on).

Any idea?

Ahmed Eltawil Canada |

9/1/2010 10:49:53 PM #

Johan

That was very weird indeed! Sorry to say, I have absolutely no clue what would cause that kind of behavior.
When you find the source of the problem you are very welcome to share what it was. I'm really curious!
Best of luck in tracking it down.

Johan Sweden |

9/2/2010 4:45:54 PM #

Ahmed Eltawil

Ok, finally got it to work again after numerous installs. Apparently if you have the DesktopModules folder setup as a Virtual Directory in IIS, that makes DotNetNuke not find any module needed to be loaded.

The reason why I had it setup as a Virtual Directory is to be able to test and debug in Visual Studio but apparently that causes some major issues. Removing the Virtual Directory from IIS fixed the problem.

I just thought I would share my findings just in case someone faced a similar situation.

Ahmed Eltawil Canada |

9/2/2010 5:06:31 PM #

Johan

Glad to hear that you sorted it out.
Thanks for sharing!

Johan Sweden |

12/31/2010 3:28:06 AM #

Moses

I'm getting the following error when I add If Not Null.IsNull(ItemId).... in Page_Load method in EditProducts.ascx.vb.
'Null' is not declared. 'Null' constant is no longer supported; use 'System.DBNull' instead.

Great tutorial otherwise. thanks -Moses

Moses United States |

12/31/2010 3:45:25 AM #

Moses

I changed the above statement to If Not [i]IsNothing(ItemId).....[/i]
I haven't tried it but I hope it works. -Moses

Moses United States |

12/31/2010 3:47:28 AM #

Moses

I changed the above statement to If Not IsNothing(ItemId).....
I haven't tried it but I hope it works. -Moses

Moses United States |

Comments are closed

About the addict

Johan Seppäläinen lives in Uppsala, Sweden. He spends most of his days working as a systems architect/developer, specialized in solutions built on Microsoft platforms.
Occasionally there is time for some recreational coding, when he pursues optimal solutions and code zen, mainly in C#. When he is not writing in this blog, that is.