How to set focus on text box and set cursor position when page loads

by Naveen 2. September 2010 05:34

While implementing a high performance search functionality for a site, I ran into some interesting issues with some UI aspects. So I thought I would share it with everybody so you have answers to some of the following questions when you run into similar issues.

  • How to set focus in text box when page load

    This is a very common requirement that when you are implementing a search box for your site, you want the users to be able to start typing in search keywords when the page load. Well it is pretty simple by using a small javascript on the page. Since Microsoft shipd jQuery with Visual Studio now and jQuery provides very concise implementation of some very common tasks, so I used jQuery to accomplish the task. Following snippet shows how to use jQuery to set focus on text box.

     $(document).ready(function () {
     	var keywordTextBox = $get("<%=keywordTextBox.ClientID%>");
     	keywordTextBox.focus();
     }
    

    Yes, I could have done whole thing in one line instead of storing the element in local variable first. But I needed this element for some other user as well. Soon you will see why. The code simple translates to when document has been loaded and DOM is ready get text box html element and call focus method to set focus on it.

  • How to set cursor position at end of text in text box

    Now that you have seen how to set focus on text box, next thing you will run into is that when page post backs when you have text in search text box, the focus is set on the text box but it is set at the start of the text. What you are really looking for is that when you have some text in text box, the focus should be set at the end of the text so user can either continue with what is already there or start deleting for a new search term. The following snippet shows how you can use setSelectionRange or createTextRange depending on browser, javascript method on text box to set the cursor at the end of the text in text box. Or for that matter you can use this technique to set cursor in text box at any position.

    $(document).ready(function () {
    try {
      var keywordTextBox = $get("<%=keywordTextBox.ClientID%>");
      if (null != keywordTextBox) {
          var pos = keywordTextBox.value.length;
          if (keywordTextBox.setSelectionRange) {
             keywordTextBox.setSelectionRange(pos, pos);
          }
          else if (keywordTextBox.createTextRange) {
            var textRange = keywordTextBox.createTextRange();
            textRange.collapse(true);
            textRange.moveEnd("character", pos);
            textRange.moveStart("character", pos);
            textRange.select();
          }
          keywordTextBox.focus();
       }
    });
    
  • How to handle enter key click in text box to submit page

    Now that we have set focus in text box. Now your user should be able to enter some text in the text box and hit ENTER key to perform search. Following code snippet shows how you can hook key events of your text box to look for ENTER key press and then submit the page.

    $(document).ready(function () {
    try {
      var keywordTextBox = $get("<%=keywordTextBox.ClientID%>");
      if (null != keywordTextBox) {
          var pos = keywordTextBox.value.length;
          if (keywordTextBox.setSelectionRange) {
             keywordTextBox.setSelectionRange(pos, pos);
          }
          else if (keywordTextBox.createTextRange) {
            var textRange = keywordTextBox.createTextRange();
            textRange.collapse(true);
            textRange.moveEnd("character", pos);
            textRange.moveStart("character", pos);
            textRange.select();
          }
          keywordTextBox.focus();
           $("input").keydown(function (e) {
           if (e.keyCode == 13) {
             __doPostBack("<%=searchButton.UniqueID%>", "");
            return false;
           }
          });
       }
    });
    

    The above code javascript snippet demonstrates all three features of handling various text box features together. You can see all this in real action at the following page. Start typing some search term and see how autocomplete start providing hints and then when you hit ENTER key, page posts back and returns with search results and then text box focus is set at the end of text in text box.

Live Demo Of Text Box Features

 

Give your advice to big bosses and make money

Views: 380

Tags: ,

ASP.Net | Javascript | JQuery

Ajax AutoComplete Control Not Working

by Naveen 25. August 2010 17:19

While implementing integrating ASP.Net Ajax AutoComplete control on a site's search text box, I ran into an issue. While I was typing inside the text box, no request was getting sent to my web service to get the list of previously used search terms with a given prefix that user was typing. I checked the mark up for AutoCompleteExtender on the page and all the required properties etc. There was nothing out of place. Obviously request was not making it to my web service method. That's when I called on handy dandy Fiddler. And there it was the following response from the web service request with Http Status code of 500.

Only Web services with a [ScriptService] attribute on the class definition can be called from script

Thats when I realized that I forgot to enable this attribute on my ASP.Net web service. So remember that if you are using an ASP.Net web service with Ajax toolkit controls, you have to enable ScriptService on your service.

Give your advice to big bosses and make money

Views: 375

Tags: ,

AJAX | ASP.Net

How to configure SMTP server for CreateUserWizard send email functionality

by Naveen 19. August 2010 11:21

As part of using Membership controls in ASP.Net, one thing lot of people do as part of user creation is send some sort of email to the new user when they register. This email could be some welcome email or email that send the user their password etc. Good news is that CreateUserWizard control takes care of most of the email functionality for you. Here is what you need to make it all work.

How does it work?

CreateUserWizard control sends an email to the newly registered when the new user has been created. SendEmail event is fired after CreatedUser event has been successfully fired and handled. Interestingly, CreateUserWizard sends this email using method SendPasswordMail. It seems this email feature was designed for sending passwords to user when password is automatically generated. But this does not mean that it is only going to be called when certain password option is chosen.

MailDefinition is the key

CreateUserWizard control does not try to send email all the time. It looks for MainDefinition template to be set in the control. If you do not definie MailDefinition template, control will not send the email. So what you need to do is fill this template inside your control container. Here is sample implementation from my sample code.

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:CreateUserWizard ID="RegisterUser" 
    runat="server" EnableViewState="false" 
    OnCreatedUser="RegisterUser_CreatedUser" 
    OnCreatingUser="RegisterUser_CreatingUser"
    BorderStyle="Dotted" 
    OnSendingMail="RegisterUser_SendingEmail" 
    OnSendMailError="RegisterUser_SendingEmailError">
       <LayoutTemplate>
         <asp:PlaceHolder ID="wizardStepPlaceholder" runat="server"></asp:PlaceHolder>
         <asp:PlaceHolder ID="navigationPlaceholder" runat="server"></asp:PlaceHolder>
        </LayoutTemplate>
        <MailDefinition 
         From="xyz@mymail.com" 
         IsBodyHtml="true" 
         Priority="Low" 
         BodyFileName="~/WelcomeEmail.htm"
         Subject="Welcome to Project Helpers from ByteBlocks.com">
         <EmbeddedObjects>
            <asp:EmbeddedMailObject Name="LogoImage" Path="~/Images/ByteBlocksLogo.png" />
         </EmbeddedObjects>
        </MailDefinition>
</asp:CreateUserWizard>

As you can see, MailDefinition template allows you to configure email parameters. You do not have to hard code some string as body of your email. It will actually become problem when you have long HTML content to be sent in email body. You can put content of your email in external file and then set the path to that file in BodyFileName attribute of MainDefinition. You can put some token or markers inside that body to replace them with appropriate values at run time. More about it little later. So remember that MailDefinition is key to sending email as part of CreateUserWizard control.

Customize email content and attachment

Some time you want to send welcome email to new users with some documents and also want to have some logo image inside the email body. Well, this all can be handled by using a standard format that the control provided. You will make use of EmbeddedObjects section of MailDefinition template. This is where you can include all the external objects or file paths. Make sure that you have unique names for these objects.

  • To include images inside email body, use the following syntax in HTML email body content.

    	<img src="cid:LogoImage" alt="ByteBlocks Project Helpers" />
    	<h2>Welcome To ByteBlocks Project Helper</h2>
    	

    This is part of HTML file that I use for email body. The key to this is src=cid:uniqueid part. This uniqueid is the name of the object that you added in EmbeddedObjects section. You can see from the markup that I showed earlier that I have included my logo image inside EmbeddedObjects section.

  • If you need to attach some documents, then include them in EmbeddedObjects section.

Following screenshot shows sample of email that get sent from my application. You can see that at the top of the email is sample logo image as well.

Configure SMTP Server for CreateUserWizard Email

This is one of the most asked question to me. Where do I set SMTP server settings for emails from CreateUserWizard?. When SendEmail event is fired, you get MailMessageEventArgs object as parameter of event handler. This object only provides you access to email message only. It does not provide a way to configure SMTP settings for outgoing email. Then how do you set it?

See the following call stack when CreateUserWizard control is trying to send the email out.

System.Net.Mail.SmtpClient.Send(MailMessage message)
   System.Web.UI.WebControls.LoginUtil.SendPasswordMail(String email, String userName, 
        String password, MailDefinition

Now if you look at constructor of SmtpClient, it initializes the settings of email transport from mailSettings section of web.config. That means the place to configure your SMTP server is in web.config file. Add mailSettings section in system.net section of web.config value. Following snippet shows you an example from my site.

<system.net>
    <mailSettings>
      <smtp deliveryMethod="Network" from="xyz@myisp.com">
        <network host="localhost" />
      </smtp>
    </mailSettings>
  </system.net>

You can provide the values as per your server settings. If you are just testing using your local machine as email relay then you do not have to specify these settings. SmtpClient by default will use local machine.

Important things

There are few things that you will need to pay attention to when setting up this MailDefinition template and changing settings for MailMessage.

  • Make sure that you have specified an email address in From section. This does not have to be a valid emails address. You can simply put something like noreply@mydomain.com. But do not leave it empty.
  • If your process does not require the users to provide their email address but you still want to send some email for record keeping then you can add a placeholder email to To collection. You can not leave To collection empty. Otherwise SmtpClient object will throw exception at you.

    protected void RegisterUser_SendingEmail(object sender, MailMessageEventArgs e)
    {
       var sendTo = RegisterUser.Email;
       if (string.IsNullOrEmpty(sendTo))
       {
          sendTo = "foo@bar.com";
          e.Message.To.Add(sendTo);
        }
    }
    
  • Do provide an event handler for SendEmailError. If there is some error or exception thrown during outoging email process, you can look at the error message. Handle this error gracefully and then set Handled properly.

    protected void RegisterUser_SendingEmailError(object sender, SendMailErrorEventArgs e)
    {
     System.Diagnostics.Trace.WriteLine(e.Exception.Message);
     e.Handled = true;
    }
    

    If you do not handle this error, then it will get propagated to the top as unhandled exception and depending on your CustomError settings, users may see ugly yellow screen with full stack trace and all.

Give your advice to big bosses and make money

Views: 564

Tags:

ASP.Net

How to use reCaptcha with CreateUserWizard In ASP.Net

by Naveen 18. August 2010 10:50

I was working on using CreateUserWizard ASP.Net control on my web site to allow users to create their account for authorized and authenticated access to certain access of sites. One of the problems you face on the web sites is that spammers tend to run bots to create accounts on sites using direct HTTP requests and things like that. One of the ways to fight this is the use of some CAPTCHA control on the pages. Yes, there are some hackers who claim to bypass some of these counter measures. But still it protects you from about 80% or so of these spam bots.

So one of things you can do is to add ASP.Net plugin for reCaptcha control in template for CreateUserWizard control. There are few issues that I ran into when I tried to integrate into my page. So here are some of the things you can learn from my experience to integrate reCaptch in ASP.Net.

  • There seems to be a validation bug in older version of reCaptcha control plugin. So I had to download the latest source code from google SVN and recompile it to use in my ASP.Net web site. The problem I was running into with bugged plugin was that Postback was not getting fired. After I will click on Create button, the page will just not fire event handler to postback the page. Once I replaced it with recompiled version of reCaptch control, the page worked fine.

  • In the post back event handler, add the following code to validate reCaptcha challenge. This will provide you server side validation of the control. I added following code to my event handler.

    protected void RegisterUser_CreatingUser(object sender, LoginCancelEventArgs e)
    {
      var captcha = 
       (Recaptcha.RecaptchaControl)RegisterUser.CreateUserStep.ContentTemplateContainer.FindControl("recaptchaCtl");
      if (null == captcha)
      {
        e.Cancel = true;
        return;
      }
      captcha.Validate();
      if (!captcha.IsValid)
      {
        //TODO: Display validation message.
        e.Cancel = true;
        return;
      }
      e.Cancel = false;
    }
    
Give your advice to big bosses and make money

Views: 521

Tags:

ASP.Net

Avoid Multiple Form Tags To Add Google Search To ASP.Net Page

by Naveen 13. August 2010 09:12

Last week I was updating the site to include some new features. I realized that I was missing a very important component on the blog and that was google search box. I had this search on my other sites for quite some time. I remember that I had to deal with the fact that Google Custom Search script is implemented as a POST FORM with the action set to a URL that will be used to display results.

First you have to deal with the fact that ASP.Net framework does not allow you to have multiple FORM tags on the page. But if you want have more than one then only one can have runat='server' attribute on it. And then you have to make sure that your FORM tags are not nested. Well, depending on your layout of the site and implementation, you may or may not be able to control location of this google search form. Here is the solution that I implemented few years ago and deployed on this site as well.

Use of iform

Yes, took the Google Custom Search script and put it in a static HTML page. And then put an IFRAME on the page where I wanted to display the search box. This is where you will have to be little careful. You will have to make sure that style of the HTML page matches your main site. Next make sure that height and width of iframe is big enough to accomodate the search box otherwise you will end up with horizontal and vertical scroll bars around the frame and that will not be a pretty sign for site users. You want to give the illusion to users that this search box is sitting on the page itself. Now perform search and it works. But there is a problem. Search result target URL is being opened in the frame where search box is. Well that is a little problem.

Fix target of FORM

This is where you will have to make a change in the script that Google Custom Search generated for you. In FORM tag, set target to _top. Now when this form is submitted, the action is sent to page contained this iframe. The following snippet is what I have in my HTML page.

<div class="cse-branding-bottom" style="background-color:#FFFFFF;color:#000000">
  <div class="cse-branding-form">
    <form action="http://localhost/ByteBlocksWeb/SearchResults.aspx" 
      id="cse-search-box" 
      target="_top">
      <div>
        <input type="hidden" name="cx" value="partner-pub-xxxxxxxxxxxxx:wcbg5i-ahdn" />
        <input type="hidden" name="cof" value="FORID:11" />
        <input type="hidden" name="ie" value="ISO-8859-1" />
        <input type="text" name="q" size="60" />
        <input type="submit" name="sa" value="Search" />
      </div>
    </form>
  </div>
  <div class="cse-branding-logo">
    <img src="http://www.google.com/images/poweredby_transparent/poweredby_FFFFFF.gif" alt="Google" />
  </div>
  <div class="cse-branding-text">
    Custom Search
  </div>
</div>

Now perform a search and you will notice that your results show up in main page and not in iframe anymore. Give it a try right here in this site by using search at top of the page and see how it works.

Give your advice to big bosses and make money

Views: 663

Tags:

ASP.Net | Google

How to use Linq with ASP.Net GridView

by Naveen 12. August 2010 10:08

Linq is one of the best things that has happened in recent past in .Net framework world. It has made data manipulation so much easy. Yes, Linq has its own set of limitations but for most part it does the job. For those special cases you can always go back to classic ways. In this post, I will describe use of Linq for Sql and provide some simple answers to questions like:

  • How to connect to database using Linq?
  • How to query data from a table using Linq?
  • How to use Linq with GridView, DataGrid etc.?

Namespace and reference to use Linq with Sql

The classes that you need to use Linq with Sql live in System.Data.Linq namespace. So in your project you will have to add the following line at top of your source code file.

using System.Data.Linq;

This namespace lives in System.Data.Linq assembly. That means that you will have to add reference to this assembly in your project. Now you are all set to us Linq.

How to connect to the databae?

You have been using ADO.Net for a while now and first thing we all do is have a connection object that will be used to connect to database, open it and later on close it. Well when you are using, all that plumbing is taken care of for you by Linq frameework. The entry point to all actions in Linq for Sql is DataContext object. This object takes care of establishing connection with the database. You can provider either a connection string or connection object to create instance of DataConext object. Rest will get taken care of for you.

var dataContext = 
new DataContext(ConfigurationManager.ConnectionStrings["blogengine"].ConnectionString);

Query data using Linq

Now you have set up DataContext object, it is time to get some data from the database. You will notice that DataContext object provides methods like GetTable, ExecuteQuery, ExecuteCommand etc. All the methods that return collection of data, expect another parameter which is Type of an object that represent the data returned from query or command. In otherwords, the method is looking for a mapping between table in the database to an object. Here is an object definition that I used in my code to map to fields from a datatable that I wanted to fetch.

[Table(Name="be_Posts")]
public class BlogPost
{
  [Column(IsPrimaryKey=true)]
  public Guid PostID
  {get;set;}

  [Column]
  public string Title
  {get;set;}

  [Column]
  public string MiniUrl
  {get;set;}
}

There are few attributes on this class that are to be notices. First, there is TableAttribute on the class itself. By default Linq assumes that name of the class or object is same as table in the database. But if your table name does not match with the class name, then you can use this attribute to provide the name of the table that maps witht this obejct. For example in my case table name be_Posts is to be mapped to BlogPosts object which is my ViewModel. Next attribute is ColumnAttribute. You will assign this attribute to properties or fields that needs to be queried. If your column name does match with name of the property or field, you can provide that mapping as well. There are more values you can set in the column attribute. I will discuss those in subsequent posts. For now this simple definition of .Net object will work for our simple query purposes.

Bind Linq To GridView

Now we have our Linq query set to go, rest is just setting this collection to our GridView object on ASP.Net page and rest is all taken care of for us. Following code snippet shows how in few lines we are able to connect to database, query the data and bind it to a GridView.

void BindGrid()
{
 var dataContext = 
  new DataContext(ConfigurationManager.ConnectionStrings["blogengine"].ConnectionString);
 var posts = dataContext.GetTable<BlogPost>();
 postsGridView.DataSource = posts;
 postsGridView.DataBind();
}

It is as simple as these 4 lines of code to connect to database, query the table and bind to a gridview using Linq to Sql.

Give your advice to big bosses and make money

Views: 750

Tags: , ,

ASP.Net | GridView | LINQ

How to embed YouTube video in ASP.Net page - Server Control

by Naveen 3. June 2010 04:37

Download Source Code (9.09 kb)

Download Binaries (6.28 kb)

Recently I started created some YouTube videos and wanted to embed them in my ASP.Net web site. YouTube provides Embed button next to each video and that helps you create HTML code that you can put on your page. But that would mean that you will have to hard code this HTML on all pages where you want to embed videos. Also if you want to show some random videos on the pages, then this approach is not flexible.

I created this ASP.Net server control that allows to embed YouTube videos on any page. The control allows you to embed videos for which you already have URL or you can configure it to fetch any of the standard YouTube feeds and then display random video from that feed.

How to use it?

  • Download source code of the control and compile it or download pre-compiled binaries of the control.
  • Add reference to ByteBlocks.YouTubeWeb assembly in your project.
  • On the page where you want to embed YouTube video, add the following directive at the top of the page.

    <%@ Register TagPrefix="ByteBlocks" Assembly="ByteBlocks.YouTubeWeb" Namespace="ByteBlocks.Web.Control" %>

  • Now add the control on the page.

    <ByteBlocks:YouTube id="youTubeVideo" runat="server" Width="480" Height="385" VideoUrl="" FeedType="MostRecent" RandomResults="true" />

  • And you are all set to show random video from Most Recent video feed from YouTube.

Configurable Properties

  • VideoUrl: This property allows you to set URL of the video that needs to be embeded.
  • Width: Sets the width of the video player
  • Height: Set the height of the videeo player
  • FeedType: If you do not want to use a pre-defined video URL, you can pick a standard feed type. The control will fetch that feed from YouTube and display it based on value set for RandomResults and IndexToShow. This property is mututally exlcusive with VideoUrl. If you want the control to fetch standard feed, then do not set any URL in VideoUrl.
  • RandomResults: This property indicates to control to pick a random Video Url from the list of videos from standard feed type.
  • IndexToShow: If you set RandomResults to false, then the control will fetch the video at this index value. If this index is out of range, then the control picks the last entry in the feed list.

See it in Action

The following web site uses this control to show videos from most featured standard feed.

YouTube Server Control Demo

Under the covers

When you generate HTML code for a video from YouTube, it looks something like as shown below.


<object width="480" height="385">
<param name="movie" value="http://www.youtube.com/v/XcugLsKDmRs&hl=en_US&fs=1&rel=0"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/XcugLsKDmRs&hl=en_US&fs=1&rel=0" 
  type="application/x-shockwave-flash" allowscriptaccess="always" 
  allowfullscreen="true" width="480" height="385"></embed>
</object>

So the control simply renders this HTML on ASP.Net page and uses the control properties to configure the display accordingly. The important components of this HTML is video ID used with the video player. I have shown that in bold in snipper above. A video URL looks like as shown below.

http://www.youtube.com/watch?v=Qp9_6ACSWug

Video ID is provided in v query string parameter. The control parses this ID and replaces it in the URL that is required for URL for video player.

Source Code and Binaries

Attached code is compiled using Visual Studio 2010 and .Net 4.0 framework. If you need code for earlier versions of Visual Studio, feel free to conttact me.

Give your advice to big bosses and make money

Views: 969

Tags: ,

.Net | ASP.Net

Server Error - Upgrading Existing ASP.Net 2.0 Web site to ASP.Net 4.0

by Naveen 24. May 2010 10:09

Recently I was working on upgrading this site to from ASP.Net 2.0 to ASP.Net 4.0. As a first quick pass, I followed my usual procedure of loading the projects into Visual Studio 2010 and set the target for all projects to use .Net 4.0 framework. So far so good. I tested it on my development machine which is Windows 7 and everything worked as I expected.

So I went ahead with deployment on my production Windows server. I changed the target ASP.Net framrwork of my web site to ASP.Net 4.0 from ASP.Net 2.0. And site loaded and started serving requests. After few hours I got an email from another site owner who is hosting site on my server that all sites have stopped working and we were getting Server Error or Application Error. I have about dozen sites hosted on the server and all but one stopped working. Only one that was working was this site that I just upgraded to use ASP.Net 4.0. Right there I realized the mistake I made. This is the samee mistake that was made when sites were upgraded from ASP.Net 1.1 to ASP.Net 2.0.

Mixed ASP.Net versions in Application Pool

Yes, now I had one site in the application pool that was using ASP.Net 4.0 and others were using ASP.Net 2.0. Application pools do not allow mixed version of .Net framework. Here are some things that you will have to take into consideration when migrating your existing ASP.Net sites from 2.0 t0 4.0 or when adding new sites on Windows 2003 server.

  • Make sure that you do not mix use of ASP.Net version in same pool
  • Best option is to make a new Application Pool and put your new or migrated ASP.Net 4.0 sites in there.
  • If you have already made a mistake (like I did) of mixing ASP.Net versions on application pool, then there are few options you can use:
    • Move the sites using ASP.Net 4.0 framework to a new pool or move ASP.Net 2.0 sites into new pool depending on whatever is less work.
    • I have run into cases where moving ASP.Net 4.0 out of pool did not work. If upgrading all sites to ASP.Net4.0 framework is not going to break anything, then you may have to consider that option.
    • When you start upgrading existing sites to use new pool or upgrade to new ASP.Net 4.0 you may run into problem that all sites start showing Service Unavailable error. This has been happening a lot on Windows 2003 server. During process of upgrading and pool switching, some time IIS stops working. You will notice a red cross mark on Web Sites node in IIS. You will have to goto Service Control Manager to restart worldwide web publishing service on your server

I hope this little piece of information helps you get out of problem of upgrading existing site to ASP.Net 4.0 when there are other sites in same pool that use older version of ASP.Net.

Give your advice to big bosses and make money

Views: 714

Tags: ,

ASP.Net | IIS

Powered by BlogEngine.NET 1.5.1.7
Theme by Naveen Kohli

By Categories