If you download the source code, you will find two embedded
JavaScript files that support client-side functionality for the control.
Using embedded JavaScript files has many benefits; this
allows the client browser to cache the script which should lead to faster page
loads especially if the script is large. By embedding the JavaScript file as a
resource rather than putting it in the control’s code, the overall code base is
also much easier to maintain.
Let us overview the JavaScript file "animatedcollapse.js." This is the part that is responsible
for sliding contents. If you take a look through the JavaScript code, you will
find "slidedown" and "slideup" functions, these two JavaScript functions are
responsible for sliding down the content to hide it and sliding up the content
to show it.
We will render a JavaScript block at render time using ScriptManager.RegisterStartupScript method for each Textbox- for
slide it up and slide it down. By using ScriptManager
rather than writer.write(the script
block), the custom control will be worked under Ajax environment. So if you are trying to render the script block using writer.write,
it will not work under Ajax environment.
Sliding mechanism occurs by placing each textbox control
inside a separate html div, and these html div's will appear/disappear using
the two JavaScript functions that I talked about.
As I mentioned, we have three languages (English, Arabic,
and French), so we have to put the English textbox control inside html div, the
Arabic textbox control should be inside another html div, and the same thing
with the French textbox control.
Take a look at the code below, registering startup script at
render time for English language. This code will be repeated three times for English,
Arabic and French with a little change for each language to make it unique.
Listing 2
'//Ajax Enabled
ScriptManager.RegisterStartupScript(Page, Me.GetType, Me.ID & "_EnBlock", _
"var " & Me.ClientID & "_collapseEn = new animatedcollapse('" & _
Me.ClientID & "_dvEn', 400, false" & IIf(DefaultLanguage = _
ControlLanguages.English, ",'block'", "") & ");", True)
As you see in listing 2, we are registering startup script
at render time for English content. Note that we are declaring a variable from
the animatedcollapse JavaScript Class. Assume that
our custom control ClientID is MutliLang1 so the variable will be like this
(MultiLang1_collapseEn). This will be a unique object for our custom control,
so it does not matter now how many times you drag/drop or how many times you
created an instance from this custom control in the page, each custom control
will be worked separately with its own JavaScript functions by using its own JavaScript
object. Take this advice; if you want to create your own custom control, use
the previous technique when you are dealing with JavaScript, which makes your
custom control more reusable.
To collapse the English content, the MultiLang1_collapseEn.slideup()
function will take care of that, and to expand it again, use MultiLang1_collapseEn.slidedown().
Use the same thing in the left languages, but remember that each language has
its own JavaScript object.
Back again to the downloaded source code, open the JavaScript
file "MultiLangJS.js.” It contains two JavaScript functions:
"MultiLangClass" function which is the main function, and
"HideShowLang" function which is responsible for calling
Slideup/Slidedown functions. "MultiLangClass" function receives many
arguments; each argument will be assigned to a JavaScript variable. These
variables will be a global through the JavaScript file.
As you saw in figure 1, we are passing the ClientID's for
controls to be assigned in the JavaScript file.
Using the same technique which we have used, we will
register another JavaScript block at render time for the whole control. This
script block will be the JavaScript controller for the whole control.
Figure 1

In the above code, we declare a JavaScript variable during
render time, which is an instance from the MultiLangClass JavaScript class.
This variable will be the key for calling all JavaScript functions from the
embedded "MultiLangJS.js" file. Again, by using this technique (i.e.
creating instance variable from JavaScript file), it allows us to drag and drop
my custom control many times in the page without worrying about confliction
between these instances. Assume that my control ID is MultiLang1 so the
JavaScript variable will be like this: (ObjJS_MultiLang1). I will use this
JavaScript object in the onclick event, when the end-user clicks on the image
of the language he wants to display. I will give more examples about how to
call this variable later in this article.
Embedding the JavaScript files will be done by using the WebResource attribute typically over the namespace
declaration in the class file for your custom control as you see in the code
below.
Listing 3
<Assembly: TagPrefix("MyCustomsControls.CustomsControls", "asp")>
<Assembly: WebResource("MyCustomsControls.MultiLangJS.js", "text/javascript")>
And we have to tell the Page that our custom control has
javascript files needed to be registered when the final HTML is generated for
that page. So we need to write a bit of code in the OnInit
sub as in Listing 4.
Listing 4
Protected Overrides Sub OnInit(ByVal e As EventArgs)
MyBase.OnInit(e)
Me.Page.ClientScript.RegisterClientScriptInclude(Me.GetType(), "MultiLangJS", _
Page.ClientScript.GetWebResourceUrl(Me.GetType(), _
"MyCustomsControls.MultiLangJS.js"))
Me.Page.ClientScript.RegisterClientScriptInclude(Me.GetType(), _
"animatedcollapse", Page.ClientScript.GetWebResourceUrl(Me.GetType(), _
"MyCustomsControls.animatedcollapse.js"))
End Sub