Monday, December 21, 2009

Calling function in code-behind using AJAX

Ever wanted to call a function in your code-behind using Javascript? I have. Maybe you want to do some client side functionality and then follow it up with some server side functionality, all without a post-back. The answer to doing this is using javascript, AJAX and the PageMethods functionality of the AJAX scriptmanager.

In order to call a function in code-behind, try this:

1. Create your AJAX web-enabled page and create a scriptmanager with your update panels, etc.
2. In the scriptmanager tag, set "EnablePageMethods" equal to True.
3. Create a javascript function using PageMethods to call the code-behind function.

     function UnlockRecord()
          {
               //Use the PageMethods functionality of the scriptmanager
               PageMethods.UnlockRecord();
          }

4. In your code-behind, create your function as a web services webmethod. You cannot call server-side code ‘directly’ from client-side code. That is because by design, the server side code executes at server side and client side code at the client.

     <System.Web.Services.WebMethod()> _
     Public Shared Function UnlockRecord() As String

          'Code to run

     End Function

That's all there is to it. Now all you have to do is call your javascript which in turn will call your code-behind function.

Friday, December 11, 2009

Reading an RSS feed - two methods

RSS feeds are a great way to enhance your web page. Your web page can be dynamic with daily headlines and stories, all in an autmated fashion. Parsing RSS feeds is fairly straightforward.


Below are two methods to reading an RSS feed.


Method 1:  This method requires very little code. It basically reads the feed via an XmlTextReader into a dataset. Then this dataset can be bound to a gridview, etc.


'Set up a Try/Catch in case the file isn't read correctly
Try

     'Open an XML file/RSS feed
     Dim reader As XmlTextReader = New XmlTextReader(http://stltomorrow.tumblr.com/rss)

     'Set up the dataset for the reader
     Dim ds As DataSet = New DataSet

     'Read the feed
     ds.ReadXml(reader)

     'Create the datatable
     Dim dtSTLtomorrow As DataTable
     dtSTLtomorrow = ds.Tables(2)

     'Bind to the datagrids/gridview
     dgSTLtomorrowVer.DataSource = dtSTLtomorrow
     dgSTLtomorrowVer.DataBind()

Catch ex As Exception

     'Show that there was an error reading the RSS feed

End Try


Method 2: This method requires a little bit more code, but it basically uses an XmlTextReader to read in the RSS feed and then loops through the feed node by node.

'Set up a Try/Catch in case the file isn't read correctly
Try

'Create the dataset to hold the incoming headlines
Dim dstSTLtomorrow As DataSet

'Set up the tables and columns
Dim dtblSTLtomorrow As DataTable
Dim dcolSTLtomorrowID As DataColumn
Dim pkColumns(1) As DataColumn

'Create the dataset
dstSTLtomorrow = New DataSet("dstSTLtomorrow")

'Create the datatable
dtblSTLtomorrow = dstSTLtomorrow.Tables.Add("STLtomorrow")

'Create the columns
'Create the id for the data table
dcolSTLtomorrowID = New DataColumn("STLtomorrowID", GetType(Int32))
dcolSTLtomorrowID.AutoIncrement = True
dcolSTLtomorrowID.Unique = True

'Add the columns to the date table
dtblSTLtomorrow.Columns.Add(dcolSTLtomorrowID)
dtblSTLtomorrow.Columns.Add("description", GetType(String))

'Assign the primary key
pkColumns(0) = dcolSTLtomorrowID
dtblSTLtomorrow.PrimaryKey = pkColumns

'Read the rss
Dim xmlReader As New XmlTextReader(http://stltomorrow.tumblr.com/rss)

'set up a datarow
Dim drowSTLtomorrow As DataRow

'Create a flag to figure out which element we are on
Dim elemFlag As Integer

'Loop through the rss
While xmlReader.Read()

     'Figure out which node type we are on
     Select Case xmlReader.NodeType

          'Element node type?
          Case XmlNodeType.Element

          'If this element name is the description then set a flag
          'to indicate that this is the node we want
          If xmlReader.Name = "description" Then

               'set flag to indicate that yes we do want this node
               elemFlag = 1

          Else

               'set flag to indicate that no we do not want this node
               elemFlag = 0

          End If

          'Text node type?
          Case XmlNodeType.Text

               'Check the flag
               'If it is equal to 1 then this is the description node
               'go ahead and grab the text
               If elemFlag = 1 Then

                    'Make sure there is an href in the string so that the user
                    'has something to click on
                    If InStr(xmlReader.Value, "<a href") > 0 Then

                         'Add Rows to the datatable with the data coming from the feed
                         drowSTLtomorrow = dstSTLtomorrow.Tables("STLtomorrow").NewRow()

                         'get the node value and put it in the datatable
                         drowSTLtomorrow("description") = Replace(xmlReader.Value, Chr(34) & ">", Chr(34) & " target='_new'>")

                         'Add the row
                         dstSTLtomorrow.Tables("STLtomorrow").Rows.Add(drowSTLtomorrow)

                    End If

               End If

     End Select

End While

'Bind to the datagrid/gridview
dgSTLtomorrowVer.DataSource = dstSTLtomorrow.Tables("STLtomorrow")
dgSTLtomorrowVer.DataBind()

'close the dataset
dstSTLtomorrow = Nothing

Catch ex As Exception

     'Show that there was an error reading the RSS feed

End Try

Thursday, December 03, 2009

Creating an AJAX CascadingDropDown extender control using a database

A very cool control in the AJAX Control Toolkit is the CascadingDropDown extender. Basically, this control will allow you to have linked dropdowns. For instance, maybe you want a state dropdown to link to a county dropdown and subsequently to a city dropdown.

To accomplish this you need three things:

1. An asp.net dropdown control.
2. A web service that connects to an XML file or database for the dropdown data.
3. The CascadingDropDown extender control linked to the dropdown to extend.

For our example, we'll be using newspaper publications that link to newspaper products. So when a user selects a publication the second dropdown will display all of the products available for that publication.

Let's start with the code on the .aspx page.

1. First, let's set the EnableEventValidation="false" in the page directive at the top of the .aspx page.
Here is explanation why you need to turn it off ?
In order for the values to be submitted, EventValidation needs to be disabled for the page. EventValidation ensures that the values in each control match the values that were present when the page was rendered, but since these drop downs are populating on the client side, this is never true.

2. Add your asp.net dropdown controls.
Publication dropdown: <asp:DropDownList ID="ddlPublication" runat="server"></asp:DropDownList>
Product dropdown: <asp:DropDownList ID="ddlProduct" runat="server"></asp:DropDownList>

Nothing special here. Just regular old dropdowns.

3. Add the CascadingDropDown extenders.
Publication extender: <cc1:CascadingDropDown ID="cddPublication" runat="server" Category="pub" TargetControlID="ddlPublication" PromptText="[Select Pub]" LoadingText="Loading Pubs..." ServicePath="pubinfo.asmx" ServiceMethod="GetPublications"></cc1:CascadingDropDown>
Product extender: <cc1:CascadingDropDown ID="cddProduct" runat="server" Category="product" ParentControlID="ddlPublication" TargetControlID="ddlProduct" PromptText="[Select Product]" LoadingText="Loading Products..." ServicePath="pubinfo.asmx" ServiceMethod="GetProducts"></cc1:CascadingDropDown>

Next, lets create the web service.

1. In Visual Studio, right click on your project and select "Add New Item".
2. Select "Web Service" and give your web service a name.
3. Now that we have a web service file, let's set up the service methods. Your file should look similar to the code below.

<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<System.Web.Script.Services.ScriptService()> _
Public Class pubinfo

     Inherits System.Web.Services.WebService

     'Set up the database connection string. This should come from the connections strings in your web.config file
     Public condatabase1String As String = System.Configuration.ConfigurationManager.ConnectionStrings("database1ConnectionString").ToString()

'GET PUBLICATIONS METHOD

<WebMethod()> _
Public Function GetPublications(ByVal knownCategoryValues As String, ByVal category As String) As AjaxControlToolkit.CascadingDropDownNameValue()

     'Create a connection to the sql database using the condatabase1String
     Dim sqlConn As New SqlConnection(condatabase1String)

     'Open the connection
     sqlConn.Open()

     'Execute the stored procedure
     Dim sqlSelect As New SqlCommand("EXEC up_MySP", sqlConn)

     'Set the command type
     sqlSelect.CommandType = System.Data.CommandType.Text

     'Create a sql adapter
     Dim sqlAdapter As New SqlDataAdapter(sqlSelect)

     'Create a dataset
     Dim myDataset As New DataSet()

     'Fill the dataset with the results from the stored procedure
     sqlAdapter.Fill(myDataset)

     'Close the connection
     sqlConn.Close()

     'Create a new list to hold the different publications
     Dim cascadingValues As New List(Of AjaxControlToolkit.CascadingDropDownNameValue)()

     'Loop through the rows in the dataset/datatable
     For Each dRow As DataRow In myDataset.Tables(0).Rows
          'Get the publication and publication name
          Dim pub_name As String = UCase("(" & dRow("pub").ToString() & ") " & dRow("pub_name").ToString())

          Dim pub As String = dRow("pub").ToString()

          'Add the values to the list
          cascadingValues.Add(New AjaxControlToolkit.CascadingDropDownNameValue(pub_name, pub))
     Next

     'return the list to the drop down
     Return cascadingValues.ToArray()

End Function

'GET PRODUCTS METHOD

<WebMethod()> _
Public Function GetProducts(ByVal knownCategoryValues As String, ByVal category As String) As AjaxControlToolkit.CascadingDropDownNameValue()

     'Get the publications list
     Dim pubValues As StringDictionary = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)

     'Create a variable to hold the selected pub
     Dim pub As String

     'Get the selected pub
     pub = Convert.ToString(pubValues("pub"))

     'Create a connection to the sql database using the condatabase1String
     Dim sqlConn As New SqlConnection(condatabase1String)

     'Open the connection
    sqlConn.Open()

     'Execute the stored procedure.
     Dim sqlSelect As New SqlCommand("EXEC up_MySP2" & pub, sqlConn)

     'Set the command type
     sqlSelect.CommandType = System.Data.CommandType.Text

     'Create a sql adapter
     Dim sqlAdapter As New SqlDataAdapter(sqlSelect)

     'Create a dataset
     Dim myDataset As New DataSet()

     'Fill the dataset with the results from the stored procedure
     sqlAdapter.Fill(myDataset)

     'Close the connection
     sqlConn.Close()

     'Create a new list to hold the different publications
     Dim cascadingValues As New List(Of AjaxControlToolkit.CascadingDropDownNameValue)()

     'Loop through the rows in the dataset/datatable
     For Each dRow As DataRow In myDataset.Tables(0).Rows

          'Get the product and product name
          Dim product As String = dRow("prod_code").ToString()

          Dim product_name As String = UCase("(" & dRow("prod_code").ToString() & ") " & Left(dRow("product_name").ToString(), 20))

          'Add the values to the list
          cascadingValues.Add(New AjaxControlToolkit.CascadingDropDownNameValue(product_name, product))
     Next

     'return the list to the drop down
     Return cascadingValues.ToArray()

     End Function
 
End Class 

Monday, November 30, 2009

Textbox with background images and gradient borders

You can make textboxes have a snazzy look by utilizing background colors or background images.  Below are some examples:

Example 1: Textbox with a background image.



    


1. Create your image in Photoshop or another image manipulating program. Make sure to size the image to be large enough to fill the textbox. If you have different size text boxes, make the size fit the largest text box. Also, you only need to make the image 1 pixel wide as we will be repeating the image. Below is the code:


          .textbox_search
               {
                     background: transparent url('images/tbgradient.gif') repeat-x;
                     height: 15px;
                     border-style: solid; border-width: 1px;
                     border-color: #d3e4f0;
                     padding-left: 3px;
               }

Example 2: Textbox with a background image border.

     You can also use a background image as a border for a textbox. The only problem with this scenario is the image border must be the same size as the text box. One possible solution to have a specialty border that will fit any textbox is to create the specialty border for two sides only. For instance, create the special border to fit the left and top of the textbox and then just use a CSS border for the right and bottom of the text box. This way the textbox can be any size. You still need to make the specialty border big enough to accomade the largest textbox. Here is an example:



    


     .textbox
          {
               font-size: .8em;
               font-family: calibri, Arial, Sans-Serif;
               background: transparent url('images/textbox_bg.jpg') no-repeat;
               color: #747862;
               height:13px;
               border-top: 0px;
               border-left: 0px;
               border-bottom: solide 1px #c8cbb8;
               border-right: solid 1px #c8cbb8;
               padding:1px 8px;
               margin-top: 0px;
               margin-bottom:0px;
          }

Example 3: Textbox with image

      Lastly, another neat trick is to place an image in the background to help facilitate the textbox meaning. For instance, you can place a magnifying glass icon in a textbox to alert the user this is a textbox for performing a search. Below is an example:





     .textbox_image
          {
               background:#FFFFFF url(images/search.png) no-repeat 4px 4px;
               padding:4px 4px 4px 22px;
               border:1px solid #CCCCCC;
               width:230px;
               height:18px;
          }

Tuesday, November 24, 2009

Selecting multiple dates from a .NET Calendar Control

While the .NET Calendar control is very handy right out of the box, you may find yourself wanting for more. By default the calendar control does allow you to select a date or select a whole week. But what happens if you want to select random dates?

The code below shows how to do this:

1. Create the calendar control.

<asp:Calendar ID="calRunDate" runat="server" OnDayRender="calRunDate_DayRender" CssClass="myCalendar" DayNameFormat="FirstTwoLetters" ShowGridLines="true" CellPadding="1" TitleStyle-BackColor="Transparent" OtherMonthDayStyle-BackColor="white" OtherMonthDayStyle-ForeColor="gray" PrevMonthText=" <img src='images/caltriangleleft.gif' border='0'>" NextMonthText="<img src='images/caltriangleright.gif' border='0'> " TitleStyle-CssClass="calTitleStyle" OtherMonthDayStyle-CssClass="calOtherMonthDayStyle" NextPrevStyle-CssClass="calNextPrevStyle" DayHeaderStyle-CssClass="calDayHeaderStyle" TodayDayStyle-CssClass="calTodayDayStyle" SelectorStyle-CssClass="calSelectorStyle" WeekendDayStyle-CssClass="calWeekendDayStyle" SelectedDayStyle-CssClass="calSelectedDayStyle" DayStyle-CssClass="calDayStyle"></asp:Calendar>

<div style="padding-top: 5px; text-align: center; width: 180px;">
     <asp:Button ID="btnClearDates" runat="server" Text="Clear Selection" CssClass="button"></asp:Button>
</div>
 
2. Create a global list variable to hold the selected dates.
 
Public Shared g_list As New List(Of DateTime)() 'List used for holding multiple date selections
 
3. Check to see if a date is selected and save it to the list/session.
 
Protected Sub calRunDate_DayRender(ByVal sender As Object, ByVal e As DayRenderEventArgs) Handles calRunDate.DayRender

     'Check to see if a day has been selected
     If e.Day.IsSelected = True Then

          'If so add it to the global list variable
          g_list.Add(e.Day.[Date])

     End If

     'Save the list to a session variable
     Session("SelectedDates") = g_list

End Sub

4. Check to see if user has selected/deselected a date.

Protected Sub calRunDate_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) Handles calRunDate.SelectionChanged

     'Let's grab the date the user selected
     'This will be needed to determine if they are unselecting a date
     'see below

     Dim mydate As Date
     mydate = calRunDate.SelectedDate

     'Check to see if the session variable exists
     If Session("SelectedDates") IsNot Nothing Then

          'If so, assign the session variable to a new list variable
          Dim newList As List(Of DateTime) = DirectCast(Session("SelectedDates"), List(Of DateTime))

          'loop through the list
          For Each dt As DateTime In newList

               'Check to see if the date in the list is equal to the date
                   'they selected. If so, then they are deselecting this date
             If CType(dt, Date) = mydate Then

                    'Remove the date from the selected dates
                    calRunDate.SelectedDates.Remove(dt)
                Else

                    'Add the date the selected dates on the calendar
                    calRunDate.SelectedDates.Add(dt)

                End If

          Next

          'Clear the list
          g_list.Clear()

     End If

End Sub

5. Grab the dates the user selected.

Via a button or some other object, run this code to get all of the dates the user selected.

     'Create a date variable to be used for looping through
      'the selected dates on the calendar
      'Dim item As Date

     'loop through the selected dates on the calendar
     'For Each item In calRunDate.SelectedDates

          'Add the dates to a text box.
          'Use commas between them
          txtRunDate.Text = txtRunDate.Text & ", " & item.Date

      'Next

6. Clear all selected dates.

You can also clear all of the selected dates by using the following code:

Protected Sub btnClearDates_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClearDates.Click

     'Clear the selected dates on the calendar
     calRunDate.SelectedDates.Clear()

     'Clear the session variable of any dates
     Session("SelectedDates") = Nothing

     'Clear the global list variable
     g_list.Clear()

End Sub

Monday, November 23, 2009

Adding mouse over events to a .NET Calendar Control

The .NET calendar control is handy way to display a functional calendar. However, the styling of the control out of the box is pretty generic.

One way to spruce things up is to enable a mouse over as the user is browsing the dates.

Below is the code I used to do this. This code should be placed in the DayRender sub of the calendar control:

'Create colors for the mouse over and out

Dim onmouseoverStyle As String = "this.style.backgroundColor='#A8C0D0';"
Dim onmouseoutStyle As String = "this.style.backgroundColor='@BackColor'"

'create a variable to hold the row back color
Dim rowBackColor As String = String.Empty

'Add the attributes to the individual calendar day cells
e.Cell.Attributes.Add("onmouseover", onmouseoverStyle)
e.Cell.Attributes.Add("onmouseout", onmouseoutStyle.Replace("@BackColor", rowBackColor))

Styling an AJAX Calendar Control

The AJAX Calendar control is a nifty control that attaches to a .NET control (i.e. textbox). The calendar is launched by clicking in the text box. Once the calendar is displayed, a user can browse through the years and months and select a date. The date is then placed in the calling text box or .NET control.

The styling of this control is fairly generic. Below is the code to style an AJAX calendar control

For the control properties, I am using this:

<cc1:CalendarExtender ID="ceChangeCopy" runat="server" TargetControlID="txtChangeCopy" Format="MM/dd/yyyy" CssClass="AJAXCalendar" />

For the CSS code, I am using this:

.AJAXCalendar .ajax__calendar_container {border:solid 1px #CDCDB5; background: transparent url(images/calendarbg.gif) repeat-x; width: 180px; z-index : 1000 ;}
.AJAXCalendar .ajax__calendar_footer {border-top:1px solid silver;}
.AJAXCalendar .ajax__calendar_dayname { font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100; border-bottom:1px solid #f5f5f5; }
.AJAXCalendar .ajax__calendar_day {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: bold;border:1px solid #ffffff;}
.AJAXCalendar .ajax__calendar_month {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;border:1px solid #ffffff;}
.AJAXCalendar .ajax__calendar_year {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;border:1px solid #ffffff;}
.AJAXCalendar .ajax__calendar_today {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;}
.AJAXCalendar .ajax__calendar_title {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;}
.AJAXCalendar .ajax__calendar_active .ajax__calendar_day {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#d9e8f1;border-color:#0066cc;color:#0066cc;}
.AJAXCalendar .ajax__calendar_active .ajax__calendar_month {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#d9e8f1;border-color:#0066cc;color:#0066cc;}
.AJAXCalendar .ajax__calendar_active .ajax__calendar_year {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#d9e8f1;border-color:#0066cc;color:#0066cc;}
.AJAXCalendar .ajax__calendar_other .ajax__calendar_day {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#ffffff;border-color:#ffffff;color:gray;}
.AJAXCalendar .ajax__calendar_other .ajax__calendar_year {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#ffffff;border-color:#ffffff;color:gray;}
.AJAXCalendar .ajax__calendar_hover .ajax__calendar_day {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#d9e8f1;border-color:#daf2fc;}
.AJAXCalendar .ajax__calendar_hover .ajax__calendar_month {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#d9e8f1;border-color:#daf2fc;color:#0066cc;}
.AJAXCalendar .ajax__calendar_hover .ajax__calendar_year {font-family: Calibri, Arial, Sans-Serif; font-size: 1.2em; font-weight: 100;background-color:#d9e8f1;border-color:#daf2fc;color:#0066cc;}
.AJAXCalendar .ajax__calendar { position: relative; left: 0px !important; top: 0px !important; visibility: visible; display: block; }
.AJAXCalendar .ajax__calendar iframe { left: 0px !important; top: 0px !important; }

Styling a .NET Calendar Control

ASP.NET comes with a very handy calendar control. This control will allow a user to click on a calendar icon and view a calendar. They can browse the different years and months and select a date. Once a date has been selected, it is displayed in the .NET control wired to the calendar control.

While this calendar control is very handy, the default styling is very generic. Below is my attempt at styling the calendar. I have found the control to be very finicky with using CSS. So, therefore, I am using a combination of control properties and CSS.

For the control properties, I am using this:

<asp:Calendar ID="calRunDate" runat="server" OnDayRender="calRunDate_DayRender" CssClass="myCalendar" DayNameFormat="FirstTwoLetters" ShowGridLines="true" CellPadding="1" TitleStyle-BackColor="Transparent" OtherMonthDayStyle-BackColor="white" OtherMonthDayStyle-ForeColor="gray" PrevMonthText=" <img src='images/caltriangleleft.gif' border='0'>" NextMonthText="<img src='images/caltriangleright.gif' border='0'> " TitleStyle-CssClass="calTitleStyle" OtherMonthDayStyle-CssClass="calOtherMonthDayStyle" NextPrevStyle-CssClass="calNextPrevStyle" DayHeaderStyle-CssClass="calDayHeaderStyle" TodayDayStyle-CssClass="calTodayDayStyle" SelectorStyle-CssClass="calSelectorStyle" WeekendDayStyle-CssClass="calWeekendDayStyle" SelectedDayStyle-CssClass="calSelectedDayStyle" DayStyle-CssClass="calDayStyle"></asp:Calendar>

For the CSS, I am using this:

.myCalendar { border: solid 1px #CDCDB5; width: 180px; background: url(images/calendarbg.gif) repeat-x; z-index: 1000; }
.myCalendar .calDayStyle a { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: bold; }
.myCalendar .calDayStyle a:hover { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: 100; }
.myCalendar .calSelectedDayStyle { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: 100; }
.myCalendar .calWeekendDayStyle a { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: bold; }
.myCalendar .calSelectorStyle { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: 100; }
.myCalendar .calTodayDayStyle a { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: bold; }
.myCalendar .calDayHeaderStyle { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: 100; }
.myCalendar .calNextPrevStyle { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: 100; }
.myCalendar .calOtherMonthDayStyle a { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: 100; }
.myCalendar .calTitleStyle { font-family: Calibri, Arial, Sans-Serif; font-size: 1em; font-weight: 100; height: 10px; }

Thursday, November 05, 2009

Creating a text box water mark extender

The textboxwatermark extender is a nice little AJAX function that enhances the user experience. The main idea is that a "watermark" can be placed in a text box to give the user some direction about what they need to do in that text box. Once the user clicks inside of the text box the watermark disappers.

Follow these steps to add a textboxwatermark extender:

1. Create the text box.
<asp:TextBox ID="txtSearch" runat="server" CssClass="textbox" Width="160px"></asp:TextBox>

2. Create the textboxwatermark extender.
<cc1:TextBoxWatermarkExtender ID="tbweSearch" runat="server" TargetControlID="txtSearch" WatermarkText="Enter package name" WatermarkCssClass="watermarked" />

The three important parameters are:

          a. TargetControlID - Put the name of the text box here.
          b. WatermarkText - Place the text box directions here.
          c. WatermarkCssClass - Put the name of the css class the watermark should use here.

Different time of day on date fields

Often when you insert a date in a datetime field, there is no associated time. (because you didn't provide one!) So, when you compare or join on a date field that did record a particular time of day, or you capture the current time of day "GETDATE()" you do not get a match.

You can set all time values associated with a date to the same value (00:00.0000) using the following code:

CAST(FLOOR(CAST(@yourdate AS FLOAT)) AS DATETIME)

Retrieving autocompleteextender's selected item ID

While the autocompleteextender is a great way to deliver a searchable list to a user, inevitably we need to know what item the user selected. Usually, this is so we can retrieve that item's additional information. For example, if we had a contact database and the autoextender was retrieving contact names, we may want the ability to click on a certain contact and get their additional information. I.e. phone number, address, etc.


In order to do this we have to involve a little bit of javascript and some additional hocus pocus. The example below is pulling some advertising packages. The idea is to let the user search for a package name and then select the particular package they would like to order for a client. Packages are basically ads that are sold as a combination.


Use these steps:

1. Place an autoextender tag in your html and link it to your text box.

For instance:

<asp:TextBox ID="txtSearch" runat="server" CssClass="textbox" width="160px"></asp:TextBox>

<cc1:AutoCompleteExtender ID="aceSearch" runat="server" TargetControlID="txtSearch" FirstRowSelected="true" ServiceMethod="GetPackages" ServicePath="packagemanager.asmx" MinimumPrefixLength="1" CompletionInterval="500" CompletionListCssClass="AutoCompleteFlyout" CompletionListItemCssClass="AutoCompleteFlyoutItem" CompletionListHighlightedItemCssClass="AutoCompleteFlyoutHilightedItem" OnClientItemSelected="GetPackageID" />
<asp:TextBox ID="txtPackageID" runat="server" Style="display: none;">0</asp:TextBox>

Notice the OnClientItemSelected parameter of the autocompleteextender. It is has a function. In this case it is called GetPackageID and will run the GetPackageID function. Also, notice the text box called txtPackageID. This text box is a hidden text box that will hold the package ID that is selected by the user.

2. Create the javascript function.

function GetPackageID(source, eventArgs )
          //This function runs when the user selects an item in the txtSearch
          //text box after the user has run the auto complete extender for the txtSearch
          //text box. Essentially, this is needed to extract the ID of the item that the
          //user selected in the auto complete extender
          {
                document.getElementById('txtPackageID').value = eventArgs.get_value();
          }

The end result is that the txtPackageID hidden text box now contains the ID of the item the user selected and since this object is a .NET object is now available to the code behind.

Friday, October 30, 2009

How to set up the autocompleteextender

The auto extender function is very handy. It is Google like in that it will display available matches in a text box drop-down. In order to makes this AJAX object the best that it can be it is necessary to be able to retrieve the ID of the selected item. Below are the steps to accomplish this.



1. Place an autoextender tag in your html and link it to your text box.


    For instance:

          <asp:TextBox ID="txtSearch" runat="server" CssClass="textbox" width="160px"></asp:TextBox>


          <cc1:AutoCompleteExtender ID="aceSearch" runat="server" TargetControlID="txtSearch" FirstRowSelected="true" ServiceMethod="GetPackages" ServicePath="packagemanager.asmx" MinimumPrefixLength="1" CompletionInterval="500" CompletionListCssClass="AutoCompleteFlyout" CompletionListItemCssClass="AutoCompleteFlyoutItem" CompletionListHighlightedItemCssClass="AutoCompleteFlyoutHilightedItem" OnClientItemSelected="GetPackageID" />


2. Next, create a web service file and place in it a function similar to the one below.


 <WebMethod()> _
Public Function GetPackages(ByVal prefixText As String) As String()

'Create a list to hold the package ID and name
Dim Packages As New List(Of String)()

'Set up the SQL connection using the connection string from above
Dim sqlConn As New SqlConnection(conWork2GoalString)

'Open the connection
sqlConn.Open()

'Create the SQL command
Dim sqlSelect As New SqlCommand("SELECT packagemasterID, package_name FROM adpack_packagemaster WHERE package_name LIKE @prefixText AND package_end_date >= CAST(FLOOR(CAST( GETDATE() AS FLOAT)) AS DATETIME)", sqlConn)

'Set up the SQL data adapter using the SQL command from above
Dim sqlAdapter As New SqlDataAdapter(sqlSelect)

'Add the parameter
sqlAdapter.SelectCommand.Parameters.Add("@prefixText", SqlDbType.VarChar, 50).Value = "%" & prefixText & "%"

'Set up the datareader
Dim drPackage As SqlDataReader

'Execute the datareader
drPackage = sqlSelect.ExecuteReader

'Loop through the datareader
While drPackage.Read()

          'Grab the package name and ID
          Dim package As String = AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(drPackage("package_name").ToString(), drPackage("packagemasterID").ToString())

          'Add the package to the list
          Packages.Add(package)

End While

'Close the datareader
drPackage.Close()

'Close the connection
sqlConn.Close()

'Dispose of the connection
sqlConn.Dispose()

'Return the packages list/array
Return Packages.ToArray()

End Function