I have tried to convert Stephen Walther Option 1, client side from his
Tip #41. I think that I have converted things to VB well enough, except that I think I did the helper wrong. I have added the namespace <add namespace="System.Web.Helpers"> in my web.config.
I am getting the following compile error:
'CascadingDropDownList' is not a member of 'System.Web.Mvc.HtmlHelper(Of PFS.KF_Address)'
Anyone know how to resolve this or where/how in VB I should import the correct namespace?
Here is a shortened version of my AddressControl.vb file:
Imports System.Data.Entity
Imports System.Web.Mvc
Imports System.Linq
Imports PFS.PFS.Helpers
Namespace PFS
Public Class AddressController
Inherits System.Web.Mvc.Controller
Function Create() As ViewResult
ViewBag.CountryID = New SelectList(db.KF_Countries, "ID", "Country")
ViewBag.StateID = New SelectList(db.KF_States, "ID", "State")
ViewBag.TypeID = New SelectList(db.KF_AddressTypes, "ID", "Name")
ViewData("CountryList") = New SelectList(db.KF_Countries, "ID", "Country")
ViewData("StateList") = New CascadingSelectList(db.KF_States, "Country_ID", "ID", "State")
Return (View())
End Function
End Class
End Namespace
I am using the _Layout and not the site.master.
@Imports PFS.PFS.Helpers
<html>
<head>
<meta charset="utf-8" />
<title>@ViewData("Title")</title>
</head>
<body>
<div class="page">
<header id="Head1">
<div id="title">
<h1>The PFS Application</h1>
</div>
<div id="logindisplay">
@Html.Partial("_LogOnPartial")
</div>
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Maintenance", "Maintenance", "Home")</li>
</ul>
</nav>
</header>
<section id="main">
<div id="MainContent">
@RenderBody()
</div>
</section>
<footer>
</footer>
</div>
</body>
</html>
Here is my View: Create.VBHtml
@ModelType PFS.KF_Address
@Code
ViewData("Title") = "Create"
End Code
<h2>Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/MicrosoftAjax.js") type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/CascadingDropDownList.js") type="text/javascript"></script>
@Using Html.BeginForm()
@Html.ValidationSummary(True)
@<fieldset>
<legend>KF_Address</legend>
<div>
<label for="Countries">
Countries:</label>
@Html.DropDownList("--Select Country--", "CountryList")
<label for="States">
States:</label>
@Html.CascadingDropDownList("StateList", "CountryList")
</div></fieldset>
Here is my Helper: JavaScriptExtensions.vb
Imports System.Collections
Imports System.Collections.Generic
Imports System.Web.Mvc
Imports System.Web.UI
Imports System.Text
Namespace PFS.Helpers
Public NotInheritable Class JavaScriptExtensions
Private Sub New()
End Sub
Public Shared Function CascadingDropDownList(helper As HtmlHelper, name As String, associatedDropDownList As String) As String
Dim sb = New StringBuilder()
sb.AppendFormat("<select name="{0}" id="{0}"></select>", name)
sb.AppendLine()
sb.AppendLine("<script type="text/javascript">")
Dim data = DirectCast(helper.ViewDataContainer.ViewData(name), CascadingSelectList)
Dim listItems = data.GetListItems()
Dim colArray = New List(Of String)()
For Each item In listItems
colArray.Add([String].Format("{{key:'{0}',value:'{1}',text:'{2}'}}", item.Key, item.Value, item.Text))
Next
Dim jsArray = [String].Join(",", colArray.ToArray())
sb.AppendFormat("$get('{0}').allOptions=[{1}];", name, jsArray)
sb.AppendLine()
sb.AppendFormat("$addHandler($get('{0}'), 'change', Function.createCallback(bindDropDownList, $get('{1}')));", associatedDropDownList, name)
sb.AppendLine()
sb.AppendLine("</script>")
Return sb.ToString()
End Function
End Class
Public Class CascadingSelectList
Private _items As IEnumerable
Private _dataKeyField As String
Private _dataValueField As String
Private _dataTextField As String
Public Sub New(items As IEnumerable, dataKeyField As String, dataValueField As String, dataTextField As String)
_items = items
_dataKeyField = dataKeyField
_dataValueField = dataValueField
_dataTextField = dataTextField
End Sub
Public Function GetListItems() As List(Of CascadingListItem)
Dim listItems = New List(Of CascadingListItem)()
For Each item As VariantType In _items
Dim key = DataBinder.GetPropertyValue(item, _dataKeyField).ToString()
Dim value = DataBinder.GetPropertyValue(item, _dataValueField).ToString()
Dim text = DataBinder.GetPropertyValue(item, _dataTextField).ToString()
listItems.Add(New CascadingListItem(key, value, text))
Next
Return listItems
End Function
End Class
Public Class CascadingListItem
Public Sub New(key As String, value As String, text As String)
Me.Key = key
Me.Value = value
Me.Text = text
End Sub
Public Property Key() As String
Get
Return m_Key
End Get
Set(value As String)
m_Key = Value
End Set
End Property
Private m_Key As String
Public Property Value() As String
Get
Return m_Value
End Get
Set(value As String)
m_Value = Value
End Set
End Property
Private m_Value As String
Public Property Text() As String
Get
Return m_Text
End Get
Set(value As String)
m_Text = Value
End Set
End Property
Private m_Text As String
End Class
End Namespace