• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 375
  • Last Modified:

How to create PhoneBox custom control ?

What i want my custom control to look like this:

(<textboxW3no>) <textbox3no> - <textbox4no>

also - it should validate the numbers and when you have typed necessary amount of number - automatically refocus on the next textbox.

Im sure some of you people out there have already done it - so where could i find code for custom control like this?
  • 5
  • 5
1 Solution
Do you mean a textbox for phone numbers that only allows numeric input, and after you enter the last digit it gives the focus to the next phone number text box?  If so, you do not need to create a custom control.  You can register some javascript and add some attributes to the textbox control to do this.  I'll show you how when you confirm that I understand your need correctly.

MargusLehisteAuthor Commented:
Yes that is exactly correct (and in this custom control should be three textboxes).

I saw your post about SSN box - but I wasnt quite sure how would i accomplish it in phone custom control
(and also Im not that familiar with c# - but ill give it a try if its only way to create the control)

I will appreciate all the input!
Are you going to put this text box into a DataGrid, DataList or Repeater?  This will affect where you add the attributes that will call the JavaScript routine to enforce numers only.  Also, you say three text boxes... so you want one for area code (3 characters), one for prefix (3 characters) and one for the last four digits?

If this is the case, you can approach it as a custom control, or you can use three text boxes and add the necessary attributes and properties depending on which one it is.  Using three text boxes and just add attributes will be the easier of the two, but if you really want to do the custom control, that's fine as well.  If you have the time to try the custom control approach, I recommend it as it will expose you to the REAL flexibility of ASP.NET

Let me know on the above, and we'll go from there...

Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

MargusLehisteAuthor Commented:
I do not intend to put the textbox to Datagrid, repeater or datalist.

I just want to create "phonebox" custom control which i could use in the forms for user input (in the userInterface it should appear as 3 separate textboxe - first for are code and last two for numbers)
OK... I need to get dinner and a couple of other things squared away.  I'll post something by later this evening that hopefully should get you started tomorrow morning.


Here is something to get you started:  Start by creating a Scripts folder in your web application.  Add a JScript file and name it PhoneNumberBox.js.  Add these two functions to it: (Note that I coded for IE.  You may need to explore cross browser JavaScript issues if your environment will require it.)

function validateKey()
      // get key code.
      var key = window.event.keyCode;
      // test key code.
      var test1 = (key >= 48      && key <= 57);      // 48-57 are the number keys above the letters.
      var test2 = (key >= 96      && key <= 105);      // 96-105 are the 10-key number keys.
      var test3 = (key == 37      || key == 39);      // 37 & 39 are left/right arrow keys.
      var test4 = (key == 46      || key == 9);      // 46 & 9 are delete and tab keys.
      var test5 = (key == 8);                  // 8 is backspace.
      // apply test.
      if (!test1 && !test2 && !test3 && !test4 && !test5)
            // cancel event.
            window.event.returnValue = false;
            window.event.cancelBubble = true;

function passFocus()
      // get source element and its max length.
      var src = window.event.srcElement;
      var maxlen = src.getAttribute("maxlength");
      // pass focus if the value's length is = to the maxlength of the element.
      if (src.value.length == maxlen) src.nextSibling.nextSibling.focus();

Then create a new project in the same solution as your web app.  Name this "ServerControls".  This project should be a Class Library project (I understand the you will be using VB).  VS will add a class for you.  Rename the file something like clsPhoneNumberControl.cls  In the file, rename the class to PhoneNumberControl.  Make sure these following namesapces are imoprted:

Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel

Then put an Inherits statement right after the class declaration:

Public Class PhoneNumberControl
     Inherits WebControl

End Class

Right after the Inherits... statement, declare variables for your three text boxes:

' declare text boxes.
Private _areacode As TextBox
Private _prefix As TextBox
Private _lastfour As TextBox

Then add the constructor (often referred to as ctor).  In VB, this is the New() sub:  (I will explain EnsureChildControls() in a moment.)

Public Sub New()
     ' make sure CreateChildControls gets called.
End Sub

Now you need to override three routines of the base class (which is WebControl): CreateChildControls(); OnInit() and Render().  The CreateChildControls() routine is where you instantiate the textbox classes declared above and add them to the base class' Controls collection.  In your New() method, you tell the base class to call this method right when the class is instantiated.  EnsureChildControls() causes the base class to call your overriden CreateChildControls().  Here is what that routine should look like:

Protected Overrides Sub CreateChildControls()
          ' instantiate and add the area code box.
          Me._areacode = New TextBox
          Me._areacode.MaxLength = 3
          Me._areacode.Width = Unit.Pixel(50)

          ' add a dash as a literal control.
          MyBase.Controls.Add(New LiteralControl("-"))

          ' instantiate and add the prefix box.
          Me._prefix = New TextBox
          Me._prefix.MaxLength = 3
          Me._prefix.Width = Unit.Pixel(50)

          ' add a dash as a literal control.
          MyBase.Controls.Add(New LiteralControl("-"))

          ' instantiate and add the last four digits box.
          Me._lastfour = New TextBox
          Me._lastfour.MaxLength = 4
          Me._lastfour.Width = Unit.Pixel(100)
End Sub

Now you want to override OnInit().  This is where you tell your page to check for the script block that points to your script file.  There is a function you will see below that checks to see if the script has already been registered.  This way if you put more than one of your control on a page, only one registration of the script block happens:

Protected Overrides Sub OnInit(ByVal e As EventArgs)
          ' make sure client script block pointing to your script file is registered.
          If Me.Page.IsClientScriptBlockRegistered("PhoneNumberBoxScript") Then
               Dim js As String = "<script language='javascript' src='Scripts/PhoneNumberBox.js'></script>"
               Me.Page.RegisterClientScriptBlock("PhoneNumberBoxScript", js)
          End If

          ' let base complete the init process.
End Sub

Here is one of the funny things about VB.NET.  These two script registering methods do not appear in Intellisense (they do appear in C#, go figure).  But they are there, just make sure your spelling is right.

Lastly, you will override Render().  By this time everything has been instantiated.  Your base class has it's id string, so it can pass it along to the three text box controls.  This is also where you add attributes to the text boxes so they call your JavaScript functions when a key has been pressed (onkeydown) to disallow non numeric characters and when the key comes up (onkeyup) to check the length of the value.  If it is the same as the maxlength property of the text box (3, 3, and 4 respectively), then it passes focus to the next box.  Here it is:

Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
          'set ids.
          Me._areacode.ID = Me.ID & "_areacode"
          Me._prefix.ID = Me.ID & "_prefix"
          Me._lastfour.ID = Me.ID & "_lastfour"

          ' set attributes.
          Me._areacode.Attributes.Add("onkeydown", "javascript:validateKey();")
          Me._areacode.Attributes.Add("onkeyup", "javascript:passFocus();")
          Me._prefix.Attributes.Add("onkeydown", "javascript:validateKey();")
          Me._prefix.Attributes.Add("onkeyup", "javascript:passFocus();")
          Me._lastfour.Attributes.Add("onkeydown", "javascript:validateKey();")

          ' render control.
End Sub

Since you have added each textbox and the dash literal controls to the base class' Controls collection, when you call MyBase.Render(), the base class renders a <span></span> tag for the base control, and then the <input> tags and the "-" characters within the <span></span>.

After you have put all of this code in your class, build your ServerControls project to make sure everything is right.  Then go to your web app (should be in the same solution file).  Go to add a reference.  When the references dialog comes up, choose the Projects tab.  You'll see your ServerControls project.  Select it and add the reference.  Build your web app now.  Both the web app and the ServerControls project should build together now.

Now open a webform.  Go to your toolbar and add a tab (I usually call this tab "TestBed").  Right click in the tab and select "Add/Remove Items".  Instead of picking from the list of controls, click the Browse button.  Find your web apps' folder and go to the bin subfolder.  You should find ServerControls.dll there.  Select that and your list should include an entry for your PhoneNumberControl.  You should be able to drag that onto your webform and give it a test run.

Good luck!


MargusLehisteAuthor Commented:
It looked great - only problem is that for some reason it cannot find those javascript functions.

How exactly should this .js file look like?
MargusLehisteAuthor Commented:
EXCELLENT (my own fault - tried to attach file like this:
Dim js As String = "<script language='javascript' src='/newmpow/Scripts/PhoneNumberBox.js'></script>")

However - added the script as inline tu PhoneNumberControl.vb file and it WORKED!!!


Ill buy you a dinner if you happen to come by NY
Gee, New York steak... I'll have to take you up on that sometime... :-)

Glad it worked.  Just to mention again, the JavaScript is IE compliant.  If your users use other browsers, they might get unexpected results.

MargusLehisteAuthor Commented:
Thank you John - I have couple of things still to solve with that control -
take a look if you are interested:

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

  • 5
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now