Conditional Item Templates with RadComboBox - telerik

I have a RadComboBox that I am using to display department name and abbreviations. I am using an Item Template with a LinqDataSource to make each item appear as:
DeptAbbr - (DeptName)
Here is the code I am using to do this and it works fine:
<telerik:RadComboBox ID="rcbDepartments" runat="server" AppendDataBoundItems="True"
OnInit="rcbDepartments_Init" DataTextField="DepartmentAbbr" AutoPostBack="True"
DataSourceID="ldsDepartments" DataValueField="DepartmentID" HighlightTemplatedItems="true"
NoWrap="true" Width="250px">
<ItemTemplate>
<div>
<b>
<%# Eval("DepartmentAbbr")%></b><%# Eval("DepartmentName", " - ({0})") %>
</div>
</ItemTemplate>
</telerik:RadComboBox>
My question is this. I want to add an initial item in the list that is for "All Departments" and is the default item. I can do this easily, but the problem I'm having is that because I am not storing an "All Departments" entry in the database, the templating shows a blank space at the beginning of the items list when you pull down the combo box. I'm trying to find out if there is any way to template all but first item in the list?
Note: I have also tried do a conditional in the Eval like this:
<b><%# (Eval("DepartmentAbbr") != null) ? Eval("DepartmentAbbr") : "All Departments" %></b><%# Eval("DepartmentName", " - ({0})") %>
But it only evaluates on the items that are databound and not the initial item which I am sticking in manually. In other words, if I change the above statement to be:
<b><%# (Eval("DepartmentAbbr") == null) ? Eval("DepartmentAbbr") : "All Departments" %></b><%# Eval("DepartmentName", " - ({0})") %>
Then I just get a list with one blank item at the top and the rest reading "All Departments".
My work around for this problem has been to do some funky selection stuff with LINQ server side, but that has forced me to get rid of all templating and html formatting.

You can define the 'All Departments' RadComboBoxItem as a static item in the <Items> collection. Since you have enabled the AppendDataBoundItems property, you don't want to bind to your data source until after the control has already bound the static items; otherwise you'll get the blank space you are seeing when expanding the combo box. Also, use DataBinder.Eval(Container, "Text") to render the DepartmentAbbr field. Since you have set this field as the DataTextField for the control, that value will always render. If not, you'll get the empty space again when the control binds to the static item because it doesn't know what DepartmentAbbr is; it only has a Text field. Here's an example to get you going:
<telerik:RadComboBox ID="RadComboBox1" runat="server"
AppendDataBoundItems="True"
DataTextField="Abbr"
AutoPostBack="True"
DataValueField="DeptID"
HighlightTemplatedItems="true"
NoWrap="true"
Width="250px">
<Items>
<telerik:RadComboBoxItem runat="server" Text="All Departments" />
</Items>
<ItemTemplate>
<div>
<b><%# DataBinder.Eval(Container, "Text")%></b><%# Eval("Name", " - ({0})") %>
</div>
</ItemTemplate>
</telerik:RadComboBox>
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
RadComboBox1.Load += new EventHandler(RadComboBox1_Load);
}
protected void RadComboBox1_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Ensure the static items are already bound before assigning
// new data to the DataSource property
RadComboBox1.DataBind();
var departments = new[] {
new { DeptID = 1, Abbr = "ACME", Name = "ACME Corporation" },
new { DeptID = 2, Abbr = "MSFT", Name = "Microsoft Corporation" },
new { DeptID = 3, Abbr = "GOOG", Name = "Google, Inc" }
};
RadComboBox1.DataSource = departments;
RadComboBox1.DataBind();
}
}
}
Hope that helps!

Related

What's wrong with this implementation of the DataList repeater?

I have the following declarative in an ascx which displays a 4 column list of file names. The file names are xlxs files that can be downloaded so the command event is called when the file name is clicked.
<asp:DataList runat="server" ID="dlHistoricalRates" RepeatColumns="4" >
<HeaderStyle>
</HeaderStyle>
<HeaderTemplate>
<span>Historial Rates</span>
</HeaderTemplate>
<ItemTemplate>
<asp:LinkButton id="historicalRate" ClientIDMode="Static"
runat="server" CommandArgument='<%# Eval("filename") %>'
CommandName="Download" OnCommand="historicalRate_OnCommand" >
<%# Eval("filename") %>
</asp:LinkButton>
</ItemTemplate>
</asp:DataList>
The code-behind command code:
protected void historicalRate_OnCommand(object sender, CommandEventArgs e)
{
if (e.CommandName == "Download")
{
if (e.CommandArgument != null)
{
historicalRate_Download(e.CommandArgument.ToString());
}
}
}
But the CommandArgument is an empty string when it should be the file name. I know the express Eval() is working as it display the file names in the control.
Why, is the filename not being passed as the CommandArgument?
Your CommandArgument looks fine but another way for getting LinkButton's arg from sender object:
protected void historicalRate_OnCommand(object sender, CommandEventArgs e)
{
// get the reference of clicked LinkButton
LinkButton lb = sender as LinkButton;
string cmd = lb.CommandName;
string arg = lb.CommandArgument;
if (cmd == "Download")
{
if (arg != null)
{
historicalRate_Download(arg);
}
}
}

Setting SelectedValue in a Telerik DropDownList in a RadGrid

I am trying to set the SelectedValue of a RadDropDownList in the EditTemplate of my RadGrid. The DataItemBound event appears to be throwing an error on compilation.
ASP.NET
<telerik:GridTemplateColumn DataField="givenAnswer" HeaderText="givenAnswer" UniqueName="givenAnswer">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "givenAnswer") %>
</ItemTemplate>
<EditItemTemplate>
<telerik:RadDropDownList ID="ddlGivenAnswer" runat="server" OnItemDataBound="ddlGivenAnswer_DataBound">
<Items>
<telerik:DropDownListItem Text="Yes" Value="Yes" />
<telerik:DropDownListItem Text="No" Value="No" />
</Items>
</telerik:RadDropDownList>
</EditItemTemplate>
</telerik:GridTemplateColumn>
C#
protected void ddlGivenAnswer_DataBound(object sender, GridItemEventArgs e)
{
if ((e.Item.IsInEditMode))
{
GridEditFormItem item = (GridEditFormItem)e.Item;
RadDropDownList ddl = (RadDropDownList)item.FindControl("ddlgivenAnswer");
ddl.SelectedValue = (string)DataBinder.Eval(e.Item.DataItem, "givenAnswer").ToString();
}
}
Error
CS0123: No overload for 'ddlGivenAnswer_DataBound' matches delegate 'DropDownListItemEventHandler'
This error is being throw on the telerik:RadDropDownList open tag line in ASP.NET. What am I missing here?
Main Edit:
Error CS0123:
First typing CS0123 in Google show me that you were using wrong parameter for your event. Probably a copypast fail. Delete the even in the aspx and ask to intelisense to create a new one. Or copypast this one.
protected void ddlGivenAnswer_ItemDataBound(object sender, Telerik.Web.UI.DropDownListItemEventArgs e)
ItemDataBound:
ItemDataBound occure when a data is bound in a control.
I'am pretty sure that inline declaration are not going to fire this event.
Minor Misconception:
Why would someone change the Value of a selected element dynamically?
It's like changing the value of a vote without changing the vote him self or the name on the vote.
What you want is to check the rigth item.
To check Waldo in the drop down list :
ddlGivenAnswer.FindItemByValue("Waldo").Selected = true;
To check the right Item:
ddlGivenAnswer.FindItemByValue(
DataBinder.Eval(e.Item.DataItem, "givenAnswer").ToString()
).Selected = true;

Suppress WebTestException in Visual Studio 2013 webtest when Selected Option context parameter not exist

In a Visual Studio 2013 WebTest, I am using the "Selected Option" extraction rule to extract the value of a DropDown into a Context Parameter. It works fine as long as a selected option exists. If a selected option does not exist (which in my test is perfectly acceptable) the test throws an exception, "The select tag 'SuchAndSuch' was not found."
The error message is misleading. When I look at the Response I see that the select tag "SuchAndSuch" does indeed exist, it just does not have a selected option. That is to say, this Html tag exists:
<select name="SuchAndSuch">
But it does not have a child tag like this:
<option selected="selected">
I also tried using "Extract Attribute Value" Extraction Rule to extract the selected item in a dropdown, since this latter rule has a "Required" property.
The rule is to look for the first instance of the tag "option" that has the attribute "selected=selected," and then extract the value of the "value" attribute. I have "Required" false because this drop-down will not always have a selected item.
The properties of my Extract Attribute Value rule are as follows:
<RuleParameters>
<RuleParameter Name="TagName" Value="option" />
<RuleParameter Name="AttributeName" Value="value" />
<RuleParameter Name="MatchAttributeName" Value="selected" />
<RuleParameter Name="MatchAttributeValue" Value="selected" />
<RuleParameter Name="HtmlDecode" Value="True" />
<RuleParameter Name="Required" Value="False" />
<RuleParameter Name="Index" Value="0" />
</RuleParameters>
This works fine as long as the drop-down has a selected item. When it does not the WebTest throws the WebTestException
Context Parameter 'SuchAndSuch' not found in test context
and the Request does not execute.
My desired behavior is when this particular drop-down lacks a selected item I want that particular Request to continue to execute and I want the test to NOT log a WebTestException. Is that possible?
The answer in this case is to write a custom extraction rule: https://msdn.microsoft.com/en-us/library/ms243179(v=vs.120).aspx
The rule I created for my own use is below, it is based on code I stole from here: https://social.msdn.microsoft.com/Forums/en-US/df4f2a0b-2fc4-4d27-9380-ac80100ca0b7/need-help-with-complex-extraction-rule?forum=vstswebtest
I first created the rule in the same project as the webtest. When I ran the webtest it immediately errored out with a "FileNotFound" exception when it tried to load the extraction rule. I moved the extraction rule to a separate project and referenced it from the web test project and it solved that problem.
[DisplayName("Extract Single-Select Dropdown")]
[Description("Extracts the attribute value of AttributeName from the selected option if selected option exists.")]
public class ExtractSingleSelectDropdown : ExtractionRule
{
[Description("The 'name' attribute of the rendered 'select' tag.")]
public string DropdownName { get; set; }
[Description("The name of the attribute of the rendered 'option' tag that contains the value that is extracted to the Context Parameter.")]
public string OptionAttributeName { get; set; }
[Description("When true, sets Success 'false' if a selected option is not found.")]
public bool Required { get; set; }
public override void Extract(object sender, ExtractionEventArgs e)
{
if (e.Response.HtmlDocument != null)
{
var tags = e.Response.HtmlDocument.GetFilteredHtmlTags(new string[] { "select", "option" });
if (tags != null && tags.Count() > 0)
{
//find the first <select><option selected="selected"> tag
var selectedOption = tags.SkipWhile(tag => String.IsNullOrWhiteSpace(tag.GetAttributeValueAsString("name")) || !tag.GetAttributeValueAsString("name").Equals(this.DropdownName, StringComparison.InvariantCultureIgnoreCase)) // skip tags that aren't the select tag we're looking for
.Skip(1) // skip the <select> tag
.TakeWhile(tag => tag.Name.Equals("option"))
.Where(tag => String.IsNullOrWhiteSpace(tag.GetAttributeValueAsString("selected"))) //
.FirstOrDefault();
if (selectedOption == null)
{
e.Message = string.Format("Zero selected options in Dropdown {0}", DropdownName);
e.WebTest.Context[ContextParameterName] = string.Empty;
e.Success = (this.Required ? false : true);
}
else
{
e.WebTest.Context[ContextParameterName] = selectedOption.GetAttributeValueAsString(OptionAttributeName);
e.Success = true;
}
}
}
}
}

MVC3 Drop Down or ListBox with dynamic check boxes

I have an MVC3 C#.Net web app. I have a requirement to display a list of check boxes (either in a drop down or a List Box) dynamically based on a table in our db. The table can contain 1:500 entries. I then need to pass the selected check boxes to the Controller in order to perform an action on each selection. Any ideas on an implementation?
There are many ways to go about this but here is a general demo.
You can pass a list of the checkbox values and descriptions either on the Model (as this example does), ViewData[""] dictionary or ViewBag (MVC3+).
Then in your view loop through them and add them to your form using the name="chxBxGroupName" to group them.
Now create a controller action to post to that takes a List of the value type (in this example int) with the parameter naming matching the name="chxBxGroupName".
It will post a list of checked values.
The post page will just print out:
123
456
// This is your landing page. It gathers the data to display to the user as checkboxes.
public ViewResult MyPageWithTheCheckboxes()
{
// For example: Assume a Dictionary with the checkbox value and description
// Replace with DB call, etc.
return View(new Dictionary<int, string> { { 123, "Foo" }, { 456, "Bar" } });
}
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<Dictionary<int,string>>" %>
<!-- Rest of HTML page... -->
<form id="frm1" action="<%=Url.Action("MyPost")%>" method="post">
<% foreach (var item in Model) { %>
<input type="checkbox" id="chxBx<%=item.Key%>" name="chxBxGroupName" value="<%=item.Key%>"/>
<label for="chxBx<%=item.Key%>"><%=item.Value%></label>
<br/><br/>
<% } %>
<input type="submit" value="Go!"/>
</form>
<!-- Rest of HTML page... -->
public ContentResult MyPost(List<int> chxBxGroupName)
{
return Content(string.Join(Environment.NewLine, chxBxGroupName ?? new List<int>()), "text/plain");
}
the answer provided by Jay accomplishes exactly what you need. If you want to put the items in a list you can do it by surrounding the markup with a div control lie below
<div style="height:40px;overflow:auto;">
<% foreach (var item in Model) { %>
<input type="checkbox" id="chxBx<%=item.Key%>" name="chxBxGroupName" value="<%=item.Key% >"/>
<label for="chxBx<%=item.Key%>"><%=item.Value%></label>
<br/><br/>
<% } %>
</div>
unfortunately you cant have checkboxes in a <select />, but if you really wanted it to look like a select list you could add some JQuery that processes onclick of a textbox and shows the div. This obviously would require some jQuery and might not be worth it

Clickable link in RadGrid column

I have a RadGrid where a column in the grid holds a URL. When a put a value in the column I can see the URL but the URL is not clickable (to go to the URL). How can I make the URL clickable?
Here is a rough example of what I'm doing now:
DataTable table = new DataTable();
DataRow row = table.Rows[0];
row["URL"] = "http://www.google.com";
grid.DataSource = table;
In addition I'd really like to show specific text instead of the URL. Something similar to Link in HTML. Is there anyway to do this?
Have you tried the GridHyperLinkColumn? Below is a detailed example.
<telerik:GridHyperLinkColumn FooterText="HyperLinkColumn footer" DataTextFormatString="Search Google for '{0}'" DataNavigateUrlFields="CompanyName" UniqueName="CompanyName" DataNavigateUrlFormatString="http://www.google.com/search?hl=en&q={0}&btnG=Google+Search" HeaderText="HyperLink<br/>Column" DataTextField="CompanyName"></telerik:GridHyperLinkColumn>
You can also view the demosite to see how it works.
http://demos.telerik.com/aspnet-ajax/grid/examples/generalfeatures/columntypes/defaultcs.aspx
Add all the columns manually in the ascx page and make the column you want to contain the hyperlink a GridTemplateColumn:
<telerik:GridTemplateColumn
UniqueName="TemplateLinkColumn"
AllowFiltering="false"
HeaderText="URL">
<ItemTemplate>
<asp:HyperLink ID="Link" runat="server"></asp:HyperLink>
</ItemTemplate>
</telerik:GridTemplateColumn>
Make sure that your grid has an OnItemDataBound method:
<telerik:RadGrid
ID="RadGrid"
runat="server"
AutoGenerateColumns="False"
OnItemDataBound="RadGrid_ItemDataBound" >
In your OnItemDataBound method set the field to the URL:
protected void RadGrid_ItemDataBound(object aSender, GridItemEventArgs anEventArgs)
{
//Get the row from the grid.
GridDataItem item = anEventArgs.Item as GridDataItem;
GridTableCell linkCell = (GridTableCell)item["TemplateLinkColumn"];
HyperLink reportLink = (HyperLink)reportLinkCell.FindControl("Link");
// Set the text to the quote number
reportLink.Text = "Google";
//Set the URL
reportLink.NavigateUrl = "http://www.google.com";
//Tell it to open in a new window
reportLink.Target = "_new";
}
You will also need to check for the correct type, as follows;
if (anEventArgs.Item.GetType().Name != "GridDataItem")
{
return;
}

Resources