Using cascading comboboxes - telerik

I'm using a Telerik radGrid to display data, including address. I want to be able to insert new, or Edit an existing address. To this end, I wish to use Cascading comboboxes which would prepopulate the next, ie country_onselectedindexchanged populates Province/State, etc.
My issue is that whenever I click on Country, I can see in the step-through that my Province/State combo is populated, but then a postback occurs and my Grid_itemdatabound event fires and the initial data is repopulated again.
I have an account on the Telerik site, but last time I posted a question it took a week to get a response.
<telerik:RadGrid ID="RecipientsGrid" runat="server" AutoGenerateColumns="false" EnableViewState="true" PageSize="5"
AllowFilteringByColumn="true" AllowPaging="true" AllowSorting="True">
<ClientSettings EnablePostBackOnRowClick="true">
<Selecting AllowRowSelect="true" />
</ClientSettings>
<MasterTableView CommandItemDisplay="Bottom" DataKeyNames="RecipientOrganizationID" EditMode="EditForms" >
<EditFormSettings EditFormType="Template">
<FormTemplate>
<telerik:RadComboBox ID="CountryCombo" runat="server" DataTextField="CountryName" DataValueField="CountryID"
OnSelectedIndexChanged="CountryCombo_SelectedIndexChanged" AutoPostBack="true">
</telerik:RadComboBox>
<telerik:RadComboBox ID="ProvinceCombo" runat="server" Width="325" EnableLoadonDemand="true" OnSelectedIndexChanged="ProvinceCombo_SelectedIndexChanged" AutoPostBack="true" >
</telerik:RadComboBox>
</FormTemplate>
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
Private Sub RecipientsGrid_NeedDataSource(sender As Object, e As Telerik.Web.UI.GridNeedDataSourceEventArgs) Handles RecipientsGrid.NeedDataSource
Dim ctx As New DataEntities
RecipientsGrid.DataSource = ctx.RecipientOrganizations.ToList
AddOrganizationButton.Visible = False
RecipientOrganizationComboBox.Visible = False
End Sub
Private Sub RecipientsGrid_ItemDataBound(sender As Object, e As Telerik.Web.UI.GridItemEventArgs) Handles RecipientsGrid.ItemDataBound
If TypeOf e.Item Is GridEditableItem AndAlso e.Item.IsInEditMode Then
Dim editedItem As GridEditableItem = TryCast(e.Item, GridEditableItem)
If e.Item.OwnerTableView.IsItemInserted Then
Dim CountryCombo As RadComboBox = TryCast(editedItem.FindControl("CountryCombo"), RadComboBox)
Dim ProvinceCombo As RadComboBox = TryCast(editedItem.FindControl("ProvinceCombo"), RadComboBox)
Dim CityCombo As RadComboBox = TryCast(editedItem.FindControl("CityCombo"), RadComboBox)
LoadCountries(CountryCombo)
Else
End If
End If
End Sub
Protected Sub CountryCombo_SelectedIndexChanged(ByVal sender As Object, ByVal e As RadComboBoxSelectedIndexChangedEventArgs)
Dim CountryCombo As RadComboBox = DirectCast(sender, RadComboBox)
Dim editedItem As GridEditableItem = DirectCast(TryCast(sender, RadComboBox).NamingContainer, GridEditableItem)
Dim ProvinceCombo As RadComboBox = DirectCast(editedItem.FindControl("ProvinceCombo"), RadComboBox)
LoadProvinces(e.Value, ProvinceCombo)
End Sub
Protected Sub ProvinceCombo_SelectedIndexChanged(ByVal sender As Object, ByVal e As RadComboBoxSelectedIndexChangedEventArgs)
Dim ProvinceCombo As RadComboBox = DirectCast(sender, RadComboBox)
Dim editedItem As GridEditableItem = DirectCast(TryCast(sender, RadComboBox).NamingContainer, GridEditableItem)
Dim CityCombo As RadComboBox = DirectCast(editedItem.FindControl("CityCombo"), RadComboBox)
LoadCities(e.Value, CityCombo)
End Sub
Protected Sub LoadCountries(ByVal Control As RadComboBox)
Using context As New DataEntities
With Control
.DataValueField = "CountryId"
.DataTextField = "CountryName"
.DataSource = context.Countries.OrderBy(Function(x) x.displayOrder).ToList
End With
Control.Width = Unit.Pixel(320)
Control.DataBind()
End Using
End Sub
Protected Sub LoadProvinces(ByVal countryID As Integer, ByVal Control As RadComboBox)
Using context As New DataEntities
With Control
.DataValueField = "ProvinceId"
.DataTextField = "NameEnglish"
.DataSource = context.Provinces.Where(Function(x) x.CountryId = countryID).OrderBy(Function(x) x.NameEnglish).ToList
End With
Control.Width = Unit.Pixel(320)
Control.DataBind()
End Using
End Sub
Protected Sub LoadCities(ByVal ProvinceId As Integer, ByVal Control As RadComboBox)
Using context As New DataEntities
With Control
.DataValueField = "CityId"
.DataTextField = "CityName"
.DataSource = context.Cities.Where(Function(x) x.ProvinceID = ProvinceId).OrderBy(Function(x) x.CityName).ToList
End With
Control.Width = Unit.Pixel(320)
Control.DataBind()
End Using
End Sub
Public Sub SetComboBoxDefault(ByVal FindItemByValue As Integer, ByVal Control As RadComboBox, ByVal DisplayText As String)
Dim ComboBoxItem As RadComboBoxItem
If FindItemByValue > 0 Then
ComboBoxItem = Control.FindItemByValue(FindItemByValue)
If ComboBoxItem IsNot Nothing Then
ComboBoxItem.Selected = True
Else
Control.Items.Insert(0, New RadComboBoxItem("-- Please select a " & DisplayText & " --", String.Empty))
End If
Else
Control.Items.Insert(0, New RadComboBoxItem("-- Please select a " & DisplayText & " --", String.Empty))
End If
End Sub

Posting this here because I don't believe I have enough rep to comment. Usually when I have this issue, it's because I have a binding event of some sort on my RadComboBox in Page_Load that isn't wrapped in a If Not IsPostBack. Try something like this:
Sub Page_Load
If Not IsPostBack
RadComboBox.DataSource = foo;
RadComboBox.DataBind();
End If
End Sub
Hope this helps.

Related

Issue with oncheckchanged in vb.net

I have a page with many gridviews. They are in 2 columns 5 on the left and 5 on the right. They are exactly the same.
The Gridview for Employment has a template for a checkbox on the far left. When this is checked, it fires the following:
Protected Sub ChckedChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim row As GridViewRow = TryCast((CType(sender, Control)).Parent.NamingContainer, GridViewRow)
Dim key As String = GridView5.DataKeys(row.RowIndex).Value.ToString()
Dim Incomeadapter As New DataSet1TableAdapters.IncomeTableAdapter
Dim tblincome As New DataSet1.IncomeDataTable
tblincome = Incomeadapter.GetData(key)
GridView6.DataSource = tblincome
GridView6.DataBind()
Exit Sub
I have debugged this, and this code for some reason I don't understand is LOOPING around! Why does it does this? The first time around it gets the correct info, but then it goes back around and ruins the binding of the gridview to the tableadapter because the wrong ID was put into the call to the tableadapter funcion. Is it possible that OncheckChanged event does not work well with the onclick event? I'm using javascript to make sure that only 1 checkbox can be selected on the gridview on the same checkbox :
<div style="overflow-x: scroll; overflow-y: scroll; height: 100px; width: 444px">
<asp:GridView ID="GridView5" runat="server" DataSourceID="SqlDataSource5" AutoGenerateColumns="False" CellPadding="2" HorizontalAlign="Center" OnRowDataBound="Gridview5_rowdatabound" DataKeyNames="EmpID" RowStyle-Wrap="False" HeaderStyle-Wrap="False" ShowHeader="False" ShowFooter="True" FooterStyle-BackColor="Black">
<FooterStyle BackColor="Black"></FooterStyle>
<HeaderStyle Wrap="False"></HeaderStyle>
<RowStyle HorizontalAlign="Center" />
<Columns>
<asp:TemplateField ItemStyle-Width="25px" HeaderText="">
<ItemTemplate>
<asp:CheckBox ID="ChkSelect" runat="server" onclick="CheckOne(this)" AutoPostBack="True" OnCheckedChanged="ChckedChanged" />
</ItemTemplate>
</asp:TemplateField>
<script type="text/javascript">
function CheckOne(obj) {
var grid = obj.parentNode.parentNode.parentNode;
var inputs = grid.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox") {
if (obj.checked && inputs[i] != obj && inputs[i].checked) {
inputs[i].checked = false;
}
}
}
}
</script>
Rather than doing a postback, with this checkbox with autopostback set to true, is there a way to bind the income gridview which is below the employment gridview without a postback? The income gridview has a separate sql table which has the ID of the employer table as a column. The idea is when you check a checkbox on gridview5 (employment) the income gridview below changes to show the income items which are reflected of the employer. There can be multiple types of income for each employer. Any advice greatly appreciated.
' CausesValidation="False" />
' />
I was able to fix the "looping" issue by rewriting the code as follows:
Dim key As String = ""
For Each row As GridViewRow In GridView5.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim chkrow As CheckBox = TryCast(row.Cells(0).FindControl("ChkSelect"), CheckBox)
If chkrow.Checked Then
key = GridView5.DataKeys(row.RowIndex).Value.ToString()
End If
End If
Next
'Dim row As GridViewRow = TryCast((CType(sender, Control)).Parent.NamingContainer, GridViewRow)
Dim Incomeadapter As New DataSet1TableAdapters.IncomeTableAdapter
Dim tblincome As New DataSet1.IncomeDataTable
tblincome = Incomeadapter.GetData(key)
GridView6.DataSource = tblincome
GridView6.DataBind()
It is working correctly, however on every postback the page goes up to the top and this is just not acceptable, so I would like to try it with Ajax and update panels. I'm reading up on this now.

classic ASP/VBscript error (Invalid character)

I am getting the following error when i load an ASP page that calls a stored procedure from SQL 2000 with a parameter used at the point of loading the ASP page.
have i made a schoolboy error? and how do i fix this?
error
Microsoft VBScript compilation error '800a0408'
Invalid character
/simon/stock_test.asp, line 6
declare #serial varchar(255)
--------^
and the page is stock_test.asp?ID=980028001365274
<!--#include file="includes/functions_test.asp"-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
declare #serial varchar(255)
set #serial = Request.QueryString("ID")
Call OpenDB()
Call OpenRecordSet(stock, "Exec sp_report_simon_test #serial")
%>
<html lang="EN">
<head>
<title>Stock</title>
</head>
<body>
<table id="test">
<tr>
<td><b>Make</b></td>
<td><b>Model</b></td>
<td><b>Serial</b></td>
</tr>
<%DO WHILE NOT stock.EOF%>
<tr>
<td><%=stock.Fields("Make").value %></td>
<td><%=stock.Fields("Model").value %></td>
<td><%=stock.Fields("serial_number").value %></td>
</tr>
<%
stock.MoveNext
LOOP
%>
</table>
<%
Call CloseRecordSet(stock)
Call CloseDB()
%>
</body>
</html>
functions file
<%
response.Charset="utf-8"
Session.lcid = 2057
Response.Buffer = False
Server.ScriptTimeout=200
Dim dbConn
Function OpenDB()
Set dbConn = Server.CreateObject("ADODB.Connection")
dbConn.Open "Driver={SQL Server}; Server=server_name; Database=db_name; UID=username; PWD=password; Option=4"
End Function
Function CloseDB()
If ucase(TypeName(dbConn)) = "OBJECT" Then
dbConn.Close
Set dbConn = Nothing
End If
End Function
Function OpenRecordSet(RecSet, SqlQuery)
Set RecSet = Server.CreateObject("ADODB.Recordset")
Set RecSet = dbConn.Execute(SqlQuery)
End Function
Function CloseRecordSet(RecSet)
RecSet.Close
Set RecSet = Nothing
End Function
Function ProcessSql(Sql, Page)
Call OpenDB()
dbConn.Execute(Sql)
Call CloseDB()
If Len(Page) > 0 Then
Response.Redirect(Page)
End If
End Function
Function Encode(DirtyText)
Dim CleanText
Cleantext = Server.HtmlEncode(DirtyText)
CleanText = Replace(CleanText, "'", "''")
CleanText = Replace(CleanText, vbCrLf, "<br>")
Encode = CleanText
End Function
Function mySqlDate(rawDate)
Dim dateString
dateString = DatePart("yyyy", cdate(rawDate))
dateString = dateString & "-" & DatePart("m", cdate(rawDate))
dateString = dateString & "-" & DatePart("d", cdate(rawDate))
mySqlDate = dateString
End Function
Function GetMonthName(monthId)
Dim monthNames
monthNames = Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
GetMonthName = monthNames(monthId -1)
End Function
Function CheckQueryString(Qstring, QName, Page)
If Not Len(QString) = 0 AND Len(QString) < 6 AND IsNumeric(QString) Then
QName = QString
Else
Response.redirect(Page)
End If
End Function
%>
It's commendable that you try to use SQL parameters, but they don't work this way in ASP. It should be self-evident that you cannot simply drop SQL into your ASP code.
Use a Command object instead.
Dim stock, serialVal
OpenDB()
serialVal = Request.QueryString("serial")
If serialVal = "" Then serialVal = vbNull
With Server.CreateObject("ADODB.Command")
Set .ActiveConnection = dbConn
.CommandText = "sp_report_simon_test"
.CommandType = adCmdStoredProc
.Parameters.Append .CreateParameter("#serial", adVarChar, adParamInput, 30, serialVal)
Set stock = .Execute
End With
Docs:
MSDN: Command Object (ADO)
MSDN: Parameters Collection (ADO)
MSDN: CreateParameter Method (ADO)
To be able to use constants like adCmdStoredProc directly in the VBScript code they must be made available by referencing their type library at the top of your ASP page.
For Windows 7/Windows Server 2008 and up, use version 6.1:
<!--metadata
type="TypeLib"
name="Microsoft ActiveX Data Objects 6.1 Library"
uuid="B691E011-1797-432E-907A-4D8C69339129"
version="6.1"-->
For earlier versions (Windows XP/Windows Server 2003), use version 2.8:
<!--metadata
type="TypeLib"
name="Microsoft ActiveX Data Objects 2.8 Library"
uuid="2A75196C-D9EB-4129-B803-931327F72D5C"
version="2.8"-->

Telerik Grid - Get master ID in details view

I have a master/detail grid where I do inserts on both the master and detail views. When I'm in detail mode, I need to obtain the master ID value but I can't seem to obtain the value.
I first obtain the inserteditem in the InsertCommand:
Dim inserteditem As GridDataInsertItem = DirectCast(e.Item, GridDataInsertItem)
And then I obtain an instance of the parent (master) view:
Dim parenttable As GridTableView = inserteditem.OwnerTableView.ParentItem.OwnerTableView
I just can't seem to get to the master key value, however. Anyone know what I should do?
Please try with the below code snippet.
.ASPX
<MasterTableView CommandItemDisplay="Top" DataKeyNames="ID" Name="parent">
<DetailTables>
<telerik:GridTableView Name="Child" DataKeyNames="Name">
</telerik:GridTableView>
</DetailTables>
<Columns>
........
........
</Columns>
</MasterTableView>
.ASPX.VB
Protected Sub RadGrid1_InsertCommand(sender As Object, e As GridCommandEventArgs)
If e.Item.OwnerTableView.Name = "Child" Then
Dim item As GridDataInsertItem = TryCast(e.Item, GridDataInsertItem)
Dim pitem As GridDataItem = TryCast(item.OwnerTableView.ParentItem, GridDataItem)
' Parent Item DataKey Here
Dim strID As String = pitem.GetDataKeyValue("ID").ToString()
End If
End Sub

Delete multiple row with radgrid

I am using Radgrid view with multi select row
I want to delete all selected records using checkbox in RadGrid
Code:
<telerik:RadGrid ID="RadGrid1" runat="server" AutoGenerateColumns="False"
OnNeedDataSource="RadGrid1_NeedDataSource"
AllowMultiRowSelection="true">
<MasterTableView DataKeyNames="ID">
<Columns>
<telerik:GridClientSelectColumn>
</telerik:GridClientSelectColumn>
<telerik:GridBoundColumn DataField="Name" UniqueName="Name" HeaderText="Name">
</telerik:GridBoundColumn>
<telerik:GridEditCommandColumn>
</telerik:GridEditCommandColumn>
</Columns>
</MasterTableView>
<ClientSettings>
<Selecting AllowRowSelect="true" />
</ClientSettings>
</telerik:RadGrid>
.aspx.vb
Protected Sub Button1_Click(sender As Object, e As EventArgs)
For Each item As GridDataItem In RadGrid1.SelectedItems
If item.Selected Then
'Access data key
Dim strID As String = item.GetDataKeyValue("ID").ToString()
End If
NEXT
End Sub
The problem is when I use this method to get selected rows IDs to delete records, it is retrieving only one record ID and deleting the record for which the ID is retrieved.
Example: I am selecting records 1,2,3,4 and clicking the delete button, it is deleting only the record with ID=4
I don't know vs Basic very well. But I can say that,
you are loose your current ID knowledge in this command
Dim strID As String = item.GetDataKeyValue("ID").ToString()
every iteration in foreach, your strId variable update with new item id.
Maybe you can use concat string methods (maybe
strId += item.id
to save your all selected ids.
Try below code:
protected void Button1_Click(object sender, EventArgs e)
{
string strID = string.Empty;
foreach( GridDataItem grditem in RadGrid.SelectedItems)
{
if (grditem.Selected)
{
strID = strID + "," + grditem.GetDataKeyValue("ID").ToString();
}
}
if (strID != string.Empty)
{
//your delete logic for db
// pass strID it will contain 1,2,3,4
}
}

Get generated element "name" attribute for HtmlHelper extension

I am building my own HtmlHelper extensions for standard DropDownLists that appear on many of my views. On other elements I use "EditorFor" and razor generates the proper element "name" attribute for me since that is important for it to be bound to the model correctly. How would I get the correct name in my View so that my Helpers name the element appropriately?
Currently my view code looks like this, but I'd rather not hardcode the element name if I can avoid it.
<tr>
<td class="editor-label">
County:
</td>
<td class="editor-field">
#Html.CountyDropDown("CountyID")
</td>
</tr>
Here is my extension code (Which returns the list of Counties based on the current user's region):
<Extension()> _
Public Function CountyDropDown(ByVal html As HtmlHelper, ByVal name As String) As MvcHtmlString
Dim db As New charityContainer
Dim usvm As New UserSettingsViewModel
Dim ddl As IEnumerable(Of SelectListItem)
ddl = (From c In db.Counties Where c.RegionId = usvm.CurrentUserRegionID
Select New SelectListItem() With {.Text = c.Name, .Value = c.Id})
Return html.DropDownList(name, ddl)
End Function
I'm a dummy I already knew how to do this:
1) Gave my Id value a UIHint in the ViewModel like so:
<UIHint("County")>
Public Property CountyId As Nullable(Of Integer)
2) Changed my View to just use EditorFor like this:
<td class="editor-field">
#Html.EditorFor(Function(x) x.CountyId)
</td>
3) Made a "County.vbhtml" partial-view in my EditorTemplates folder:
#ModelType Nullable(Of Integer)
#Html.DropDownList("", Html.CountySelectList(Model))
4) Returned just an IEnumerable(Of SelectListItem) from my helper, not the entire drop down html:
Public Function CountySelectList(Optional ByVal selectedId As Nullable(Of Integer) = 0) As IEnumerable(Of SelectListItem)
Dim db As New charityContainer
Dim usvm As New UserSettingsViewModel
Dim CurrentUserRegionID = usvm.CurrentUserRegionID
Dim ddl As IEnumerable(Of SelectListItem)
ddl = (From c In db.Counties Where c.RegionId = CurrentUserRegionID
Select New SelectListItem() With {.Text = c.Name, .Value = c.Id, .Selected = If(c.Id = selectedId, True, False)})
Return ddl
End Function

Resources