Test if Item Selected in ListBox

Testing to ensure that a ListBox has a selected item on submit.

Here all is done using the built in asp.net functions.

Alternatively, could use JavaScript or JQuery. Note that to do so would need to assign variables to the listbox element for the testing.

1. Field Validator

Here’s the list box with its items. I find fruit and veg a ready source of names when trying out examples such as this.

<asp:ListBox ID="lbxFruit" runat="server">
        <asp:ListItem>Apple</asp:ListItem>
        <asp:ListItem>Plum</asp:ListItem>
        <asp:ListItem>Pear</asp:ListItem>
        <asp:ListItem>Peach</asp:ListItem>
        <asp:ListItem>Grape</asp:ListItem>
    </asp:ListBox>
    <asp:Button ID="btnSubmit" runat="server" Text="Button" />
    <asp:RequiredFieldValidator ID="rqdFruit" runat="server" 
        ControlToValidate="lbxFruit" Display="Dynamic" 
        ErrorMessage="Required! Please choose 1!">Required! Please choose 1</asp:RequiredFieldValidator>

With the RequiredFieldValidator using the Dynamic display option gives instant feedback if the field isn’t completed.

2. On Form Submit

If lbxFruit.SelectedIndex = -1 Then
Response.Write("Please select at least one item")
End If

In this example the form is submitted. The work is then done on the server to check whether the submission is correct.

Here the test is whether the SecletedIndex has a value of -1, ie not set.

For simplicity I have simply shown a response write. The presentation should be better with a label populated with the details of the field which has been selected, I assume that other fields will also be similarly tested.

Also I’ve not shown an abort. If there’s an error on the form then further actions on the field won’t be processed. The page will be returned back to the visitor as many times as needed until its correctly filled out.

3. JavaScript/JQuery

Custom javaScript or JQuery can be written.

To be able to make such actions the ID of fields the fields will be required. This will be done by assigning to a variable the reference on the page, as composed by asp.net.

var lbxFruit = document.getElementById(“<%= lbxFruit.ClientID %>”).innerText;

Thoughts

I prefer in practice to use a combination of the two examples above.

By first checking whether the use has filled out the form correctly the responses are immediate. The user experience is the better for it

and we impose less impact on the server.

Once the user input has been validated then it can be submitted to the server and checked. Checking is required because there’s the chance that the user input has escaped the validation and who knows maybe the page has been edited to enable the trial of input of bad data.

Disable ASP.NET Form Button

When providing buttons on a web page, we may wish to show a particular button as ‘greyed out’, signifying that it is more generally available for use, but not for the task we are undertaking.

An example of this would be an edit button.

If the content we are adding (perhaps the details for a user) is new then it would be inappropriate to be able to click on a button to edit the details.

In this example the editor used is Visual Studio as a part of a DotNetNuke module. The file edited is the presentation view, perhaps a file called default.ascx.

To grey the text on a button simply add the word disabled to the button definition.

<input id=”edit” “disabled” type=”submit” value=”Edit” name=”edit”>

It looks strange but I’ve found that the word disabled should be within speech marks.

Formatting Datagrid Data Text Two Ways

Data grid output can be formatted differently for the public/normal view and the edit view.

In this example both methods are used.

Using inline table row editing with a DataGrid I wished to change the formatting according to its state.

To illustrate this I have included below an example template column.

<HEADERSTYLE HorizontalAlign="Center"></HEADERSTYLE>
<ITEMTEMPLATE>
<asp:Label Text=‘<%# DataBinder.Eval(Container, "DataItem.price", "{0:c}") %>’ runat="server">
</asp:Label>
</ITEMTEMPLATE>
<EDITITEMTEMPLATE>
<asp:TextBox id="price" Text=‘<%# DataBinder.Eval(Container, "DataItem.price", "{0:N2}") %>’ runat="server" Columns="6">
</asp:TextBox>
</EDITITEMTEMPLATE>

We are able to format the content of the DataGrid cell by one of two methods, dependent upon whether the column is a bound column or whether it is a template column.

As can be seen two different formatting styles are used.

When the DataGrid is normally viewed the currency format is displayed and when the row is being edited we switch to a 2 decimal place view. To provide the number in a suitable format, without the presentation of the currency symbol. After all a currency symbol within the textbox will give us an extra unnecessary item to handle.

Bound column

For the bound column I’ve added DataFormatString=”{0:N2}%” to the definition of the column.

Looking at the table below, we can see that in our example, we shall format the column to have two digits after the decimal point, followed by a percentage sign.

Template column

For the template column I’ve added the formatting into the reference to the data:

text=‘<%# DataBinder.Eval(Container, “DataItem.Total”, “{0:N2}%”) %>’

Formatting

The table below summarises the formatting expressions with their results.

ExpressionDescription
{0:C}Currency item based on the locale, For example £29.99
{0:D4}A number of the set number plus 1. For example 00124
{0:N2}%A number with two decimal places, followed by a percentage sign
{0:0.0}A number rounded to one decimal place.
{0:D}The date represented as a long string. For example Monday, 20 July 2004
{0:dd-MM-yy}The number as defined by the day, month and year code. for example 20-07-04

Add Browser Redirection to ASP.NET File

Perhaps a page was created with a spelling error, or a reorganisation of the website means that a particular page has been renamed.

We wish to redirect our visitors to the page to a different address.

In the example below its assumed that the website page has moved to www.example.com/fruit-and-veg/.

We wish to tell the browser to redirect to the new page name by adding a short snippet of code to the page.

<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location","http://www.example.com/fruit-and-veg/");
}
</script>

The code example above can be added to the page. This is for a dynamic asp.net page. It won’t work for a static HTML page.

In the above I’ve included the notification that the change is permanent.

Browsers will cache the redirect, after all you’ve told the browser that you no longer wish the old page to be visited. You may find forcing browsers to adopt a change back difficult to achieve, with the browser reluctant to discover the change. A further permanent redirect back again may be used.

I’ve illustrated the example using a permanent redirect. But, as noted, it’s possible that the browsers will equally permanently cache your rule. If it’s wrong then amending it may well be ignored. Experiment first with a temporary redirect, just to be safe.

If its your intention to redirect more than the single page, perhaps a whole menu section, by adding the redirect into a common header file then you may wish to reconsider your approach. Making use of the file web.config.

CustomValidator with Client JavaScript

I had crafted a custom validator for an DNN asp.net web page with a function to validate form elements.

Using the DNN pop-up calendar, with appropriate date formatting according to the browser, had issues with visitors not setting the language within the browser correctly. It was also decided that using 3 dropdownlists would provide a better control of the selection, and less issue with date selection on mobile devices using the pop up calendar.

I added 3 drop down lists to a web page to facilitate date selection.

To ensure that the date was valid I created a custom control to be referenced on the page with validateDate()

Initially I found that the function was firing, but that the status wasn’t being returned.

The JavaScript function was amended, requiring both sender and args parameters, like so:

<script type="text/javascript">
function validateDate(sender,args) {
    var ddlDay = $("#<% = ddlTheDay.clientid %>");
    var ddlMonth = $("#<% = ddlTheMonth.clientid %>");
    var ddlYear = $("#<% = ddlTheYear.clientid %>");

    document.getElementById('<% = cvTheDay.clientid %>').style.display = 'none';
    document.getElementById('<% = cvTheMonth.clientid %>').style.display = 'none';
    document.getElementById('<% = cvTheYear.clientid %>').style.display = 'none';

    // check date was selected
    if (ddlDay.val() < 0 ||
        ddlMonth.val() < 0 ||
        ddlYear.val() < 0) { // if ($('.validateDate').hasClass('validDate')){ // $('.validateDate').toggleClass('inValidDate validDate'); //} args.IsValid = false; return false; } // ensure days value correct if (ddlDay.val() > daysInMonth(ddlMonth.val(), ddlYear.val())) {
        args.IsValid = false;
        return false;
    }


    // check date is valid
    var dobDate = new Date(ddlYear.val(), ddlMonth.val() - 1, ddlDay.val());

    if (Object.prototype.toString.call(dobDate) === "[object Date]") {
        if (isNaN(dobDate.getTime())) {
            // date is not valid
            args.IsValid = false;
            return false;
        }
        else {
            // date is valid
            args.IsValid = true;
            return true;
        }
    }
    else {
        // not a date
        args.IsValid = false;
        return false;
    }
}

function daysInMonth(month, year) {
    return new Date(year, month, 0).getDate();
}
</script>

Shown below are the dropdownlists, together with their custom validators.

<asp:dropdownlist id="ddlTheDay" visible="true" runat="server" name="ddlTheDay" class="ddlTheDay" />
<asp:dropdownlist id="ddlTheMonth" visible="true" runat="server" name="ddlTheMonth" class="ddlTheMonth" />
<asp:dropdownlist id="ddlTheYear" visible="true" runat="server" name="ddlTheYear" class="ddlTheYear" />
<asp:customvalidator id="cvTheDay" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheDay" ClientValidationFunction="validateDate" />
<asp:customvalidator id="cvTheMonth" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheMonth" ClientValidationFunction="validateDate" />
<asp:customvalidator id="cvTheYear" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheYear" ClientValidationFunction="validateDate" />
<div class="validateDate validDate">The date is invalid!</div>

As can be seen above I am using just the one div with the error announcement. Its default setting is within the module’s CSS file module.css, details are below:

.validateDate{color:#d00;font-weight:bold;}
.validDate{display:none;}
.invalidDate{display:block;}

A RadioButtonList in a GridView

A GridView is to include a RadioButtonList in its presentation. The options are to be populated as fixed options, not taken from a database.

The example below takes values from the DotNetNuke Lists and displays them as a radio button list.

In the presentation file there is a GridView, called gdvMembership

<asp:GridView ID="gdvMembership" runat="server"
  AllowPaging="false"
  AllowSorting="false"
  AutoGenerateColumns="false"
  GridLines="none"
  cellspacing="1"
  border="0"
>
  <Columns>
    <asp:TemplateField ItemStyle-HorizontalAlign="left" ItemStyle-Width="80%">
    <ItemTemplate>
    <asp:RadioButton ID="rbnOptions" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Text")  %>' GroupName='<%# DataBinder.Eval(Container, "DataItem.Value")  %>' Checked='<%# DataBinder.Eval(Container, "DataItem.Selected")  %>' AutoPostBack="true" OnCheckedChanged="setSelection" />
    </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

In the code behind, a subroutine is used to populate the GridView and to set the selected item.

Private Sub Registration(ByVal SeclectedValue as string)
  Dim dt as DataTable = new DataTable
  dt.Columns.Add(New DataColumn("Text"))
  dt.Columns.Add(New DataColumn("Value"))
  dt.Columns.Add(New DataColumn("Enabled"))
  Dim row as dataRowrow = dt.newRow()
  row("Text") = "I am registered with the organisation"
  row("Value") = "Registered"
  row("Enabled") = True"
  If SelectedValue Is Nothing Then
    row("Selected") = False
  ElseIf SelectedValue = "Registered" Then
    row("Selected") = True
  Else
    row("Selected") = False
  End If
  dt.Rows.Add(row)row = dt.newRow()
  gdvMembership.DataSource = dt
  gdvMembership.DataBind()
End Sub

Whilst populating the rest of the page content the above sub-routine is called with the value of the registration status.

Registration(objIApplication.Membership)

Radio buttons of a different row in a GridView cannot be grouped together. The issue is caused by each row in the GridView being given a different ident.

The radiobuttons are therefore not of the same name once the page is rendered.

<input id=”dnn_ctr485_application_gdvMembership_rbnOptions_0″ name=”dnn_ctr485_application_gdvMembership_rbnOptions_1″…>

Use the GroupName parameter.

I had considered using JQuery to change uncheck the other options when the selection is changed. However, I chose to use an auto postback and a call to a function: don’t forget to add AutoPostBack=”true”.

Protected Sub setSelection(ByVal sender As Object, ByVal e As System.EventArgs)
  For Each row As GridViewRow In gdvMembership.Rows
    Dim rb As RadioButton = TryCast(row.FindControl("rbnCUOptions"), RadioButton)
    Dim rbn As RadioButton = TryCast(sender, RadioButton)
    If Not rb Is rbn Then
      rb.Checked = False
    End If
  Next
End Sub

Determine Subroutine Click Event Trigger

Using one sub-routine to handle more than one link button click event requires determination of which button click triggered the sub-routine.

I had an existing subroutine handling a link button. Examining the entries in a form, updating a database and sending an email. A second button was required on the form which would update the database but not send the email.

Options were:

  1. Clone the sub-routine omitting the email sending
  2. Two subroutines to handle the click events with each calling a common function where the difference between the two actions is to be determined. Or just the common block of code for saving the form values.
  3. One subroutine to handle the two click events with the email sending determined by which link button was clicked.

For a quick solution I chose option 1 – clone the subroutine.

However, with time available later I was interested in implementing option 3 – one subroutine handling two click events with a part of the code in the subroutine determined by which link button triggered the event.

In the code below the two link buttons are declared, followed by an outline subroutine to handle the clicking of the two buttons.

'Declare two link buttons with event handling
Dim WithEvents cmdSave as System.LinkButton
Dim WithEvents cmdAdd as System.LinkButton'Sub routine to handle the clicking of either button.
'Run common block of code in sub routine
'Determine event was triggered and run an optional block
Private Sub cmdLButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click , cmdAdd.click
  'common block of code here (update database)
  'Code here specific to one item
  If sender = cmdAdd  Then
    'send email to applicant confirming form submission
  End If
  If sender = cmdSave Then
    'send email to applicant confirming form submission
  End If
End Sub

A test is made to determine which of the two link buttons was clicked.

In the example above I have shown each as their own separate if statement. When I developed this further I replaced the if statements with a select.

Shown below is a part of the updated

missing the right buttons/commands, would be better to base this upon the GridView edit/update/delete automation

 <asp:GridView ID="gdvCU" runat="server"
    AllowPaging="false"
    AllowSorting="false"
    AutoGenerateColumns="false"
    >
  <Columns>                            
    <asp:TemplateField ItemStyle-HorizontalAlign="left" ItemStyle-Width="80%">
      <ItemTemplate>
        <asp:RadioButton ID="rbnOption" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Text")  %>' GroupName='<%# DataBinder.Eval(Container, "DataItem.Value")  %>' Checked='<%# DataBinder.Eval(Container, "DataItem.Selected")  %>' AutoPostBack="true" OnCheckedChanged="DeselectSelected" />
      </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField ItemStyle-HorizontalAlign="Left" ItemStyle-Width="20%">
      <ItemTemplate>
        <asp:LinkButton ID="cmdCU" runat="server" Text="Send" CommandName='<%# DataBinder.Eval(Container, "DataItem.Value") %>' CommandArgument='<%# DataBinder.Eval(Container, "DataItem.Value") %>' CausesValidation="false" Visible='<%# DataBinder.Eval(Container, "DataItem.enabled")  %>'></asp:LinkButton>
        <asp:Label ID="FruitId" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.FruitId") %>' Visible="false"></asp:Label>
      </ItemTemplate>
    </asp:TemplateField>    
  </Columns>
</asp:GridView>

The Associated subroutine to handle the above gridview and its submission.

Protected Sub cmdCURegister(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) Handles gdvCU.RowCommand
  Try
      Select Case e.CommandName
        Case "Registered"
          'action here if visitor is registered
        Case "NotRegistered"
          'action here if visitor is not registered                      
      End Select
    End If

  Catch exc As Exception 'Module failed to load
    ProcessModuleLoadException(Me, exc)
  End Try
End Sub

What about option 2?

Having satisfied my interest with the common subroutine with a test to determine the source and choose the appropriate action I never implemented option 2.

Converting to and from ASCII with vb.net

The ASCII table is a representation of the Roman characters as numeric values. Given an ASCII value we may wish to convert it to its corresponding character, or indeed back the other way from character to ASCII value.

To convert an integer variable of ASCII value, myASCII, to a string we use:

myString = char(myASCII)

and to convert back the other way, from a character to the ASCII value, we use

myASCII = asc(myString)

For the ASCII table of characters see the article: ASCII Table of Numbers and Characters.

Convert Textbox String to Double

The task is to take user entered textbox content, converting it to a field of type double.

As a part of a form I had a numeric entry field. The string value entered in this textbox to be converted to type double for saving in a database.

The public view of the textbox included the appropriate numeric validation. However, I prefer to test the entered content rather than assuming that this protection will be sufficient.

Given below is the text box definition.

<asp:TextBox is=”price” Visible=”True” runat=”Server />

I found that my old test for reading the value in a textbox and assigning it to a variable of type double had become unreliable.

To ensure the textbox string is correctly converted to a double, set the value to 0 if empty, or if it’s value doesn’t qualify as a double. I used the following:

Dim d as Double
If Double.TryParse(tbxPrice.Text, d) Then
  Price = convert.ToDouble(tbxPrice.Text)
Else
  Price = 0
End If

In the example above I first test to see if the content will convert to type double. If this works then we are good to make the conversion.

If the trial conversion fails then set the value to 0.

Whilst it’s possible to add checks to ensure that field values are of the correct type prior to submission I like to also add a check of the data when handling too. You can’t be too careful.

LinkButton Handles OnClick Equivelent in C#

To handle a Linkbutton onclick in VB.NET the LinkButton is declared and a handler sub declared:

<asp:linkbutton id="cmdAdd" runat="server" ResourceKey="Add" BorderStyle="none" CausesValidation="true" />

Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
:::
:::
End Sub

C# doesn’t support the VB.net handles on click, the function is simply declared.

The LinkButton declaration is given below. Unlike vb.net there is no WithEvents part of the declaration.

protected global::System.Web.UI.WebControls.LinButton cmdAdd

Explanations of the above:

  • protected – Used to restrict access to the code to the same class.
  • global – Used to clarify that the object is taken from the global namespace as opposed to the current one.
  • :: – This operator, positioned between two indentifiers, is used to look up an identifier.
  • cmdAdd – name of the LinkButton

Looking in the .ascx presentation file the link button is declared as:

<asp:linkbutton id=”cmdAdd” runat=”server” ResourceKey=”cmdAdd” CausesValidation=”true” />

Begin the OnLoad, and include reference for the LinkButton

protected override void OnLoad(EventArgs e) {
base.OnLoad(e)
try {
cmdAdd.click += new System.EventHandler(cmdAdd_Click);

Then later in the code there is the cmdAdd_Click function:

private void cmdAdd_Click(System.Object sender, System.EventArgs e) {try {
// actions here for the function

References

MSDN: global

MSDN: The :: Operator

MSDN: How to: Use the Global Namespace Alias